110
125
static Bool vmResumed;
112
133
static Bool GuestInfoUpdateVmdb(ToolsAppCtx *ctx, GuestInfoType infoType, void *info);
113
134
static Bool SetGuestInfo(ToolsAppCtx *ctx, GuestInfoType key,
114
const char *value, char delimiter);
115
static Bool DiskInfoChanged(PGuestDiskInfo diskInfo);
136
static void SendUptime(ToolsAppCtx *ctx);
137
static Bool DiskInfoChanged(const GuestDiskInfo *diskInfo);
116
138
static void GuestInfoClearCache(void);
117
139
static GuestNicList *NicInfoV3ToV2(const NicInfoV3 *infoV3);
118
140
static void TweakGatherLoop(ToolsAppCtx *ctx, gboolean enable);
122
* Lauches the VM support process in the guest when requested by the host.
124
* @param[in] data RPC request data.
126
* @return TRUE on success.
144
******************************************************************************
145
* GuestInfoVMSupport -- */ /**
147
* Launches the vm-support process. Data returned asynchronously via RPCI.
149
* @param[in] data RPC request data.
151
* @return TRUE if able to launch script, FALSE if script failed.
153
******************************************************************************
203
230
******************************************************************************
204
* GuestInfoServerConfReload -- */ /**
206
* @brief Reconfigures the poll loop interval upon config file reload.
208
* @param[in] src The source object.
209
* @param[in] ctx The application context.
210
* @param[in] data Unused.
212
******************************************************************************
216
GuestInfoServerConfReload(gpointer src,
220
TweakGatherLoop(ctx, TRUE);
225
******************************************************************************
226
* GuestInfoServerIOFreeze -- */ /**
228
* IO freeze signal handler. Disables info gathering while I/O is frozen.
231
* @param[in] src The source object.
232
* @param[in] ctx The application context.
233
* @param[in] freeze Whether I/O is being frozen.
234
* @param[in] data Unused.
236
******************************************************************************
240
GuestInfoServerIOFreeze(gpointer src,
245
TweakGatherLoop(ctx, !freeze);
250
* Cleanup internal data on shutdown.
252
* @param[in] src The source object.
253
* @param[in] ctx Unused.
254
* @param[in] data Unused.
258
GuestInfoServerShutdown(gpointer src,
262
GuestInfoClearCache();
264
if (gatherTimeoutSource != NULL) {
265
g_source_destroy(gatherTimeoutSource);
266
gatherTimeoutSource = NULL;
272
* Reset callback - sets the internal flag that says we should purge all
275
* @param[in] src The source object.
276
* @param[in] ctx Unused.
277
* @param[in] data Unused.
281
GuestInfoServerReset(gpointer src,
290
* Send the guest uptime through the backdoor, if @a set is TRUE.
292
* @param[in] src The source object.
293
* @param[in] ctx The application context.
294
* @param[in] set Whether capabilities are being set.
295
* @param[in] data Unused.
301
GuestInfoServerSendUptime(gpointer src,
307
gchar *uptime = g_strdup_printf("%"FMT64"u", System_Uptime());
308
g_debug("Setting guest uptime to '%s'\n", uptime);
309
GuestInfoUpdateVmdb(ctx, INFO_UPTIME, uptime);
317
* Responds to a "broadcastIP" Set_Option command, by sending the primary IP
320
* @param[in] src The source object.
321
* @param[in] ctx The application context.
322
* @param[in] option Option name.
323
* @param[in] value Option value.
324
* @param[in] data Unused.
328
GuestInfoServerSetOption(gpointer src,
337
if (strcmp(option, TOOLSOPTION_BROADCASTIP) != 0) {
341
if (strcmp(value, "0") == 0) {
346
if (strcmp(value, "1") != 0) {
350
ip = NetUtil_GetPrimaryIP();
354
msg = g_strdup_printf("info-set guestinfo.ip %s", ip);
355
ret = RpcChannel_Send(ctx->rpc, msg, strlen(msg) + 1, NULL, NULL);
361
return (gboolean) ret;
366
* Periodically collects all the desired guest information and updates VMDB.
231
* GuestInfoGather -- */ /**
233
* Collects all the desired guest information and updates the VMX.
368
235
* @param[in] data The application context.
237
* @return TRUE to indicate that the timer should be rescheduled.
239
******************************************************************************
374
243
GuestInfoGather(gpointer data)
377
char osNameFull[MAX_VALUE_LEN];
378
char osName[MAX_VALUE_LEN];
245
char name[GUESTINFO_MAX_VALUE_SIZE];
246
char osNameFull[GUESTINFO_MAX_VALUE_SIZE];
247
char osName[GUESTINFO_MAX_VALUE_SIZE];
379
248
gboolean disableQueryDiskInfo;
380
249
NicInfoV3 *nicInfo = NULL;
381
GuestDiskInfo diskInfo;
250
GuestDiskInfo *diskInfo = NULL;
382
251
#if defined(_WIN32) || defined(linux)
383
252
GuestMemInfo vmStats = {0};
253
gboolean perfmonEnabled;
385
255
ToolsAppCtx *ctx = data;
413
283
g_key_file_get_boolean(ctx->config, CONFGROUPNAME_GUESTINFO,
414
284
CONFNAME_GUESTINFO_DISABLEQUERYDISKINFO, NULL);
415
285
if (!disableQueryDiskInfo) {
416
if (!GuestInfo_GetDiskInfo(&diskInfo)) {
286
if ((diskInfo = GuestInfo_GetDiskInfo()) == NULL) {
417
287
g_warning("Failed to get disk info.\n");
419
if (!GuestInfoUpdateVmdb(ctx, INFO_DISK_FREE_SPACE, &diskInfo)) {
289
if (GuestInfoUpdateVmdb(ctx, INFO_DISK_FREE_SPACE, diskInfo)) {
290
GuestInfo_FreeDiskInfo(gInfoCache.diskInfo);
291
gInfoCache.diskInfo = diskInfo;
420
293
g_warning("Failed to update VMDB\n.");
294
GuestInfo_FreeDiskInfo(diskInfo);
422
GuestInfo_FreeDiskInfo(&diskInfo);
426
if (!GuestInfo_GetFqdn(sizeof name, name)) {
299
if (!System_GetNodeName(sizeof name, name)) {
427
300
g_warning("Failed to get netbios name.\n");
428
301
} else if (!GuestInfoUpdateVmdb(ctx, INFO_DNS_NAME, name)) {
429
302
g_warning("Failed to update VMDB.\n");
450
323
/* Send the uptime to VMX so that it can detect soft resets. */
451
GuestInfoServerSendUptime(NULL, ctx, TRUE, NULL);
453
326
#if defined(_WIN32) || defined(linux)
454
327
/* Send the vmstats to the VMX. */
328
perfmonEnabled = !g_key_file_get_boolean(ctx->config,
329
CONFGROUPNAME_GUESTINFO,
330
CONFNAME_GUESTINFO_DISABLEPERFMON,
456
if (!GuestInfo_PerfMon(&vmStats)) {
457
g_warning("Failed to get vmstats.\n");
460
if (!GuestInfoUpdateVmdb(ctx, INFO_MEMORY, &vmStats)) {
461
g_warning("Failed to send vmstats.\n");
333
if (perfmonEnabled) {
334
if (!GuestInfo_PerfMon(&vmStats)) {
335
g_warning("Failed to get vmstats.\n");
338
if (!GuestInfoUpdateVmdb(ctx, INFO_MEMORY, &vmStats)) {
339
g_warning("Failed to send vmstats.\n");
471
*----------------------------------------------------------------------
473
* GuestInfoConvertNicInfoToNicInfoV1 --
475
* Convert the new dynamic nicInfoNew to fixed size struct GuestNicInfoV1.
478
* TRUE if successfully converted
482
* If number of NICs or number of IP addresses on any of the NICs
483
* exceeding MAX_NICS and MAX_IPS respectively, the extra ones
484
* are truncated, on successful return.
486
*----------------------------------------------------------------------
350
******************************************************************************
351
* GuestInfoConvertNicInfoToNicInfoV1 -- */ /**
353
* Converts V3 XDR NicInfo to hand-packed GuestNicInfoV1.
355
* @note Any NICs above MAX_NICS or IPs above MAX_IPS will be truncated.
357
* @param[in] info V3 input data.
358
* @param[out] infoV1 V1 output data.
360
* @retval TRUE Conversion succeeded.
361
* @retval FALSE Conversion failed.
363
******************************************************************************
490
GuestInfoConvertNicInfoToNicInfoV1(NicInfoV3 *info, // IN
491
GuestNicInfoV1 *infoV1) // OUT
367
GuestInfoConvertNicInfoToNicInfoV1(NicInfoV3 *info,
368
GuestNicInfoV1 *infoV1)
546
*-----------------------------------------------------------------------------
548
* GuestInfoUpdateVmdb --
550
* Update VMDB with new guest information.
551
* This is the only function that should need to change when the VMDB pipe
552
* is implemented. Since we dont currently have a VMDB instance in the guest
553
* the function updates the VMDB instance on the host. Updates are sent only
554
* if the values have changed.
557
* TRUE on success, FALSE on failure.
560
* VMDB is updated if the given value has changed.
562
*-----------------------------------------------------------------------------
423
******************************************************************************
424
* GuestInfoUpdateVmdb -- */ /**
426
* Push singular GuestInfo snippets to the VMX.
428
* @note Data are cached, so updates are sent only if they have changed.
430
* @param[in] ctx Application context.
431
* @param[in] infoType Guest information type.
432
* @param[in] info Type-specific information.
434
* @retval TRUE Update sent successfully.
435
* @retval FALSE Had trouble with serialization or transmission.
437
******************************************************************************
816
692
* it's safe to send it from 64-bit Tools to a 32-bit VMX, etc.
818
694
memcpy(request + offset, &partitionCount, sizeof partitionCount);
819
memcpy(request + offset + sizeof partitionCount, pdi->partitionList,
820
sizeof *pdi->partitionList * pdi->numEntries);
697
* Conditioned because memcpy(dst, NULL, 0) -may- lead to undefined
700
if (pdi->partitionList) {
701
memcpy(request + offset + sizeof partitionCount, pdi->partitionList,
702
sizeof *pdi->partitionList * pdi->numEntries);
822
705
g_debug("sizeof request is %d\n", requestSize);
823
706
status = RpcChannel_Send(ctx->rpc, request, requestSize, &reply, &replyLen);
856
*----------------------------------------------------------------------
860
* Ask Vmx to write some information about the guest into VMDB.
864
* TRUE/FALSE depending on whether the RPCI succeeded or failed.
870
*----------------------------------------------------------------------
734
******************************************************************************
735
* SendUptime -- */ /**
737
* Send the guest uptime through the backdoor.
739
* @param[in] ctx The application context.
741
******************************************************************************
745
SendUptime(ToolsAppCtx *ctx)
747
gchar *uptime = g_strdup_printf("%"FMT64"u", System_Uptime());
748
g_debug("Setting guest uptime to '%s'\n", uptime);
749
GuestInfoUpdateVmdb(ctx, INFO_UPTIME, uptime);
755
******************************************************************************
756
* SetGuestInfo -- */ /**
758
* Sends a simple key-value update request to the VMX.
760
* @param[in] ctx Application context.
761
* @param[in] key VMDB key to set
762
* @param[in] value GuestInfo data
764
* @retval TRUE RPCI succeeded.
765
* @retval FALSE RPCI failed.
767
******************************************************************************
874
SetGuestInfo(ToolsAppCtx *ctx, // IN: application context
875
GuestInfoType key, // IN: the VMDB key to set
876
const char *value, // IN:
877
char delimiter) // IN: delimiting character for the rpc
878
// message. 0 indicates default.
771
SetGuestInfo(ToolsAppCtx *ctx,
912
*-----------------------------------------------------------------------------
914
* GuestInfoFindMacAddress --
916
* Locates a NIC with the given MAC address in the NIC list.
919
* If there is an entry in nicInfo which corresponds to this MAC address,
920
* it is returned. If not NULL is returned.
925
*-----------------------------------------------------------------------------
808
******************************************************************************
809
* GuestInfoFindMacAddress -- */ /**
811
* Locates a NIC with the given MAC address in the NIC list.
813
* @param[in] nicInfo NicInfoV3 container.
814
* @param[in] macAddress Requested MAC address.
816
* @return Valid pointer if NIC found, else NULL.
818
******************************************************************************
929
823
GuestInfoFindMacAddress(NicInfoV3 *nicInfo, // IN/OUT
930
824
const char *macAddress) // IN
946
*----------------------------------------------------------------------
950
* Checks whether disk info information just obtained is different from
951
* the information last sent to VMDB.
955
* TRUE if the disk info has changed, FALSE otherwise.
961
*----------------------------------------------------------------------
840
******************************************************************************
841
* DiskInfoChanged -- */ /**
843
* Checks whether disk info information just obtained is different from the
844
* information last sent to the VMX.
846
* @param[in] diskInfo New disk info.
848
* @retval TRUE Data has changed.
849
* @retval FALSE Data has not changed.
851
******************************************************************************
965
DiskInfoChanged(PGuestDiskInfo diskInfo) // IN:
855
DiskInfoChanged(const GuestDiskInfo *diskInfo)
1187
1078
******************************************************************************
1188
1079
* BEGIN Tools Core Services goodies.
1190
* TODO Move GuestInfoServerShutdown and friends within this block. Saving
1191
* that for a later changeset.
1084
******************************************************************************
1085
* GuestInfoServerConfReload -- */ /**
1087
* @brief Reconfigures the poll loop interval upon config file reload.
1089
* @param[in] src The source object.
1090
* @param[in] ctx The application context.
1091
* @param[in] data Unused.
1093
******************************************************************************
1097
GuestInfoServerConfReload(gpointer src,
1101
TweakGatherLoop(ctx, TRUE);
1106
******************************************************************************
1107
* GuestInfoServerIOFreeze -- */ /**
1109
* IO freeze signal handler. Disables info gathering while I/O is frozen.
1112
* @param[in] src The source object.
1113
* @param[in] ctx The application context.
1114
* @param[in] freeze Whether I/O is being frozen.
1115
* @param[in] data Unused.
1117
******************************************************************************
1121
GuestInfoServerIOFreeze(gpointer src,
1126
TweakGatherLoop(ctx, !freeze);
1131
******************************************************************************
1132
* GuestInfoServerShutdown -- */ /**
1134
* Cleanup internal data on shutdown.
1136
* @param[in] src The source object.
1137
* @param[in] ctx Unused.
1138
* @param[in] data Unused.
1140
******************************************************************************
1144
GuestInfoServerShutdown(gpointer src,
1148
GuestInfoClearCache();
1150
if (gatherTimeoutSource != NULL) {
1151
g_source_destroy(gatherTimeoutSource);
1152
gatherTimeoutSource = NULL;
1156
NetUtil_FreeIpHlpApiDll();
1162
******************************************************************************
1163
* GuestInfoServerReset -- */ /**
1165
* Reset callback - sets the internal flag that says we should purge all
1168
* @param[in] src The source object.
1169
* @param[in] ctx Unused.
1170
* @param[in] data Unused.
1172
******************************************************************************
1176
GuestInfoServerReset(gpointer src,
1185
******************************************************************************
1186
* GuestInfoServerSendCaps -- */ /**
1188
* Send capabilities callback. If setting capabilities, sends VM's uptime.
1190
* This is weird. There's sort of an old Tools <-> VMX understanding that
1191
* vmsvc should report the guest's uptime in response to a "what're your
1192
* capabilities?" RPC.
1194
* @param[in] src The source object.
1195
* @param[in] ctx The application context.
1196
* @param[in] set TRUE if setting capabilities, FALSE if unsetting them.
1197
* @param[in] data Client data.
1199
* @retval NULL This function returns no capabilities.
1201
******************************************************************************
1205
GuestInfoServerSendCaps(gpointer src,
1218
******************************************************************************
1219
* GuestInfoServerSetOption -- */ /**
1221
* Responds to a "broadcastIP" Set_Option command, by sending the primary IP
1224
* @param[in] src The source object.
1225
* @param[in] ctx The application context.
1226
* @param[in] option Option name.
1227
* @param[in] value Option value.
1228
* @param[in] data Unused.
1230
******************************************************************************
1234
GuestInfoServerSetOption(gpointer src,
1236
const gchar *option,
1243
if (strcmp(option, TOOLSOPTION_BROADCASTIP) != 0) {
1247
if (strcmp(value, "0") == 0) {
1252
if (strcmp(value, "1") != 0) {
1256
ip = NetUtil_GetPrimaryIP();
1260
msg = g_strdup_printf("info-set guestinfo.ip %s", ip);
1261
ret = RpcChannel_Send(ctx->rpc, msg, strlen(msg) + 1, NULL, NULL);
1267
return (gboolean) ret;
1272
******************************************************************************
1273
* ToolsOnLoad -- */ /**
1196
1275
* Plugin entry point. Initializes internal plugin state.
1198
1277
* @param[in] ctx The app context.
1200
1279
* @return The registration data.
1281
******************************************************************************
1203
1284
TOOLS_MODULE_EXPORT ToolsPluginData *
1218
1299
{ RPC_VMSUPPORT_START, GuestInfoVMSupport, ®Data, NULL, NULL, 0 }
1220
1301
ToolsPluginSignalCb sigs[] = {
1221
{ TOOLS_CORE_SIG_CAPABILITIES, GuestInfoServerSendUptime, NULL },
1302
{ TOOLS_CORE_SIG_CAPABILITIES, GuestInfoServerSendCaps, NULL },
1222
1303
{ TOOLS_CORE_SIG_CONF_RELOAD, GuestInfoServerConfReload, NULL },
1223
1304
{ TOOLS_CORE_SIG_IO_FREEZE, GuestInfoServerIOFreeze, NULL },
1224
1305
{ TOOLS_CORE_SIG_RESET, GuestInfoServerReset, NULL },