ntpd: add -S PROG option. This feature is crucial for CMOS/RTC syncronization

function                                             old     new   delta
run_script                                           112     278    +166
ntpd_main                                            779     825     +46
update_local_clock                                   824     858     +34
packed_usage                                       26518   26540     +22
ntp_init                                             366     371      +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/0 up/down: 273/0)             Total: 273 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-01-06 12:27:47 +01:00
parent 79ae534ac7
commit ede737b7cf
2 changed files with 57 additions and 7 deletions

View File

@ -3226,7 +3226,7 @@
"Address: 127.0.0.1\n"
#define ntpd_trivial_usage \
"[-dnqwl] [-p PEER]..."
"[-dnqwl] [-S PROG] [-p PEER]..."
#define ntpd_full_usage "\n\n" \
"NTP client/server\n" \
"\nOptions:" \
@ -3238,6 +3238,7 @@
/* "\n -N Run at high priority" */ \
"\n -w Do not set time (only query peers), implies -n" \
"\n -l Run as server on port 123" \
"\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" \
"\n -p PEER Obtain time from PEER (may be repeated)" \
#define od_trivial_usage \

View File

@ -194,7 +194,8 @@ enum {
/* Non-compat options: */
OPT_w = (1 << 4),
OPT_p = (1 << 5),
OPT_l = (1 << 6) * ENABLE_FEATURE_NTPD_SERVER,
OPT_S = (1 << 6),
OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER,
};
struct globals {
@ -205,6 +206,9 @@ struct globals {
double reftime;
/* total dispersion to currently selected reference clock */
double rootdisp;
double last_script_run;
char *script_name;
llist_t *ntp_peers;
#if ENABLE_FEATURE_NTPD_SERVER
int listen_fd;
@ -682,6 +686,38 @@ send_query_to_peer(peer_t *p)
}
static void run_script(const char *action)
{
char *argv[3];
char *env1, *env2;
if (!G.script_name)
return;
argv[0] = (char*) G.script_name;
argv[1] = (char*) action;
argv[2] = NULL;
VERB1 bb_error_msg("executing '%s %s'", G.script_name, action);
env1 = xasprintf("stratum=%u", G.stratum);
putenv(env1);
env2 = xasprintf("freq_drift_ppm=%ld", G.kernel_freq_drift);
putenv(env2);
/* Other items of potential interest: selected peer,
* rootdelay, reftime, rootdisp, refid, ntp_status, poll_exp,
* last_update_offset, last_update_recv_time, discipline_jitter
*/
wait4pid(spawn(argv));
G.last_script_run = G.cur_time;
unsetenv("stratum");
unsetenv("freq_drift_ppm");
free(env1);
free(env2);
}
static NOINLINE void
step_time(double offset)
{
@ -1140,6 +1176,9 @@ update_local_clock(peer_t *p)
G.polladj_count = 0;
G.poll_exp = MINPOLL;
G.stratum = MAXSTRAT;
run_script("step");
if (G.discipline_state == STATE_NSET) {
set_new_values(STATE_FREQ, /*offset:*/ 0, recv_time);
return 1; /* "ok to increase poll interval" */
@ -1225,7 +1264,10 @@ update_local_clock(peer_t *p)
set_new_values(STATE_SYNC, offset, recv_time);
break;
}
G.stratum = p->lastpkt_stratum + 1;
if (G.stratum != p->lastpkt_stratum + 1) {
G.stratum = p->lastpkt_stratum + 1;
run_script("stratum");
}
}
G.reftime = G.cur_time;
@ -1729,17 +1771,17 @@ static NOINLINE void ntp_init(char **argv)
G.stratum = MAXSTRAT;
if (BURSTPOLL != 0)
G.poll_exp = BURSTPOLL; /* speeds up initial sync */
G.reftime = G.last_update_recv_time = gettime1900d(); /* sets G.cur_time too */
G.last_script_run = G.reftime = G.last_update_recv_time = gettime1900d(); /* sets G.cur_time too */
/* Parse options */
peers = NULL;
opt_complementary = "dd:p::wn"; /* d: counter; p: list; -w implies -n */
opts = getopt32(argv,
"nqNx" /* compat */
"wp:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
"wp:S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
"d" /* compat */
"46aAbgL", /* compat, ignored */
&peers, &G.verbose);
&peers, &G.script_name, &G.verbose);
if (!(opts & (OPT_p|OPT_l)))
bb_show_usage();
// if (opts & OPT_x) /* disable stepping, only slew is allowed */
@ -1854,8 +1896,15 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
VERB2 bb_error_msg("poll %us, sockets:%u", timeout, i);
nfds = poll(pfd, i, timeout * 1000);
gettime1900d(); /* sets G.cur_time */
if (nfds <= 0)
if (nfds <= 0) {
if (G.adjtimex_was_done
&& G.cur_time - G.last_script_run > 11*60
) {
/* Useful for updating battery-backed RTC and such */
run_script("periodic");
}
continue;
}
/* Process any received packets */
j = 0;