Fix #295: add reboot/shutdown/poweroff timeout -t SEC to initctl

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2022-08-12 15:06:54 +02:00
1 parent ef1a05425d
commit 6c874895dc
3 files changed
+62 -13

No files matched your search

+39 -4
View File
@@ -45,8 +45,9 @@
#include "log.h" #include "log.h"
#include "plugin.h" #include "plugin.h"
#include "private.h" #include "private.h"
#include "sig.h" #include "schedule.h"
#include "service.h" #include "service.h"
#include "sig.h"
#include "util.h" #include "util.h"
extern svc_t *wdog; extern svc_t *wdog;
@@ -227,10 +228,44 @@ static svc_t *do_find_byc(char *buf, size_t len)
return NULL; return NULL;
} }
static int do_reboot(int cmd, char *buf, size_t len) static void bypass_shutdown(void *);
struct wq emergency = { .cb = bypass_shutdown };
static void bypass_shutdown(void *unused)
{
cprintf("TIMEOUT TIMEOUT SHUTTING DOWN NOW!!\n");
do_shutdown(halt);
}
static int do_reboot(int cmd, int timeout, char *buf, size_t len)
{ {
int rc = 1; int rc = 1;
switch (cmd) {
case INIT_CMD_REBOOT:
halt = SHUT_REBOOT;
break;
case INIT_CMD_HALT:
halt = SHUT_HALT;
break;
case INIT_CMD_POWEROFF:
halt = SHUT_OFF;
break;
case INIT_CMD_SUSPEND:
break;
default:
return 255;
}
if (timeout > 0) {
emergency.delay = timeout * 1000;
schedule_work(&emergency);
}
switch (cmd) { switch (cmd) {
case INIT_CMD_REBOOT: case INIT_CMD_REBOOT:
_d("reboot"); _d("reboot");
@@ -263,7 +298,7 @@ static int do_reboot(int cmd, char *buf, size_t len)
break; break;
default: default:
rc = 255; /* Handled previously */
break; break;
} }
@@ -404,7 +439,7 @@ static void api_cb(uev_t *w, void *arg, int events)
case INIT_CMD_HALT: case INIT_CMD_HALT:
case INIT_CMD_POWEROFF: case INIT_CMD_POWEROFF:
case INIT_CMD_SUSPEND: case INIT_CMD_SUSPEND:
result = do_reboot(rq.cmd, rq.data, sizeof(rq.data)); result = do_reboot(rq.cmd, rq.sleeptime, rq.data, sizeof(rq.data));
break; break;
case INIT_CMD_ACK: case INIT_CMD_ACK:
+4 -2
View File
@@ -64,6 +64,7 @@ int verbose = 0;
int plain = 0; int plain = 0;
int quiet = 0; int quiet = 0;
int runlevel = 0; int runlevel = 0;
int timeout = 0;
int cgrp = 0; int cgrp = 0;
int utmp = 0; int utmp = 0;
@@ -513,8 +514,9 @@ static int do_cond_show(char *arg)
static int do_cmd(int cmd) static int do_cmd(int cmd)
{ {
struct init_request rq = { struct init_request rq = {
.magic = INIT_MAGIC, .magic = INIT_MAGIC,
.cmd = cmd, .cmd = cmd,
.sleeptime = timeout,
}; };
if (client_send(&rq, sizeof(rq))) { if (client_send(&rq, sizeof(rq))) {
+19 -7
View File
@@ -43,6 +43,8 @@ static cmd_t cmd = CMD_UNKNOWN;
static char *msg = NULL; static char *msg = NULL;
/* initctl API */ /* initctl API */
extern int timeout;
extern int do_reboot (char *arg); extern int do_reboot (char *arg);
extern int do_halt (char *arg); extern int do_halt (char *arg);
extern int do_poweroff(char *arg); extern int do_poweroff(char *arg);
@@ -103,12 +105,13 @@ static int usage(int rc)
{ {
fprintf(stderr, "Usage: %s [OPTIONS]\n\n" fprintf(stderr, "Usage: %s [OPTIONS]\n\n"
"Options:\n" "Options:\n"
" -?, --help This help text\n" " -?, --help This help text\n"
" -f, --force Force unsafe %s now, do not contact the init system.\n" " -f, --force Force unsafe %s now, do not contact the init system.\n"
" --halt Halt system, regardless of how the command is called.\n" " --halt Halt system, regardless of how the command is called.\n"
" -h Halt or power off after shutdown.\n" " -h Halt or power off after shutdown.\n"
" -P, --poweroff Power-off system, regardless of how the command is called.\n" " -P, --poweroff Power-off system, regardless of how the command is called.\n"
" -r, --reboot Reboot system, regardless of how the command is called.\n" " -r, --reboot Reboot system, regardless of how the command is called.\n"
" -t, --timeout=SEC Force reboot/shutdown after a given timeout\n"
"\n", prognm, msg); "\n", prognm, msg);
return rc; return rc;
@@ -122,14 +125,16 @@ int reboot_main(int argc, char *argv[])
{"halt", 0, NULL, 'H'}, {"halt", 0, NULL, 'H'},
{"poweroff", 0, NULL, 'p'}, {"poweroff", 0, NULL, 'p'},
{"reboot", 0, NULL, 'r'}, {"reboot", 0, NULL, 'r'},
{"timeout", 1, NULL, 't'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
int c, force = 0; int c, force = 0;
int tmp;
/* Initial command taken from program name */ /* Initial command taken from program name */
transform(prognm); transform(prognm);
while ((c = getopt_long(argc, argv, "h?fHPpr", long_options, NULL)) != EOF) { while ((c = getopt_long(argc, argv, "h?fHPprt:", long_options, NULL)) != EOF) {
switch(c) { switch(c) {
case '?': case '?':
return usage(0); return usage(0);
@@ -152,6 +157,13 @@ int reboot_main(int argc, char *argv[])
cmd = CMD_REBOOT; cmd = CMD_REBOOT;
break; break;
case 't':
tmp = atoi(optarg);
if (tmp < 1)
errx(1, "Invalid forced timeout value.");
timeout = tmp;
break;
default: default:
return usage(1); return usage(1);
} }