2012-11-06 104 views
0

我在ntpdate命令中使用了strace命令,它調用adjtimex來調整時間。 我得到這個:ntpdate如何更新時間?

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) 

然後我看着落實adjtimex API的do_adjtimex主要funcition。 但是從代碼我看不到ntpdate如何調整時間。

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檢查ntp是否同步。 time_status是STA_UNSYNC。 什麼也不做,並返回。

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

我錯過了什麼嗎?

回答

0

ntp.c已經從kernel/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_base。 請注意adjtimentp_adjtime的獨立性。

+0

txc的模式未設置爲0x2000的ADJ_OFFSET_READONLY。模式= ADJ_OFFSET |爲0x8000 = ADJ_OFFSET | ADJ_ADJTIME。 – DaVid