~n-muench/ubuntu/oneiric/open-vm-tools/open-vm-tools.fix-836277

« back to all changes in this revision

Viewing changes to services/plugins/timeSync/timeSync.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-07-30 12:56:49 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730125649-97sfj5li8axiseoo
Tags: 2009.07.22-179896-2
* Temporarily building without dumbnet, the recently uploaded
  new dumbnet upstream version broke down (Closes: #539006).
* Using more common name to store local debian additions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#define G_LOG_DOMAIN "timeSync"
26
26
 
27
27
/* sync the time once a minute */
28
 
#define TIME_SYNC_TIME     60000
 
28
#define TIME_SYNC_TIME     60
29
29
/* only PERCENT_CORRECTION percent is corrected everytime */
30
30
#define PERCENT_CORRECTION   50
31
31
 
51
51
   gboolean    slewCorrection;
52
52
   uint32      slewPercentCorrection;
53
53
   gint        timeSyncState;
54
 
   uint32      timeSyncPeriod;         /* In milliseconds. */
 
54
   uint32      timeSyncPeriod;         /* In seconds. */
55
55
   GSource    *timer;
56
56
} TimeSyncData;
57
57
 
61
61
 *
62
62
 * @param[in]  slewCorrection    Is clock slewing enabled?
63
63
 * @param[in]  syncOnce          Is this function called in a loop?
 
64
 * @param[in]  allowBackwardSync Can we sync time backwards when doing syncOnce?
64
65
 * @param[in]  _data             Time sync data.
65
66
 *
66
67
 * @return TRUE on success.
69
70
static gboolean
70
71
TimeSyncDoSync(Bool slewCorrection,
71
72
               Bool syncOnce,
 
73
               Bool allowBackwardSync,
72
74
               void *_data)
73
75
{
74
76
   Backdoor_proto bp;
191
193
       * 1) The guest OS is behind the host OS by more than maxTimeLag + interruptLag.
192
194
       * 2) The guest OS is ahead of the host OS.
193
195
       */
