diff --git a/candm.h b/candm.h index 6798a9d..2ff3853 100644 --- a/candm.h +++ b/candm.h @@ -99,7 +99,8 @@ #define REQ_ADD_PEER2 59 #define REQ_ADD_SERVER3 60 #define REQ_ADD_PEER3 61 -#define N_REQUEST_TYPES 62 +#define REQ_SHUTDOWN 62 +#define N_REQUEST_TYPES 63 /* Structure used to exchange timespecs independent of time_t size */ typedef struct { diff --git a/client.c b/client.c index 7c403aa..a38077b 100644 --- a/client.c +++ b/client.c @@ -1246,6 +1246,7 @@ give_help(void) "cyclelogs\0Close and re-open log files\0" "dump\0Dump all measurements to save files\0" "rekey\0Re-read keys from key file\0" + "shutdown\0Stop daemon\0" "\0\0" "Client commands:\0\0" "dns -n|+n\0Disable/enable resolving IP addresses to hostnames\0" @@ -1280,9 +1281,9 @@ command_name_generator(const char *text, int state) "maxdelay", "maxdelaydevratio", "maxdelayratio", "maxpoll", "maxupdateskew", "minpoll", "minstratum", "ntpdata", "offline", "online", "polltarget", "quit", "refresh", "rekey", "reselect", "reselectdist", - "retries", "rtcdata", "serverstats", "settime", "smoothing", "smoothtime", - "sources", "sources -v", "sourcestats", "sourcestats -v", "timeout", - "tracking", "trimrtc", "waitsync", "writertc", + "retries", "rtcdata", "serverstats", "settime", "shutdown", "smoothing", + "smoothtime", "sources", "sources -v", "sourcestats", "sourcestats -v", + "timeout", "tracking", "trimrtc", "waitsync", "writertc", NULL }; static int list_index, len; @@ -2707,6 +2708,14 @@ process_cmd_refresh(CMD_Request *msg, char *line) /* ================================================== */ +static void +process_cmd_shutdown(CMD_Request *msg, char *line) +{ + msg->command = htons(REQ_SHUTDOWN); +} + +/* ================================================== */ + static int process_cmd_waitsync(char *line) { @@ -3002,6 +3011,8 @@ process_line(char *line) } else if (!strcmp(command, "settime")) { do_normal_submit = 0; ret = process_cmd_settime(line); + } else if (!strcmp(command, "shutdown")) { + process_cmd_shutdown(&tx_message, line); } else if (!strcmp(command, "smoothing")) { do_normal_submit = 0; ret = process_cmd_smoothing(line); diff --git a/cmdmon.c b/cmdmon.c index 9d1eb95..85f77de 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -138,6 +138,7 @@ static const char permissions[] = { PERMIT_AUTH, /* ADD_PEER2 */ PERMIT_AUTH, /* ADD_SERVER3 */ PERMIT_AUTH, /* ADD_PEER3 */ + PERMIT_AUTH, /* SHUTDOWN */ }; /* ================================================== */ @@ -1239,6 +1240,15 @@ handle_ntp_data(CMD_Request *rx_message, CMD_Reply *tx_message) memset(tx_message->data.ntp_data.reserved, 0xff, sizeof (tx_message->data.ntp_data.reserved)); } +/* ================================================== */ + +static void +handle_shutdown(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + LOG(LOGS_INFO, "Received shutdown command"); + SCH_QuitProgram(); +} + /* ================================================== */ /* Read a packet and process it */ @@ -1630,6 +1640,10 @@ read_from_cmd_socket(int sock_fd, int event, void *anything) handle_ntp_data(&rx_message, &tx_message); break; + case REQ_SHUTDOWN: + handle_shutdown(&rx_message, &tx_message); + break; + default: DEBUG_LOG("Unhandled command %d", rx_command); tx_message.status = htons(STT_FAILED); diff --git a/doc/chronyc.adoc b/doc/chronyc.adoc index 9c5ac5c..c987907 100644 --- a/doc/chronyc.adoc +++ b/doc/chronyc.adoc @@ -1128,6 +1128,10 @@ running. The *rekey* command causes *chronyd* to re-read the key file specified in the configuration file by the <> directive. +[[rekey]]*shutdown*:: +The *shutdown* command causes *chronyd* to exit. This is equivalent to sending +the process the SIGTERM signal. + === Client commands [[dns]]*dns* _option_:: diff --git a/pktlength.c b/pktlength.c index d93d139..112ee26 100644 --- a/pktlength.c +++ b/pktlength.c @@ -118,6 +118,7 @@ static const struct request_length request_lengths[] = { { 0, 0 }, /* ADD_PEER2 */ REQ_LENGTH_ENTRY(ntp_source, null), /* ADD_SERVER3 */ REQ_LENGTH_ENTRY(ntp_source, null), /* ADD_PEER3 */ + REQ_LENGTH_ENTRY(null, null), /* SHUTDOWN */ }; static const uint16_t reply_lengths[] = {