0

I used strace on ntpdate command which calls adjtimex to adjust time. I got this:

adjtimex({modes=ADJ_OFFSET|0x8000, offset=-479139, freq=0, maxerror=16000000, esterror=16000000, status=STA_UNSYNC, constant=2, precision=1, tolerance=32768000, time={1352220968, 428418}, tick=10000, ppsfreq=0, jitter=0, shift=0, stabil=0, jitcnt=0, calcnt=0, errcnt=0, stbcnt=0}) = 5 (TIME_ERROR)

Then I looked into implementation of adjtimex API in do_adjtimex main funcition. But from the code I can not see how ntpdate adjusts the time.

modes=ADJ_OFFSET|0x8000=ADJ_OFFSET|ADJ_ADJTIME

int do_adjtimex(struct timex *txc)
{
    struct timespec ts;
    int result;
/* Validate the data before disabling interrupts */
if (txc->modes & ADJ_ADJTIME) { **<----this is true. modes as ADJ_OFFSET|ADJ_ADJTIME**
    /* singleshot must not be used with any other mode bits */
    if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
        return -EINVAL;
    if (!(txc->modes & ADJ_OFFSET_READONLY) &&
        !capable(CAP_SYS_TIME))
        return -EPERM;
} else {
    .....
}

if (txc->modes & ADJ_SETOFFSET) { **《===this is false**
    .....
}

getnstimeofday(&ts);**《------------just get the walk time**

spin_lock_irq(&ntp_lock);

if (txc->modes & ADJ_ADJTIME) {<----this is true.
    long save_adjust = time_adjust; **<----this is global valu eoffset=-479139**

    if (!(txc->modes & ADJ_OFFSET_READONLY)) {
        /* adjtime() is independent from ntp_adjtime() */
        time_adjust = txc->offset;
        ntp_update_frequency();
    }
    txc->offset = save_adjust;
} else {

    .......
}

result = time_state;    /* mostly `TIME_OK' */ this is 
/* check for errors */
if (is_error_status(time_status)) **<----this is STA_UNSYNC**
    result = TIME_ERROR;

txc->freq      = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) *
                 PPM_SCALE_INV, NTP_SCALE_SHIFT);
txc->maxerror      = time_maxerror;
txc->esterror      = time_esterror;
txc->status    = time_status;
txc->constant      = time_constant;
txc->precision     = 1;
txc->tolerance     = MAXFREQ_SCALED / PPM_SCALE;
txc->tick      = tick_usec;
txc->tai       = time_tai;

/* fill PPS status fields */
pps_fill_timex(txc);

spin_unlock_irq(&ntp_lock);

txc->time.tv_sec = ts.tv_sec;
txc->time.tv_usec = ts.tv_nsec;
if (!(time_status & STA_NANO))
    txc->time.tv_usec /= NSEC_PER_USEC;

notify_cmos_timer(); <---- call sync_cmos_clock.

return result;
}

sync_cmos_clock checks whether ntp is synced. time_status is STA_UNSYNC. Just do nothing and return.

if (!ntp_synced()) { /*
                      * Not synced, exit, do not restart a timer (if one is
                      * running, let it run out). */
return; }

Am I missing something?

4

1 回答 1

0

ntp.c已从 fromkernel/timer.ckernel/time.c

在里面ntp.c你会找到对 的调用ntp_update_frequency()

if (!(txc->modes & ADJ_OFFSET_READONLY)) {
   /* adjtime() is independent from ntp_adjtime() */
   time_adjust = txc->offset;
   ntp_update_frequency();
}
txc->offset = save_adjust;

ntp_update_frequency()更新u64 tick_lengthstatic tick_length_baseadjtime注意和的独立性ntp_adjtime

于 2012-11-07T10:30:18.687 回答