VirtualBox

Changeset 31912 in vbox for trunk


Ignore:
Timestamp:
Aug 24, 2010 12:12:15 PM (14 years ago)
Author:
vboxsync
Message:

VBoxService/VMInfo/PropCache: Don't bail out in error cases and report information we already got, first implementation of zapping stale network information (not enabled yet), misc. adjustments.

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.cpp

    r31893 r31912  
    205205 * Updates the local guest property cache and writes it to HGCM if outdated.
    206206 *
    207  * @returns VBox status code. Errors will be logged.
     207 * @returns VBox status code.
    208208 *
    209209 * @param   pCache          The property cache.
     
    306306
    307307/**
     308 * Updates all cache values which are matching the specified path.
     309 *
     310 * @returns VBox status code.
     311 *
     312 * @param   pCache          The property cache.
     313 * @param   pszValue        The value to set.  A NULL will delete the value.
     314 * @param   fFlags          Flags to set.
     315 * @param   pszPathFormat   The path format string.  May not be null and has
     316 *                          to be an absolute path.
     317 * @param   ...             Format arguments.
     318 */
     319int VBoxServicePropCacheUpdateByPath(PVBOXSERVICEVEPROPCACHE pCache, const char *pszValue, uint32_t fFlags, const char *pszPathFormat, ...)
     320{
     321    AssertPtr(pCache);
     322    AssertPtr(pszPathFormat);
     323    int rc = VERR_NOT_FOUND;
     324    PVBOXSERVICEVEPROPCACHEENTRY pNodeIt = NULL;
     325    if (RT_SUCCESS(RTCritSectEnter(&pCache->CritSect)))
     326    {
     327        /*
     328         * Format the value first.
     329         */
     330        char *pszPath = NULL;
     331        va_list va;
     332        va_start(va, pszPathFormat);
     333        RTStrAPrintfV(&pszPath, pszPathFormat, va);
     334        va_end(va);
     335        if (!pszPath)
     336            return VERR_NO_STR_MEMORY;
     337
     338        /* Iterate through all nodes and compare their paths. */
     339        RTListForEach(&pCache->NodeHead, pNodeIt, VBOXSERVICEVEPROPCACHEENTRY, NodeSucc)
     340        {
     341            if (RTStrStr(pNodeIt->pszName, pszPath) == pNodeIt->pszName)
     342            {
     343                /** @todo Use some internal function to update the node directly, this is slow atm. */
     344                rc = VBoxServicePropCacheUpdate(pCache, pNodeIt->pszName, pszValue);
     345            }
     346            if (RT_FAILURE(rc))
     347                break;
     348        }
     349        RTStrFree(pszPath);
     350        RTCritSectLeave(&pCache->CritSect);
     351    }
     352    return rc;
     353}
     354
     355
     356/**
    308357 * Flushes the cache by writing every item regardless of its state.
    309358 *
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServicePropCache.h

    r29885 r31912  
    3030int VBoxServicePropCacheUpdate(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, const char *pszValueFormat, ...);
    3131int VBoxServicePropCacheUpdateEx(PVBOXSERVICEVEPROPCACHE pCache, const char *pszName, uint32_t fFlags, const char *pszValueReset, const char *pszValueFormat, ...);
     32int VBoxServicePropCacheUpdateByPath(PVBOXSERVICEVEPROPCACHE pCache, const char *pszValue, uint32_t fFlags, const char *pszPathFormat, ...);
    3233int VBoxServicePropCacheFlush(PVBOXSERVICEVEPROPCACHE pCache);
    3334void VBoxServicePropCacheDestroy(PVBOXSERVICEVEPROPCACHE pCache);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp

    r31905 r31912  
    333333static int vboxserviceVMInfoWriteNetwork(void)
    334334{
    335     int  cIfacesReport = 0;
     335    int rc = VINF_SUCCESS;
     336    uint32_t  cIfacesReport = 0;
    336337    char szPropPath[256];
    337338
     
    364365        return RTErrConvertFromWin32(dwRet);
    365366    }
    366 # endif
     367# endif /* !TARGET_NT4 */
    367368
    368369    SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
     
    406407        char szIp[32];
    407408        RTStrPrintf(szIp, sizeof(szIp), "%s", inet_ntoa(pAddress->sin_addr));
    408         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
     409        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/IP", cIfacesReport);
    409410        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szIp);
    410411
    411412        pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
    412         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
     413        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Broadcast", cIfacesReport);
    413414        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    414415
    415416        pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask);
    416         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
     417        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Netmask", cIfacesReport);
    417418        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    418419
    419         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
     420        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/Status", cIfacesReport);
    420421        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, nFlags & IFF_UP ? "Up" : "Down");
    421422
     
    426427                break;
    427428
    428         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
     429        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/MAC", cIfacesReport);
    429430        if (pAdp)
    430431        {
     
    437438        else
    438439            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, NULL);
    439 # endif
     440# endif /* !TARGET_NT4 */
    440441
    441442        cIfacesReport++;
     
    447448
    448449#elif defined(RT_OS_FREEBSD)
    449     int rc = 0;
    450450    struct ifaddrs *pIfHead = NULL;
    451451
     
    454454    if (rc < 0)
    455455    {
    456         VBoxServiceError("VMInfo/Network: Failed to get all interfaces: Error %d\n", errno);
    457         return RTErrConvertFromErrno(errno);
     456        rc = RTErrConvertFromErrno(errno);
     457        VBoxServiceError("VMInfo/Network: Failed to get all interfaces: Error %Rrc\n");
     458        return rc;
    458459    }
    459460
     
    473474            getnameinfo(pIfCurr->ifa_addr, sizeof(struct sockaddr_in),
    474475                        szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
    475             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
     476            RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/IP", cIfacesReport);
    476477            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
    477478
     
    479480            getnameinfo(pIfCurr->ifa_broadaddr, sizeof(struct sockaddr_in),
    480481                        szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
    481             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
     482            RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Broadcast", cIfacesReport);
    482483            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
    483484
     
    485486            getnameinfo(pIfCurr->ifa_netmask, sizeof(struct sockaddr_in),
    486487                        szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
    487             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
     488            RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Netmask", cIfacesReport);
    488489            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
    489490
     
    502503                    RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
    503504                                pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3],  pu8Mac[4], pu8Mac[5]);
    504                     RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
     505                    RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/MAC", cIfacesReport);
    505506                    VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
    506507                    break;
     
    508509            }
    509510
    510             RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
     511            RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/Status", cIfacesReport);
    511512            VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, pIfCurr->ifa_flags & IFF_UP ? "Up" : "Down");
    512513
     
    522523    if (sd < 0)
    523524    {
    524         VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", errno);
    525         return RTErrConvertFromErrno(errno);
     525        rc = RTErrConvertFromErrno(errno);
     526        VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %Rrc\n", rc);
     527        return rc;
    526528    }
    527529
     
    532534    if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0)
    533535    {
    534         VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno);
    535         return RTErrConvertFromErrno(errno);
     536        rc = RTErrConvertFromErrno(errno);
     537        VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFCONF) on socket: Error %Rrc\n", rc);
     538        return rc;
    536539    }
    537540
     
    544547        if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0)
    545548        {
    546             VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno);
    547             close(sd);
    548             return RTErrConvertFromErrno(errno);
     549            rc = RTErrConvertFromErrno(errno);
     550            VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFFLAGS) on socket: Error %Rrc\n", rc);
     551            break;
    549552        }
    550553        if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip the loopback device. */
     
    554557        pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr);
    555558        Assert(pAddress);
    556         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
     559        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/IP", cIfacesReport);
    557560        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    558561
    559562        if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0)
    560563        {
    561             VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
    562             close(sd);
    563             return RTErrConvertFromErrno(errno);
     564            rc = RTErrConvertFromErrno(errno);
     565            VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %Rrc\n", rc);
     566            break;
    564567        }
    565568        pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr;
    566         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
     569        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Broadcast", cIfacesReport);
    567570        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    568571
    569572        if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0)
    570573        {
    571             VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
    572             close(sd);
    573             return RTErrConvertFromErrno(errno);
     574            rc = RTErrConvertFromErrno(errno);
     575            VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFNETMASK) on socket: Error %Rrc\n", rc);
     576            break;
    574577        }
    575578# if defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
     
    579582# endif
    580583
    581         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
     584        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Netmask", cIfacesReport);
    582585        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
    583586
     
    605608                memcpy(&IfMac, ArpReq.arp_ha.sa_data, sizeof(IfMac));
    606609            else
    607                 VBoxServiceError("VMInfo/Network: failed to ioctl(SIOCGARP) on socket: Error %d\n", errno);
     610            {
     611                rc = RTErrConvertFromErrno(errno);
     612                VBoxServiceError("VMInfo/Network: failed to ioctl(SIOCGARP) on socket: Error %Rrc\n", rc);
     613                break;
     614            }
    608615        }
    609616        else
    610             VBoxServiceError("VMInfo/Network: failed to ioctl(SIOCGLIFADDR) on socket: Error %d\n", errno);
     617        {
     618            rc = RTErrConvertFromErrno(errno);
     619            VBoxServiceError("VMInfo/Network: failed to ioctl(SIOCGLIFADDR) on socket: Error %Rrc\n", rc);
     620            break;
     621        }
    611622# else
    612623        if (ioctl(sd, SIOCGIFHWADDR, &ifrequest[i]) < 0)
    613624        {
    614             /* @todo don't fail here, handle failure with zero MAC address */
    615             VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFHWADDR) on socket: Error %d\n", errno);
    616             close(sd);
    617             return RTErrConvertFromErrno(errno);
     625            rc = RTErrConvertFromErrno(errno);
     626            VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFHWADDR) on socket: Error %Rrc\n", rc);
     627            break;
    618628        }
    619629# endif
     
    627637        RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
    628638                    pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3],  pu8Mac[4], pu8Mac[5]);
    629         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
     639        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/MAC", cIfacesReport);
    630640        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
    631641
    632         RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
     642        RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/Status", cIfacesReport);
    633643        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, fIfUp ? "Up" : "Down");
    634644        cIfacesReport++;
     
    636646
    637647    close(sd);
     648    if (RT_FAILURE(rc))
     649        VBoxServiceError("VMInfo/Network: Network enumeration for interface %d failed with error %Rrc\n", i, rc);
    638650
    639651#endif /* !RT_OS_WINDOWS */
     652
     653#if 0 /* Zapping not enabled yet, needds more testing first. */
     654    /*
     655     * Zap all stale network interface data if the former (saved) network ifaces count
     656     * is bigger than the current one.
     657     */
     658
     659    /* Get former count. */
     660    uint32_t cIfacesReportOld;
     661    rc = VBoxServiceReadPropUInt32(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/Net/Count", &cIfacesReportOld,
     662                                   0 /* Min */, UINT32_MAX /* Max */);
     663    if (   RT_SUCCESS(rc)
     664        && cIfacesReportOld > cIfacesReport) /* Are some ifaces not around anymore? */
     665    {
     666        VBoxServiceVerbose(3, "VMInfo/Network: Stale interface data detected (%u old vs. %u current)\n",
     667                           cIfacesReportOld, cIfacesReport);
     668
     669        uint32_t uIfaceDeleteIdx = cIfacesReport;
     670        do
     671        {
     672            VBoxServiceVerbose(3, "VMInfo/Network: Deleting stale data of interface %d ...\n", uIfaceDeleteIdx);
     673            rc = VBoxServicePropCacheUpdateByPath(&g_VMInfoPropCache, NULL /* Value, delete */, 0 /* Flags */, "/VirtualBox/GuestInfo/Net/%u", uIfaceDeleteIdx++);
     674        } while (RT_SUCCESS(rc));
     675    }
     676    else if (   RT_FAILURE(rc)
     677             && rc != VERR_NOT_FOUND)
     678    {
     679        VBoxServiceError("VMInfo/Network: Failed retrieving old network interfaces count with error %Rrc\n", rc);
     680    }
     681#endif
    640682
    641683    /*
     
    647689                               cIfacesReport);
    648690
    649     /** @todo r=bird: if cIfacesReport decreased compared to the previous run, zap
    650      *        the stale data.  This can probably be encorporated into the cache.  */
    651 
     691    /* Don't fail here; just report everything we got. */
    652692    return VINF_SUCCESS;
    653693}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette