~henrix/ubuntu/precise/open-vm-dkms/lp-1416003

« back to all changes in this revision

Viewing changes to guestd/toolsDaemon.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-10-23 15:32:00 UTC
  • mfrom: (1.1.2 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20081023153200-gc1bfx89hj35c799
Tags: 2008.10.10-123053-2
* Correcting typo in dh_installinit call.
* Downgrading depends on module-assistant to recommends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
 
40
40
#ifdef _WIN32
41
41
#   include <windows.h>
42
 
#   include "win95.h"
43
42
#   include "win32u.h"
44
43
#   include "hgfsUsabilityLib.h"
 
44
#   include "ServiceHelpers.h"
45
45
#endif
46
46
 
47
47
 
87
87
#define RPCIN_POLL_TIME      10
88
88
/* sync the time once a minute */
89
89
#define TIME_SYNC_TIME     6000
 
90
/* only PERCENT_CORRECTION percent is corrected everytime */
 
91
#define PERCENT_CORRECTION   50
90
92
 
91
93
/*
92
94
 * Table mapping state changes to their conf file names.
130
132
 */
131
133
 
132
134
Bool
133
 
ToolsDaemon_SyncTime(Bool syncBackward)
 
135
ToolsDaemon_SyncTime(Bool slewCorrection,  // IN: Is clock slewing enabled?
 
136
                     Bool syncOnce,        // IN: Is this function called in a loop?
 
137
                     void *toolsData)      // IN: Opaque data
134
138
{
135
139
   Backdoor_proto bp;
136
140
   int64 maxTimeLag;
 
141
   int64 interruptLag;
137
142
   int64 guestSecs;
138
143
   int64 guestUsecs;
139
144
   int64 hostSecs;
141
146
   int64 diffSecs;
142
147
   int64 diffUsecs;
143
148
   int64 diff;
 
149
   ToolsDaemon_Data *data = (ToolsDaemon_Data *) toolsData;
 
150
   Bool timeLagCall = FALSE;
144
151
#ifdef VMX86_DEBUG
145
152
   static int64 lastHostSecs = 0;
146
153
   int64 secs1, usecs1;
152
159
   Debug("Daemon: Synchronizing time\n");
153
160
 
154
161
   /* 
155
 
    * Get the host OS time & the max lag limit. The GETTIME backdoor command
156
 
    * suffers from a 136-year overflow problem that cannot be corrected
157
 
    * without breaking backwards compatibility with older Tools. Instead, we
158
 
    * introduced the newer BDOOR_CMD_GETTIMEFULL (which is overflow safe), and
159
 
    * we'll try it before falling back on the unsafe BDOOR_CMD_GETTIME.
160
 
    *
161
 
    * Note that BDOOR_CMD_GETTIMEFULL will not touch EAX when it succeeds. So
162
 
    * we check for errors by comparing EAX to BDOOR_MAGIC, which was set by the
163
 
    * call to Backdoor() prior to touching the backdoor port.
 
162
    * We need 3 things from the host, and there exist 3 different versions of
 
163
    * the calls (described further below):
 
164
    * 1) host time
 
165
    * 2) maximum time lag allowed (config option), which is a 
 
166
    *    threshold that keeps the tools from being over eager about
 
167
    *    resetting the time when it is only a little bit off.
 
168
    * 3) interrupt lag
 
169
    *
 
170
    * First 2 versions of the call add interrupt lag to the maximum allowed
 
171
    * time lag, where as in the last call it is returned separately.
 
172
    *
 
173
    * Three versions of the call:
 
174
    *
 
175
    * - BDOOR_CMD_GETTIME: suffers from a 136-year overflow problem that
 
176
    *   cannot be corrected without breaking backwards compatibility with
 
177
    *   older Tools. So, we have the newer BDOOR_CMD_GETTIMEFULL, which is
 
178
    *   overflow safe.
 
179
    *
 
180
    * - BDOOR_CMD_GETTIMEFULL: overcomes the problem above.
 
181
    *
 
182
    * - BDOOR_CMD_GETTIMEFULL_WITH_LAG: Both BDOOR_CMD_GETTIMEFULL and
 
183
    *   BDOOR_CMD_GETTIME returns max lag limit as interrupt lag + the maximum
 
184
    *   allowed time lag. BDOOR_CMD_GETTIMEFULL_WITH_LAG separates these two
 
185
    *   values. This is helpful when synchronizing time backwards by slewing
 
186
    *   the clock.
 
187
    *
 
188
    * We use BDOOR_CMD_GETTIMEFULL_WITH_LAG first and fall back to
 
189
    * BDOOR_CMD_GETTIMEFULL or BDOOR_CMD_GETTIME.
 
190
    *
 
191
    * Note that BDOOR_CMD_GETTIMEFULL and BDOOR_CMD_GETTIMEFULL_WITH_LAG will
 
192
    * not touch EAX when it succeeds. So we check for errors by comparing EAX to
 
193
    * BDOOR_MAGIC, which was set by the call to Backdoor() prior to touching the
 
194
    * backdoor port.
164
195
    */
165
 
   bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL;
 
196
   bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL_WITH_LAG;
166
197
   Backdoor(&bp);
167
198
   if (bp.out.ax.word == BDOOR_MAGIC) {
168
199
      hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word;
 
200
      interruptLag = bp.out.di.word;
 
201
      timeLagCall = TRUE;
 
202
      Debug("Using BDOOR_CMD_GETTIMEFULL_WITH_LAG\n");
169
203
   } else {
170
 
      Debug("New get time command not supported by current host, attempting "
171
 
            "older command.\n");
172
 
      bp.in.cx.halfs.low = BDOOR_CMD_GETTIME;
 
204
      Debug("BDOOR_CMD_GETTIMEFULL_WITH_LAG not supported by current host, attempting "
 
205
            "BDOOR_CMD_GETTIMEFULL\n");
 
206
      interruptLag = 0;
 
207
      bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL;
173
208
      Backdoor(&bp);
174
 
      hostSecs = bp.out.ax.word;
 
209
      if (bp.out.ax.word == BDOOR_MAGIC) {
 
210
         hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word;
 
211
      } else {
 
212
         Debug("BDOOR_CMD_GETTIMEFULL not supported by current host, attempting "
 
213
               "BDOOR_CMD_GETTIME\n");
 
214
         bp.in.cx.halfs.low = BDOOR_CMD_GETTIME;
 
215
         Backdoor(&bp);
 
216
         hostSecs = bp.out.ax.word;
 
217
      }
175
218
   }
176
219
   hostUsecs = bp.out.bx.word;
177
 
 
178
 
   /*
179
 
    * maxTimeLag is computed by the VMX as the sum of two things:
180
 
    * 1) A threshold that keeps the tools from being over eager about
181
 
    *    resetting the time when it is only a little bit off.
182
 
    * 2) The current backlog of timer interrupts that still need to be
183
 
    *    delivered to the guest.
184
 
    */
185
220
   maxTimeLag = bp.out.cx.word;
186
221
 
187
222
   if (hostSecs <= 0) {
193
228
 
194
229
   /* Get the guest OS time */
195
230
   if (!System_GetCurrentTime(&guestSecs, &guestUsecs)) {
196
 
      Warning("Unable to retrieve the guest OS time: %s.\n\n",
197
 
              Msg_ErrString());
198
 
 
 
231
      Warning("Unable to retrieve the guest OS time: %s.\n\n", Msg_ErrString());
199
232
      return FALSE;
200
233
   }
201
234
 
203
236
   diffUsecs = hostUsecs - guestUsecs;
204
237
   if (diffUsecs < 0) {
205
238
      diffSecs -= 1;
206
 
      diffUsecs += 1000000L;
 
239
      diffUsecs += 1000000U;
207
240
   }
208
241
   diff = diffSecs * 1000000L + diffUsecs;
209
242
 
211
244
   Debug("Daemon: Guest clock lost %.6f secs; limit=%.2f; "
212
245
         "%"FMT64"d secs since last update\n",
213
246
         diff / 1000000.0, maxTimeLag / 1000000.0, hostSecs - lastHostSecs);
 
247
   Debug("Daemon: %d, %d, %"FMT64"d, %"FMT64"d, %"FMT64"d.\n",
 
248
         syncOnce, slewCorrection, diff, maxTimeLag, interruptLag);
214
249
   lastHostSecs = hostSecs;
215
250
#endif
216
251
 
217
 
   /*
218
 
    * Adjust the guest OS time to equal the host OS time if:
219
 
    * 1) The guest OS is behind the host OS by more than maxTimeLag.
220
 
    * 2) The guest OS is ahead of the host OS and syncBackward
221
 
    *    is specified. syncBackwards is set to TRUE when the tools
222
 
    *    daemon starts and when the timesync feature is toggled from
223
 
    *    FALSE => TRUE.
224
 
    */
225
 
   if (diff > maxTimeLag || syncBackward) {
226
 
      if (!System_AddToCurrentTime(diffSecs, diffUsecs)) {
227
 
          Warning("Unable to set the guest OS time: %s.\n\n",
228
 
                  Msg_ErrString());
229
 
 
230
 
          return FALSE;
231
 
      }
 
252
   if (syncOnce) {
 
253
      /*
 
254
       * Non-loop behavior:
 
255
       *
 
256
       * Perform a step correction if:
 
257
       * 1) The guest OS is behind the host OS by more than maxTimeLag + interruptLag.
 
258
       * 2) The guest OS is ahead of the host OS.
 
259
       */
 
260
      if (diff > maxTimeLag + interruptLag) {
 
261
         System_DisableTimeSlew();
 
262
         if (!System_AddToCurrentTime(diffSecs, diffUsecs)) {
 
263
            Warning("Unable to set the guest OS time: %s.\n\n", Msg_ErrString());
 
264
            return FALSE;
 
265
         }
 
266
      }
 
267
   } else {
 
268
 
 
269
      /*
 
270
       * Loop behavior:
 
271
       *
 
272
       * If guest is behind host by more than maxTimeLag + interruptLag
 
273
       * perform a step correction to the guest clock and ask the monitor
 
274
       * to drop its accumulated catchup (interruptLag).
 
275
       *
 
276
       * Otherwise, perform a slew correction.  Adjust the guest's clock
 
277
       * rate to be either faster or slower than nominal real time, such
 
278
       * that we expect to correct correctionPercent percent of the error
 
279
       * during this synchronization cycle.
 
280
       */
 
281
 
 
282
      if (diff > maxTimeLag + interruptLag) {
 
283
         System_DisableTimeSlew();
 
284
         if (!System_AddToCurrentTime(diffSecs, diffUsecs)) {
 
285
            Warning("Unable to set the guest OS time: %s.\n\n", Msg_ErrString());
 
286
            return FALSE;
 
287
         }
 
288
      } else if (slewCorrection && timeLagCall) {
 
289
         int64 slewDiff;
 
290
 
 
291
         /* Don't consider interruptLag during clock slewing. */
 
292
         slewDiff = diff - interruptLag;
 
293
 
 
294
         /* Correct only data->slewPercentCorrection percent error. */
 
295
         slewDiff = (data->slewPercentCorrection * slewDiff) / 100;
 
296
 
 
297
         if (!System_EnableTimeSlew(slewDiff, data->timeSyncPeriod)) {
 
298
            Warning("Unable to slew the guest OS time: %s.\n\n", Msg_ErrString());
 
299
            return FALSE;
 
300
         }
 
301
      } else {
 
302
         System_DisableTimeSlew();
 
303
      }
 
304
   }
232
305
 
233
306
#ifdef VMX86_DEBUG
234
307
      System_GetCurrentTime(&secs2, &usecs2);
237
310
            secs1, usecs1, secs2, usecs2);
238
311
#endif
239
312
 
240
 
      /*
241
 
       * We have just synchronized the guest time to the host time. Ask
242
 
       * VMware to reset to normal the rate of timer interrupts it forwards
243
 
       * from the host to the guest.
244
 
       */
 
313
   /*
 
314
    * If we have stepped the time, ask TimeTracker to reset to normal the rate
 
315
    * of timer interrupts it forwards from the host to the guest.
 
316
    */
 
317
   if (!System_IsTimeSlewEnabled()) {
245
318
      bp.in.cx.halfs.low = BDOOR_CMD_STOPCATCHUP;
246
319
      Backdoor(&bp);
247
320
   }
274
347
 
275
348
   ASSERT(pConfDict);
276
349
 
277
 
 
278
350
   /*
279
351
    * With the addition of the Sync Driver we can get into a state
280
352
    * where the system drive is frozen, preventing the completion of
293
365
      if (Conf_ReloadFile(pConfDict)) {
294
366
         GuestInfoServer_DisableDiskInfoQuery(
295
367
            GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_DISABLEQUERYDISKINFO));
 
368
 
296
369
         Debug_Set(GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_LOG),
297
370
                   DEBUG_PREFIX);
298
371
         Debug_EnableToFile(GuestApp_GetDictEntry(*pConfDict, CONFNAME_LOGFILE),
335
408
ToolsDaemonTimeSyncLoop(void *clientData) // IN
336
409
{
337
410
   ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
338
 
   uint32 period = 0;
339
411
 
340
412
   ASSERT(data);
341
413
 
342
414
   /* The event has fired: it is no longer valid */
343
415
   data->timeSyncEvent = NULL;
344
416
 
345
 
   if (!ToolsDaemon_SyncTime(FALSE)) {
 
417
   if (!data->timeSyncPeriod) {
 
418
      data->timeSyncPeriod = TIME_SYNC_TIME;
 
419
   }
 
420
   if (!ToolsDaemon_SyncTime(data->slewCorrection, FALSE, clientData)) {
346
421
      Warning("Unable to synchronize time.\n\n");
347
 
 
348
422
      return FALSE;
349
423
   }
350
424
 
351
 
   period = data->timeSyncPeriod ? data->timeSyncPeriod * 100 : TIME_SYNC_TIME;
352
 
   data->timeSyncEvent = EventManager_Add(ToolsDaemonEventQueue, period,
 
425
   data->timeSyncEvent = EventManager_Add(ToolsDaemonEventQueue, data->timeSyncPeriod,
353
426
                                          ToolsDaemonTimeSyncLoop, data);
354
427
   if (data->timeSyncEvent == NULL) {
355
428
      Warning("Unable to run the \"time synchronization\" loop.\n\n");
386
459
   DWORD timeIncrement;
387
460
   DWORD error;
388
461
   BOOL timeAdjustmentDisabled;
389
 
   Bool success = FALSE;
390
 
   /* Below needed for privilege junk. */
391
 
   TOKEN_PRIVILEGES tp;
392
 
   LUID luid;
393
 
   HANDLE token = INVALID_HANDLE_VALUE;
 
462
   BOOL success = FALSE;
394
463
 
395
464
   /*
396
465
    * We need the SE_SYSTEMTIME_NAME privilege to make the change; get
397
 
    * the privilege now (or bail it if we can't).
 
466
    * the privilege now (or bail if we can't).
398
467
    */
399
 
   if (!OpenProcessToken(GetCurrentProcess(),
400
 
                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
401
 
                         &token)) {
402
 
      error = GetLastError();
403
 
      Debug("OpenProcessToken failed: %d", error);
404
 
      goto exit;
405
 
   }
406
 
   if (!LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &luid)) {
407
 
      error = GetLastError();
408
 
      Debug("LookupPrivilegeValue(SE_SYSTEMTIME_NAME) failed: %d", error);
409
 
      goto exit;
410
 
   }
411
 
 
412
 
   memset(&tp, 0, sizeof tp);
413
 
   tp.PrivilegeCount = 1;
414
 
   tp.Privileges[0].Luid = luid;
415
 
   tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
416
 
   if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof tp, NULL, NULL)) {
417
 
      error = GetLastError();
418
 
      Debug("AdjustTokenPrivileges failed: %d", error);
419
 
      goto exit;
 
468
   success = System_SetProcessPrivilege(SE_SYSTEMTIME_NAME, TRUE);
 
469
   if (!success) {
 
470
      return FALSE;
420
471
   }
421
472
 
422
473
   /* Actually try to stop the time daemon. */
459
510
   success = TRUE;
460
511
 
461
512
  exit:
462
 
   if (token != INVALID_HANDLE_VALUE) {
463
 
      CloseHandle(token);
464
 
   }
465
513
   Debug("Stopping time daemon %s.\n", success ? "succeeded" : "failed");
 
514
   System_SetProcessPrivilege(SE_SYSTEMTIME_NAME, FALSE);
466
515
   return success;
467
516
}
468
517
#endif
510
559
      return TRUE;
511
560
   } else if (!start && data->timeSyncEvent != NULL) {
512
561
      Debug("Daemon: Stopping time sync loop\n");
 
562
      System_DisableTimeSlew();
513
563
      EventManager_Remove(data->timeSyncEvent);
514
564
      data->timeSyncEvent = NULL;
515
565
 
864
914
      if (strcmp(name, stateChangeCmdTable[i].tcloCmd) == 0) {
865
915
         const char *script;
866
916
         char *scriptCmd;
867
 
 
868
 
         data->stateChgInProgress = (GuestOsState) stateChangeCmdTable[i].id;
 
917
         unsigned int stateId;
 
918
 
 
919
         stateId = stateChangeCmdTable[i].id;
 
920
         data->stateChgInProgress = (GuestOsState)stateId;
 
921
 
 
922
         /* Check for the toolScripts option. */
 
923
         if (!data->toolScriptOption[stateId]) {
 
924
            ToolsDaemonStateChangeDone(TRUE, data);
 
925
            Debug("Script for %s not configured to run\n", stateChangeCmdTable[i].tcloCmd);
 
926
            return RpcIn_SetRetVals(result, resultLen, "", TRUE);
 
927
         }
869
928
 
870
929
         script = GuestApp_GetDictEntry(*data->pConfDict,
871
 
                                        stateChgConfNames[stateChangeCmdTable[i].id]);
 
930
                                        stateChgConfNames[stateId]);
872
931
         ASSERT(script);
873
932
         if (strlen(script) == 0) {
874
933
            ToolsDaemonStateChangeDone(TRUE, data);
1108
1167
 
1109
1168
#if defined(WIN32)
1110
1169
   HgfsUsability_RegisterServiceCaps();
 
1170
   if (System_GetOSType() >= OS_VISTA) {
 
1171
      ServiceHelpers_SendResolutionCaps();
 
1172
   }
1111
1173
#endif
1112
1174
 
1113
1175
   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
1139
1201
                        size_t argsSize,         // Ignored
1140
1202
                        void *clientData)        // Ignored
1141
1203
{
1142
 
   Bool syncBackward = strcmp(args, "1")==0;
 
1204
   Bool slewCorrection = !strcmp(args, "1");
1143
1205
 
1144
 
   if (!ToolsDaemon_SyncTime(syncBackward)) {
 
1206
   if (!ToolsDaemon_SyncTime(slewCorrection, TRUE, clientData)) {
1145
1207
      return RpcIn_SetRetVals(result, resultLen,
1146
1208
                              "Unable to sync time", FALSE);
1147
1209
   } else {
1201
1263
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
1202
1264
         goto invalid_value;
1203
1265
      }
 
1266
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_SLEWCORRECTION) == 0) {
 
1267
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
1268
         goto invalid_value;
 
1269
      }
 
1270
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERCENTCORRECTION) == 0) {
 
1271
      int32 percent;
 
1272
      if (!StrUtil_StrToInt(&percent, value) || percent == 0 || percent > 100) {
 
1273
         goto invalid_value;
 
1274
      }
 
1275
      Debug("Daemon: update the slew correction percent.\n");
1204
1276
   } else if (strcmp(option, TOOLSOPTION_COPYPASTE) == 0) {
1205
1277
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
1206
1278
         goto invalid_value;
1235
1307
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
1236
1308
         goto invalid_value;
1237
1309
      }
 
1310
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWERON) == 0) {
 
1311
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
1312
         goto invalid_value;
 
1313
      }
 
1314
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWEROFF) == 0) {
 
1315
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
1316
         goto invalid_value;
 
1317
      }
 
1318
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_SUSPEND) == 0) {
 
1319
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
1320
         goto invalid_value;
 
1321
      }
 
1322
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_RESUME) == 0) {
 
1323
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
1324
         goto invalid_value;
 
1325
      }
 
1326
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_REBOOT) == 0) {
 
1327
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
1328
         goto invalid_value;
 
1329
      }
1238
1330
   } else {
1239
1331
      goto invalid_option;
1240
1332
   }
1250
1342
       * Try the one-shot time sync if time sync transitions from
1251
1343
       * 'off' to 'on'.
1252
1344
       */
1253
 
      if (oldTimeSyncValue == 0 && start) {
1254
 
         const char *backwardsAllowed;
1255
 
         
1256
 
         backwardsAllowed = GuestApp_GetDictEntry(data->optionsDict, 
1257
 
                                                  TOOLSOPTION_SYNCTIME_ENABLE);
1258
 
         /* 
1259
 
          * Preserve backwards compatibility: VMX may not ever send us this
1260
 
          * option, so value may be NULL.
1261
 
          */
1262
 
         ToolsDaemon_SyncTime(backwardsAllowed && 
1263
 
                              strcmp(backwardsAllowed, "1") == 0);
 
1345
      if (oldTimeSyncValue == 0 && start &&
 
1346
          GuestApp_GetDictEntry(data->optionsDict, TOOLSOPTION_SYNCTIME_ENABLE)) {
 
1347
         ToolsDaemon_SyncTime(data->slewCorrection, TRUE, clientData);
1264
1348
      }
1265
1349
      oldTimeSyncValue = start;
1266
1350
      
1271
1355
                          retVal = FALSE);
1272
1356
         goto exit;
1273
1357
      }
 
1358
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_SLEWCORRECTION) == 0) {
 
1359
      data->slewCorrection = strcmp(value, "0");
 
1360
      Debug("Daemon: Setting slewCorrection, %d.\n", data->slewCorrection);
 
1361
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERCENTCORRECTION) == 0) {
 
1362
      int32 percent;
 
1363
      if (StrUtil_StrToInt(&percent, value)) {
 
1364
         data->slewPercentCorrection = percent;
 
1365
      }
1274
1366
   } else if (strcmp(option, TOOLSOPTION_BROADCASTIP) == 0 &&
1275
1367
              strcmp(value, "1") == 0) {
1276
1368
      char *ip;
1296
1388
       * just remember the new sync period value.
1297
1389
       */
1298
1390
      if (period != data->timeSyncPeriod) {
1299
 
         data->timeSyncPeriod = period;
 
1391
         data->timeSyncPeriod = period * 100;
1300
1392
 
1301
1393
         if (data->timeSyncEvent != NULL) {
1302
1394
            Bool status;
1322
1414
         timeSyncStartup = FALSE;
1323
1415
 
1324
1416
         if (syncStartupOk) {
1325
 
            if (!ToolsDaemon_SyncTime(TRUE)) {
 
1417
            if (!ToolsDaemon_SyncTime(TRUE, TRUE, clientData)) {
1326
1418
               RpcIn_SetRetVals(result, resultLen,
1327
1419
                                "Unable to sync time during startup",
1328
1420
                                retVal = FALSE);
1345
1437
                          retVal = FALSE);
1346
1438
         goto exit;
1347
1439
      }
 
1440
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWERON) == 0) {
 
1441
      data->toolScriptOption[GUESTOS_STATECHANGE_POWERON] =
 
1442
                                strcmp(value, "0") ? TRUE : FALSE;
 
1443
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWEROFF) == 0) {
 
1444
      data->toolScriptOption[GUESTOS_STATECHANGE_HALT] =
 
1445
                                strcmp(value, "0") ? TRUE : FALSE;
 
1446
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_SUSPEND) == 0) {
 
1447
      data->toolScriptOption[GUESTOS_STATECHANGE_SUSPEND] =
 
1448
                                strcmp(value, "0") ? TRUE : FALSE;
 
1449
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_RESUME) == 0) {
 
1450
      data->toolScriptOption[GUESTOS_STATECHANGE_RESUME] =
 
1451
                                strcmp(value, "0") ? TRUE : FALSE;
 
1452
   } else if (strcmp(option, TOOLSOPTION_SCRIPTS_REBOOT) == 0) {
 
1453
      data->toolScriptOption[GUESTOS_STATECHANGE_REBOOT] =
 
1454
                                strcmp(value, "0") ? TRUE : FALSE;
1348
1455
   }
1349
1456
 
1350
1457
   /* success! */
1517
1624
                 void *unlinkHgfsCBData)            // IN
1518
1625
{
1519
1626
   ToolsDaemon_Data *data;
 
1627
   int i;
1520
1628
 
1521
1629
#ifndef N_PLAT_NLM
1522
1630
   Atomic_Init();
1546
1654
   data->unlinkHgfsCB = unlinkHgfsCB;
1547
1655
   data->unlinkHgfsCBData = unlinkHgfsCBData;
1548
1656
   data->timeSyncPeriod = 0;
 
1657
   data->slewPercentCorrection = PERCENT_CORRECTION;
 
1658
   data->slewCorrection = TRUE;
 
1659
 
 
1660
   for (i = 0; i < GUESTOS_STATECHANGE_LAST; i++) {
 
1661
      data->toolScriptOption[i] = TRUE;
 
1662
   }
1549
1663
 
1550
1664
#if ALLOW_TOOLS_IN_FOREIGN_VM
1551
1665
   if (!VmCheck_IsVirtualWorld()) {
1555
1669
 
1556
1670
#if defined(VMX86_DEBUG) && !defined(__APPLE__)
1557
1671
   {
1558
 
      int i;
1559
 
 
1560
1672
      /* Make sure the confDict has all the confs we need */
1561
1673
      for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) {
1562
1674
         const char *confName;