本文共 1796 字,大约阅读时间需要 5 分钟。
这个函数主要用于读取kernel时间,如果是superuser的话,则可以写kernel时间。其源码分析如下:SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p){ struct timex txc; /* Local copy of parameter */ int ret; /* Copy the user data space into the kernel copy * structure. But bear in mind that the structures * may change */ #从user space copy txc_p中的内容到txc中 if (copy_from_user(&txc, txc_p, sizeof(struct timex))) return -EFAULT; #根据txc中的内容读写kernel时间 ret = do_adjtimex(&txc); #从kernel space 中的txc中的内容copy到txc_p中 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;}int do_adjtimex(struct timex *txc){#得到timer keeper的时间 struct timekeeper *tk = &tk_core.timekeeper; unsigned long flags; struct timespec64 ts; s32 orig_tai, tai; int ret; /* Validate the data before disabling interrupts */ #检查txc 中的时间是否合法 ret = timekeeping_validate_timex(txc); if (ret) return ret; #ADJ_SETOFFSET 表示增加当前time keeper的时间 if (txc->modes & ADJ_SETOFFSET) { struct timespec64 delta; delta.tv_sec = txc->time.tv_sec; delta.tv_nsec = txc->time.tv_usec; if (!(txc->modes & ADJ_NANO)) delta.tv_nsec *= 1000; ret = timekeeping_inject_offset(&delta); #正常情况下ret等于零。 if (ret) return ret; } #以timespec64格式获取当前时间 getnstimeofday64(&ts); #开始修改time keeper时间 raw_spin_lock_irqsave(&timekeeper_lock, flags); write_seqcount_begin(&tk_core.seq); orig_tai = tai = tk->tai_offset; #根据txc和ts的时间来或者写 kernel 时间,主要给txc赋值,并通过process_adjtime_modes得到tail ret = __do_adjtimex(txc, &ts, &tai); #说明时间已经被更新了,开始update time keeper中的时间 if (tai != orig_tai) { __timekeeping_set_tai_offset(tk, tai); timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); } tk_update_leap_state(tk); write_seqcount_end(&tk_core.seq); raw_spin_unlock_irqrestore(&timekeeper_lock, flags); if (tai != orig_tai) clock_was_set(); #通知ntp时间已经被修改 ntp_notify_cmos_timer(); return ret;}
转载地址:http://bjnmi.baihongyu.com/