194
 
      if (diff > maxTimeLag + interruptLag) {
 
196
      if (diff > maxTimeLag + interruptLag || (diff < 0 && allowBackwardSync)) {
195
197
         System_DisableTimeSlew();
196
198
         if (!System_AddToCurrentTime(diffSecs, diffUsecs)) {
197
199
            g_warning("Unable to set the guest OS time: %s.\n\n", Msg_ErrString());
221
223
         }
222
224
      } else if (slewCorrection && timeLagCall) {
223
225
         int64 slewDiff;
 
226
         int64 timeSyncPeriodUS = data->timeSyncPeriod * 1000000;
224
227
 
225
228
         /* Don't consider interruptLag during clock slewing. */
226
229
         slewDiff = diff - interruptLag;
228
231
         /* Correct only data->slewPercentCorrection percent error. */
229
232
         slewDiff = (data->slewPercentCorrection * slewDiff) / 100;
230
233
 
231
 
         if (!System_EnableTimeSlew(slewDiff, data->timeSyncPeriod)) {
 
234
         if (!System_EnableTimeSlew(slewDiff, timeSyncPeriodUS)) {
232
235
            g_warning("Unable to slew the guest OS time: %s.\n\n", Msg_ErrString());
233
236
            return FALSE;
234
237
         }
270
273
{
271
274
   TimeSyncData *data = _data;
272
275
 
273
 
   g_assert(data != NULL);
 
276
   ASSERT(data != NULL);
274
277
 
275
 
   if (!TimeSyncDoSync(data->slewCorrection, FALSE, data)) {
 
278
   if (!TimeSyncDoSync(data->slewCorrection, FALSE, FALSE, data)) {
276
279
      g_warning("Unable to synchronize time.\n");
277
280
      if (data->timer != NULL) {
278
281
         g_source_unref(data->timer);
373
376
                      TimeSyncData *data,
374
377
                      gboolean start)
375
378
{
376
 
   g_assert(data != NULL);
 
379
   ASSERT(data != NULL);
377
380
 
378
381
   if (start && data->timer == NULL) {
379
382
      g_debug("Starting time sync loop.\n");
380
 
      g_debug("New sync period is %d sec.\n", data->timeSyncPeriod / 1000);
 
383
      g_debug("New sync period is %d sec.\n", data->timeSyncPeriod);
381
384
      if (!ToolsDaemonTimeSyncLoop(data)) {
382
385
         return FALSE;
383
386
      }
384
 
      data->timer = g_timeout_source_new(data->timeSyncPeriod);
 
387
      data->timer = g_timeout_source_new(data->timeSyncPeriod * 1000);
385
388
      VMTOOLSAPP_ATTACH_SOURCE(ctx, data->timer, ToolsDaemonTimeSyncLoop, data, NULL);
386
389
 
387
390
#if defined(_WIN32)
420
423
static Bool
421
424
TimeSyncTcloHandler(RpcInData *data)
422
425
{
423
 
   Bool slewCorrection = !strcmp(data->args, "1");
 
426
   Bool backwardSync = !strcmp(data->args, "1");
424
427
   TimeSyncData *syncData = data->clientData;
425
428
 
426
 
   if (!TimeSyncDoSync(slewCorrection, TRUE, syncData)) {
 
429
   if (!TimeSyncDoSync(syncData->slewCorrection, TRUE, backwardSync, syncData)) {
427
430
      return RPCIN_SETRETVALS(data, "Unable to sync time", FALSE);
428
431
   } else {
429
432
      return RPCIN_SETRETVALS(data, "", TRUE);
432
435
 
433
436
 
434
437
/**
 
438
 * Parses boolean option string.
 
439
 *
 
440
 * @param[in]  string     Option string to be parsed.
 
441
 * @param[out] gboolean   Value of the option.
 
442
 *
 
443
 * @return TRUE on success.
 
444
 */
 
445
 
 
446
static gboolean
 
447
ParseBoolOption(const gchar *string,
 
448
                gboolean *value)
 
449
{
 
450
      if (strcmp(string, "1") == 0) {
 
451
         *value = TRUE;
 
452
      } else if (strcmp(string, "0") == 0) {
 
453
         *value = FALSE;
 
454
      } else {
 
455
         return FALSE;
 
456
      }
 
457
      return TRUE;
 
458
}
 
459
 
 
460
/**
435
461
 * Handles a "Set_Option" callback. Processes the time sync related options.
436
462
 *
437
463
 * @param[in]  src      The source object.
451
477
                  ToolsPluginData *plugin)
452
478
{
453
479
   TimeSyncData *data = plugin->_private;
 
480
 
454
481
   if (strcmp(option, TOOLSOPTION_SYNCTIME) == 0) {
455
482
      gboolean start;
456
483
 
457
 
      if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
 
484
      if (!ParseBoolOption(value, &start)) {
458
485
         return FALSE;
459
486
      }
460
 
      start = (strcmp(value, "1") == 0);
461
487
 
462
488
      /*
463
489
       * Try the one-shot time sync if time sync transitions from
464
490
       * 'off' to 'on'.
 
491
       * Note that if TOOLSOPTION_SYNCTIME_ENABLE is absent from
 
492
       * vmx config file it is considered to be TRUE.
465
493
       */
466
494
      if (data->timeSyncState == 0 && start &&
467
 
          g_key_file_get_boolean(ctx->config, "timeSync",
 
495
          g_key_file_get_boolean(ctx->config, "vmsvc",
468
496
                                 TOOLSOPTION_SYNCTIME_ENABLE, NULL)) {
469
 
         TimeSyncDoSync(data->slewCorrection, TRUE, data);
 
497
         TimeSyncDoSync(data->slewCorrection, TRUE, TRUE, data);
470
498
      }
471
499
      data->timeSyncState = start;
472
500
 
479
507
      g_debug("Daemon: Setting slewCorrection, %d.\n", data->slewCorrection);
480
508
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERCENTCORRECTION) == 0) {
481
509
      int32 percent;
 
510
      g_debug("Daemon: Setting slewPercentCorrection to %s.\n", value);
482
511
      if (!StrUtil_StrToInt(&percent, value)) {
483
512
         return FALSE;
484
513
      }
485
 
      data->slewPercentCorrection = percent;
 
514
      if (percent <= 0 || percent > 100) {
 
515
         data->slewPercentCorrection = PERCENT_CORRECTION;
 
516
      } else {
 
517
         data->slewPercentCorrection = percent;
 
518
      }
486
519
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERIOD) == 0) {
487
520
      uint32 period;
488
521
 
496
529
       * not running, just remember the new sync period value.
497
530
       */
498
531
      if (period != data->timeSyncPeriod) {
499
 
         data->timeSyncPeriod = (period > 0) ? period * 1000 : TIME_SYNC_TIME;
 
532
         data->timeSyncPeriod = (period > 0) ? period : TIME_SYNC_TIME;
500
533
 
501
534
         if (data->timer != NULL) {
502
535
            TimeSyncStartStopLoop(ctx, data, FALSE);
506
539
            }
507
540
         }
508
541
      }
 
542
   } else if (strcmp(option, TOOLSOPTION_SYNCTIME_STARTUP) == 0) {
 
543
      static gboolean doneAlready = FALSE;
 
544
      gboolean doSync;
 
545
 
 
546
      if (!ParseBoolOption(value, &doSync)) {
 
547
         return FALSE;
 
548
      }
 
549
 
 
550
      if (doSync && !doneAlready &&
 
551
            !TimeSyncDoSync(data->slewCorrection, TRUE, TRUE, data)) {
 
552
         g_warning("Unable to sync time during startup.\n");
 
553
         return FALSE;
 
554
      }
 
555
 
 
556
      doneAlready = TRUE;
 
557
 
509
558
   } else {
510
559
      return FALSE;
511
560
   }
565
614
      { TOOLS_APP_SIGNALS, VMTools_WrapArray(sigs, sizeof *sigs, ARRAYSIZE(sigs)) }
566
615
   };
567
616
 
568
 
   data->slewCorrection = TRUE;
 
617
   data->slewCorrection = FALSE;
569
618
   data->slewPercentCorrection = PERCENT_CORRECTION;
570
619
   data->timeSyncState = -1;
571
620
   data->timeSyncPeriod = TIME_SYNC_TIME;