Changeset 44097 in vbox for trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
- Timestamp:
- Dec 11, 2012 5:06:02 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
r44073 r44097 72 72 73 73 74 /** Structure containing information about a location awarness 75 * client provided by the host. */ 76 /** @todo Move this (and functions) into VbglR3. */ 77 typedef struct VBOXSERVICELACLIENTINFO 78 { 79 uint32_t uID; 80 char *pszName; 81 char *pszLocation; 82 char *pszDomain; 83 bool fAttached; 84 uint64_t uAttachedTS; 85 } VBOXSERVICELACLIENTINFO, *PVBOXSERVICELACLIENTINFO; 86 87 74 88 /******************************************************************************* 75 89 * Global Variables * … … 87 101 /** The VM session ID. Changes whenever the VM is restored or reset. */ 88 102 static uint64_t g_idVMInfoSession; 103 /** The last attached locartion awareness (LA) client timestamp. */ 104 static uint64_t g_LAClientAttachedTS = 0; 105 /** The current LA client info. */ 106 static VBOXSERVICELACLIENTINFO g_LAClientInfo; 89 107 90 108 … … 92 110 * Defines * 93 111 *******************************************************************************/ 112 static const char *g_pszLAActiveClient = "/VirtualBox/HostInfo/VRDP/ActiveClient"; 113 94 114 #ifdef VBOX_WITH_DBUS 95 115 /** ConsoleKit defines (taken from 0.4.5). */ … … 153 173 g_cMsVMInfoInterval = g_DefaultInterval * 1000; 154 174 if (!g_cMsVMInfoInterval) 155 g_cMsVMInfoInterval = 10 * 1000; 175 { 176 /* Set it to 5s by default for location awareness checks. */ 177 g_cMsVMInfoInterval = 5 * 1000; 178 } 156 179 157 180 int rc = RTSemEventMultiCreate(&g_hVMInfoEvent); … … 161 184 /* The status code is ignored as this information is not available with VBox < 3.2.10. */ 162 185 186 /* Initialize the LA client object. */ 187 RT_ZERO(g_LAClientInfo); 188 163 189 rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID); 164 190 if (RT_SUCCESS(rc)) 165 VBoxServiceVerbose(3, " VMInfo:Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID);191 VBoxServiceVerbose(3, "Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID); 166 192 else 167 193 { … … 170 196 if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */ 171 197 { 172 VBoxServiceVerbose(0, " VMInfo:Guest property service is not available, disabling the service\n");198 VBoxServiceVerbose(0, "Guest property service is not available, disabling the service\n"); 173 199 rc = VERR_SERVICE_DISABLED; 174 200 } 175 201 else 176 VBoxServiceError(" VMInfo:Failed to connect to the guest property service! Error: %Rrc\n", rc);202 VBoxServiceError("Failed to connect to the guest property service! Error: %Rrc\n", rc); 177 203 RTSemEventMultiDestroy(g_hVMInfoEvent); 178 204 g_hVMInfoEvent = NIL_RTSEMEVENTMULTI; … … 196 222 } 197 223 return rc; 224 } 225 226 227 /** 228 * Retrieves a specifiy client LA property. 229 * 230 * @return IPRT status code. 231 * @param uClientID LA client ID to retrieve property for. 232 * @param pszProperty Property (without path) to retrieve. 233 * @param ppszValue Where to store value of property. 234 * @param puTimestamp Timestamp of property to retrieve. Optional. 235 */ 236 static int vboxServiceGetLAClientValue(uint32_t uClientID, const char *pszProperty, 237 char **ppszValue, uint64_t *puTimestamp) 238 { 239 AssertReturn(uClientID, VERR_INVALID_PARAMETER); 240 AssertPtrReturn(pszProperty, VERR_INVALID_POINTER); 241 242 int rc; 243 244 char pszClientPath[255]; 245 if (RTStrPrintf(pszClientPath, sizeof(pszClientPath), 246 "/VirtualBox/HostInfo/VRDP/Client/%RU32/%s", uClientID, pszProperty)) 247 { 248 rc = VBoxServiceReadHostProp(g_uVMInfoGuestPropSvcClientID, pszClientPath, true /* Read only */, 249 ppszValue, NULL /* Flags */, puTimestamp); 250 } 251 else 252 rc = VERR_NO_MEMORY; 253 254 return rc; 255 } 256 257 258 /** 259 * Retrieves LA client information. On success the returned structure will have allocated 260 * objects which need to be free'd with vboxServiceFreeLAClientInfo. 261 * 262 * @return IPRT status code. 263 * @param uClientID Client ID to retrieve information for. 264 * @param pClient Pointer where to store the client information. 265 */ 266 static int vboxServiceGetLAClientInfo(uint32_t uClientID, PVBOXSERVICELACLIENTINFO pClient) 267 { 268 AssertReturn(uClientID, VERR_INVALID_PARAMETER); 269 AssertPtrReturn(pClient, VERR_INVALID_POINTER); 270 271 int rc = vboxServiceGetLAClientValue(uClientID, "Name", &pClient->pszName, 272 NULL /* Timestamp */); 273 if (RT_SUCCESS(rc)) 274 { 275 char *pszAttach; 276 rc = vboxServiceGetLAClientValue(uClientID, "Attach", &pszAttach, 277 &pClient->uAttachedTS); 278 if (RT_SUCCESS(rc)) 279 { 280 AssertPtr(pszAttach); 281 pClient->fAttached = !RTStrICmp(pszAttach, "1") ? true : false; 282 283 RTStrFree(pszAttach); 284 } 285 } 286 if (RT_SUCCESS(rc)) 287 rc = vboxServiceGetLAClientValue(uClientID, "Location", &pClient->pszLocation, 288 NULL /* Timestamp */); 289 if (RT_SUCCESS(rc)) 290 rc = vboxServiceGetLAClientValue(uClientID, "Domain", &pClient->pszDomain, 291 NULL /* Timestamp */); 292 if (RT_SUCCESS(rc)) 293 pClient->uID = uClientID; 294 295 return rc; 296 } 297 298 299 /** 300 * Frees all allocated LA client information of a structure. 301 * 302 * @param pClient Pointer to client information structure to free. 303 */ 304 static void vboxServiceFreeLAClientInfo(PVBOXSERVICELACLIENTINFO pClient) 305 { 306 if (pClient) 307 { 308 if (pClient->pszName) 309 RTStrFree(pClient->pszName); 310 if (pClient->pszLocation) 311 RTStrFree(pClient->pszLocation); 312 if (pClient->pszDomain) 313 RTStrFree(pClient->pszDomain); 314 315 pClient = NULL; 316 } 198 317 } 199 318 … … 433 552 } 434 553 435 VBoxServiceVerbose(4, "ConsoleKit: session '%s' is %s\n", 554 VBoxServiceVerbose(4, "ConsoleKit: session '%s' is %s\n", 436 555 *ppszCurSession, fActive ? "active" : "not active"); 437 556 … … 613 732 if (RT_FAILURE(rc)) 614 733 { 615 VBoxServiceError(" VMInfo:Error writing logged on users list, rc=%Rrc\n", rc);734 VBoxServiceError("Error writing logged on users list, rc=%Rrc\n", rc); 616 735 cUsersInList = 0; /* Reset user count on error. */ 617 736 } … … 620 739 if (RT_FAILURE(rc)) 621 740 { 622 VBoxServiceError(" VMInfo:Error writing logged on users count, rc=%Rrc\n", rc);741 VBoxServiceError("Error writing logged on users count, rc=%Rrc\n", rc); 623 742 cUsersInList = 0; /* Reset user count on error. */ 624 743 } … … 629 748 cUsersInList == 0 ? "true" : "false"); 630 749 if (RT_FAILURE(rc)) 631 VBoxServiceError(" VMInfo:Error writing no logged in users beacon, rc=%Rrc\n", rc);750 VBoxServiceError("Error writing no logged in users beacon, rc=%Rrc\n", rc); 632 751 g_cVMInfoLoggedInUsers = cUsersInList; 633 752 } … … 1066 1185 break; 1067 1186 1187 /* Whether to wait for event semaphore or not. */ 1188 bool fWait = true; 1189 1190 /* Check for location awareness. This most likely only 1191 * works with VBox (latest) 4.1 and up. */ 1192 1193 /* Check for new connection. */ 1194 char *pszLAClientID; 1195 int rc2 = VBoxServiceReadHostProp(g_uVMInfoGuestPropSvcClientID, g_pszLAActiveClient, true /* Read only */, 1196 &pszLAClientID, NULL /* Flags */, NULL /* Timestamp */); 1197 if (RT_SUCCESS(rc2)) 1198 { 1199 if (RTStrICmp(pszLAClientID, "0")) /* Is a client connected? */ 1200 { 1201 uint32_t uLAClientID = RTStrToInt32(pszLAClientID); 1202 uint64_t uLAClientAttachedTS; 1203 1204 /* Peek at "Attach" value to figure out if hotdesking happened. */ 1205 char *pszAttach = NULL; 1206 rc2 = vboxServiceGetLAClientValue(uLAClientID, "Attach", &pszAttach, 1207 &uLAClientAttachedTS); 1208 1209 if ( RT_SUCCESS(rc2) 1210 && ( !g_LAClientAttachedTS 1211 || (g_LAClientAttachedTS != uLAClientAttachedTS))) 1212 { 1213 vboxServiceFreeLAClientInfo(&g_LAClientInfo); 1214 1215 /* Note: There is a race between setting the guest properties by the host and getting them by 1216 * the guest. */ 1217 rc2 = vboxServiceGetLAClientInfo(uLAClientID, &g_LAClientInfo); 1218 if (RT_SUCCESS(rc2)) 1219 { 1220 VBoxServiceVerbose(1, "VRDP: Hotdesk client %s with ID=%RU32, Name=%s, Domain=%s\n", 1221 /* If g_LAClientAttachedTS is 0 this means there already was an active 1222 * hotdesk session when VBoxService started. */ 1223 !g_LAClientAttachedTS ? "already active" : g_LAClientInfo.fAttached ? "connected" : "disconnected", 1224 uLAClientID, g_LAClientInfo.pszName, g_LAClientInfo.pszDomain); 1225 1226 g_LAClientAttachedTS = g_LAClientInfo.uAttachedTS; 1227 1228 /* Don't wait for event semaphore below anymore because we now know that the client 1229 * changed. This means we need to iterate all VM information again immediately. */ 1230 fWait = false; 1231 } 1232 else 1233 { 1234 static int s_iBitchedAboutLAClientInfo = 0; 1235 if (s_iBitchedAboutLAClientInfo++ < 10) 1236 VBoxServiceError("Error getting active location awareness client info, rc=%Rrc\n", rc2); 1237 } 1238 } 1239 else if (RT_FAILURE(rc2)) 1240 VBoxServiceError("Error getting attached value of location awareness client %RU32, rc=%Rrc\n", 1241 uLAClientID, rc2); 1242 if (pszAttach) 1243 RTStrFree(pszAttach); 1244 } 1245 else 1246 { 1247 VBoxServiceVerbose(1, "VRDP: UTTSC disconnected from VRDP server\n"); 1248 vboxServiceFreeLAClientInfo(&g_LAClientInfo); 1249 } 1250 1251 RTStrFree(pszLAClientID); 1252 } 1253 else 1254 { 1255 static int s_iBitchedAboutLAClient = 0; 1256 if ( (rc2 != VERR_NOT_FOUND) /* No location awareness installed, skip. */ 1257 && s_iBitchedAboutLAClient++ < 3) 1258 VBoxServiceError("VRDP: Querying connected location awareness client failed with rc=%Rrc\n", rc2); 1259 } 1260 1068 1261 /* 1069 1262 * Flush all properties if we were restored. … … 1073 1266 if (idNewSession != g_idVMInfoSession) 1074 1267 { 1075 VBoxServiceVerbose(3, " VMInfo:The VM session ID changed, flushing all properties\n");1268 VBoxServiceVerbose(3, "The VM session ID changed, flushing all properties\n"); 1076 1269 vboxserviceVMInfoWriteFixedProperties(); 1077 1270 VBoxServicePropCacheFlush(&g_VMInfoPropCache); … … 1087 1280 if (*pfShutdown) 1088 1281 break; 1089 int rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval); 1282 if (fWait) 1283 rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval); 1090 1284 if (*pfShutdown) 1091 1285 break; 1092 1286 if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2)) 1093 1287 { 1094 VBoxServiceError(" VMInfo:RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);1288 VBoxServiceError("RTSemEventMultiWait failed; rc2=%Rrc\n", rc2); 1095 1289 rc = rc2; 1096 1290 break; … … 1101 1295 rc2 = RTSemEventMultiReset(g_hVMInfoEvent); 1102 1296 if (RT_FAILURE(rc2)) 1103 rc2 = VBoxServiceError(" VMInfo:RTSemEventMultiReset failed; rc2=%Rrc\n", rc2);1297 rc2 = VBoxServiceError("RTSemEventMultiReset failed; rc2=%Rrc\n", rc2); 1104 1298 } 1105 1299 } … … 1140 1334 int rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat)); 1141 1335 1336 /* Destroy LA client info. */ 1337 vboxServiceFreeLAClientInfo(&g_LAClientInfo); 1338 1142 1339 /* Destroy property cache. */ 1143 1340 VBoxServicePropCacheDestroy(&g_VMInfoPropCache); … … 1146 1343 rc = VbglR3GuestPropDisconnect(g_uVMInfoGuestPropSvcClientID); 1147 1344 if (RT_FAILURE(rc)) 1148 VBoxServiceError(" VMInfo:Failed to disconnect from guest property service! Error: %Rrc\n", rc);1345 VBoxServiceError("Failed to disconnect from guest property service! Error: %Rrc\n", rc); 1149 1346 g_uVMInfoGuestPropSvcClientID = 0; 1150 1347
Note:
See TracChangeset
for help on using the changeset viewer.