mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 13:33:09 +07:00
Fix #147: refactor reboot as multi-call to initctl
This patch drops the stand-alone reboot binary and folds it into the initctl tool, which now becomes a multi-call binary. With this change the reboot/shutdown/poweroff/halt/suspend commands also no longer default to sending signals to PID 1, instead it now uses the initctl <--> finit UNIX domain socket API. Signals are only used as a fallback in case of non-working domain socket. The -f,--force mode of operation still works, where `reboot(2)` is called directly. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -12,6 +12,11 @@ to service conditions. There are other significant changes as well, so
|
||||
make sure to read the whole changelog when upgrading.
|
||||
|
||||
### Changes
|
||||
* The stand-alone `reboot` tool has been replaced with a symlink to
|
||||
`initctl`, like its siblings: halt, shutdown, poweroff, and suspend.
|
||||
Calling `reboot` & C:o now defaults to the corresponding `initctl cmd`
|
||||
with a fallback to sending signals as per traditional SysV init. The
|
||||
`-f` (force) flag remains, where `reboot(2)` is called directly
|
||||
* Introducing Finit progress 𝓜𝓸𝓭𝓮𝓻𝓷
|
||||
* Removed built-in inetd super server. If you need this functionality,
|
||||
use an external inetd, like xinetd, instead. A pull request for a
|
||||
|
||||
+34
-46
@@ -8,7 +8,7 @@ else
|
||||
AM_LDFLAGS = -export-dynamic
|
||||
endif
|
||||
|
||||
sbin_PROGRAMS = finit initctl reboot
|
||||
sbin_PROGRAMS = finit initctl
|
||||
pkglibexec_SCRIPTS = cgreaper.sh
|
||||
if WATCHDOGD
|
||||
pkglibexec_PROGRAMS = watchdogd
|
||||
@@ -49,19 +49,15 @@ else
|
||||
finit_LDADD += -ldl
|
||||
endif
|
||||
|
||||
initctl_SOURCES = initctl.c client.c client.h \
|
||||
serv.c serv.h svc.h \
|
||||
initctl_SOURCES = initctl.c client.c client.h \
|
||||
reboot.c serv.c serv.h svc.h \
|
||||
cond.c cond.h util.c util.h
|
||||
initctl_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
|
||||
initctl_CFLAGS += $(lite_CFLAGS)
|
||||
initctl_LDADD = $(lite_LIBS)
|
||||
|
||||
reboot_SOURCES = reboot.c util.c util.h
|
||||
reboot_CFLAGS = $(lite_CFLAGS)
|
||||
reboot_LDADD = $(lite_LIBS)
|
||||
|
||||
INIT_LNKS = init
|
||||
REBOOT_LNKS = shutdown halt poweroff suspend
|
||||
REBOOT_LNKS = reboot shutdown halt poweroff suspend
|
||||
|
||||
if WATCHDOGD
|
||||
watchdogd_SOURCES = watchdog.c watchdog.h
|
||||
@@ -72,46 +68,38 @@ endif
|
||||
# Hook in install to add finit and reboot symlink(s)
|
||||
install-exec-hook:
|
||||
@$(INSTALL_DATA) $(srcdir)/rescue.conf $(DESTDIR)$(pkglibdir)
|
||||
@for file in $(INIT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
if [ -e $$lnk ]; then \
|
||||
echo "Skipping $$lnk exists."; \
|
||||
else \
|
||||
$(LN_S) finit $$lnk; \
|
||||
fi; \
|
||||
@for file in $(INIT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
if [ -e $$lnk ]; then \
|
||||
echo "Skipping $$lnk exists."; \
|
||||
else \
|
||||
$(LN_S) finit $$lnk; \
|
||||
fi; \
|
||||
done
|
||||
@for file in $(REBOOT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
if [ -e $$lnk ]; then \
|
||||
echo "Skipping $$lnk exists."; \
|
||||
else \
|
||||
$(LN_S) initctl $$lnk; \
|
||||
fi; \
|
||||
done
|
||||
@if [ -L $(DESTDIR)$(sbindir)/reboot ]; then \
|
||||
echo "Non-finit reboot, skipping install."; \
|
||||
else \
|
||||
for file in $(REBOOT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
if [ -e $$lnk ]; then \
|
||||
echo "Skipping $$lnk exists."; \
|
||||
else \
|
||||
$(LN_S) reboot $$lnk; \
|
||||
fi; \
|
||||
done; \
|
||||
fi
|
||||
|
||||
uninstall-hook:
|
||||
@$(RM) $(DESTDIR)$(pkglibdir)/rescue.conf
|
||||
@for file in $(INIT_LNKS); do \
|
||||
lnk=`readlink $(DESTDIR)$(sbindir)/$$file`; \
|
||||
if [ "$$lnk" != "finit" ]; then \
|
||||
echo "Skipping non-finit $$file."; \
|
||||
continue; \
|
||||
fi; \
|
||||
$(RM) $(DESTDIR)$(sbindir)/$$file; \
|
||||
@for file in $(INIT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
dst=`readlink $$lnk`; \
|
||||
if [ "$$dst" != "finit" ]; then \
|
||||
continue; \
|
||||
fi; \
|
||||
$(RM) $(DESTDIR)$(sbindir)/$$file; \
|
||||
done
|
||||
@for file in $(REBOOT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
dst=`readlink $$lnk`; \
|
||||
if [ "$$dst" != "initctl" ]; then \
|
||||
continue; \
|
||||
fi; \
|
||||
$(RM) $$lnk; \
|
||||
done
|
||||
@if [ -L $(DESTDIR)$(sbindir)/reboot ]; then \
|
||||
echo "Non-finit reboot, skipping uninstall."; \
|
||||
else \
|
||||
for file in $(REBOOT_LNKS); do \
|
||||
lnk=$(DESTDIR)$(sbindir)/$$file; \
|
||||
dst=`readlink $$lnk`; \
|
||||
if [ "$$dst" != "reboot" ]; then \
|
||||
continue; \
|
||||
fi; \
|
||||
$(RM) $$lnk; \
|
||||
done; \
|
||||
fi
|
||||
|
||||
+44
-8
@@ -54,6 +54,9 @@ int verbose = 0;
|
||||
int runlevel = 0;
|
||||
int iw, pw;
|
||||
|
||||
extern int reboot_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
/* figure ut width of IDENT and PID columns */
|
||||
static void col_widths(void)
|
||||
{
|
||||
@@ -349,17 +352,30 @@ static int do_cond(char *cmd)
|
||||
return do_cond_show(NULL);
|
||||
}
|
||||
|
||||
static int do_signal(int signo, const char *msg)
|
||||
static int do_cmd(int cmd)
|
||||
{
|
||||
if (kill(1, signo))
|
||||
err(1, "Failed signalling init to %s", msg);
|
||||
struct init_request rq = {
|
||||
.magic = INIT_MAGIC,
|
||||
.cmd = cmd,
|
||||
};
|
||||
|
||||
if (client_send(&rq, sizeof(rq))) {
|
||||
if (rq.cmd == INIT_CMD_NACK)
|
||||
puts(rq.data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Wait here for systemd to shutdown/reboot */
|
||||
sleep(5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_halt (char *arg) { return do_signal(SIGUSR1, "halt"); }
|
||||
static int do_poweroff(char *arg) { return do_signal(SIGUSR2, "power off"); }
|
||||
static int do_reboot (char *arg) { return do_signal(SIGTERM, "reboot"); }
|
||||
int do_reboot (char *arg) { return do_cmd(INIT_CMD_REBOOT); }
|
||||
int do_halt (char *arg) { return do_cmd(INIT_CMD_HALT); }
|
||||
int do_poweroff(char *arg) { return do_cmd(INIT_CMD_POWEROFF); }
|
||||
int do_suspend (char *arg) { return do_cmd(INIT_CMD_SUSPEND); }
|
||||
|
||||
int utmp_show(char *file)
|
||||
{
|
||||
@@ -605,6 +621,22 @@ static int show_cgroup(char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int transform(char *nm)
|
||||
{
|
||||
char *names[] = {
|
||||
"reboot", "shutdown", "poweroff", "halt", "suspend",
|
||||
NULL
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; names[i]; i++) {
|
||||
if (!strcmp(nm, names[i]))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usage(int rc)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@@ -644,7 +676,8 @@ static int usage(int rc)
|
||||
" runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot\n"
|
||||
" reboot Reboot system\n"
|
||||
" halt Halt system\n"
|
||||
" poweroff Halt and power off system\n", prognm);
|
||||
" poweroff Halt and power off system\n"
|
||||
" suspend Suspend system\n", prognm);
|
||||
|
||||
if (has_utmp())
|
||||
fprintf(stderr,
|
||||
@@ -693,6 +726,7 @@ int main(int argc, char *argv[])
|
||||
{ "reboot", do_reboot },
|
||||
{ "halt", do_halt },
|
||||
{ "poweroff", do_poweroff },
|
||||
{ "suspend", do_suspend },
|
||||
|
||||
{ "utmp", do_utmp },
|
||||
{ NULL, NULL }
|
||||
@@ -706,7 +740,9 @@ int main(int argc, char *argv[])
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
progname(argv[0]);
|
||||
if (transform(progname(argv[0])))
|
||||
return reboot_main(argc, argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "bh?ntv", long_options, NULL)) != EOF) {
|
||||
switch(c) {
|
||||
case 'b':
|
||||
|
||||
+34
-12
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@@ -40,6 +41,13 @@ typedef enum {
|
||||
static cmd_t cmd = CMD_UNKNOWN;
|
||||
static char *msg = NULL;
|
||||
|
||||
/* initctl API */
|
||||
extern int do_reboot (char *arg);
|
||||
extern int do_halt (char *arg);
|
||||
extern int do_poweroff(char *arg);
|
||||
extern int do_suspend (char *arg);
|
||||
|
||||
|
||||
static void transform(char *nm)
|
||||
{
|
||||
if (!nm)
|
||||
@@ -80,6 +88,16 @@ static void transform(char *nm)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fallback in case of initctl API failure
|
||||
*/
|
||||
static void do_kill(int signo, char *msg)
|
||||
{
|
||||
if (kill(1, signo))
|
||||
err(1, "Failed signalling init to %s", msg);
|
||||
do_sleep(5);
|
||||
}
|
||||
|
||||
static void sig(int signo)
|
||||
{
|
||||
(void)signo; /* NOP */
|
||||
@@ -100,7 +118,7 @@ static int usage(int rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int reboot_main(int argc, char *argv[])
|
||||
{
|
||||
int c, force = 0;
|
||||
struct option long_options[] = {
|
||||
@@ -113,7 +131,7 @@ int main(int argc, char *argv[])
|
||||
};
|
||||
|
||||
/* Initial command taken from program name */
|
||||
transform(progname(argv[0]));
|
||||
transform(prognm);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h?fHPpr", long_options, NULL)) != EOF) {
|
||||
switch(c) {
|
||||
@@ -165,6 +183,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
case CMD_SUSPEND:
|
||||
c = reboot(RB_SW_SUSPEND);
|
||||
if (c && errno == EINVAL)
|
||||
errx(1, "Kernel does not support suspend.");
|
||||
break;
|
||||
|
||||
case CMD_UNKNOWN:
|
||||
@@ -173,22 +193,25 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (c)
|
||||
warn("Failed forced %s", msg);
|
||||
else
|
||||
return 0;
|
||||
err(1, "Failed forced %s", msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_REBOOT:
|
||||
c = kill(1, SIGTERM);
|
||||
if (do_reboot(NULL))
|
||||
do_kill(SIGTERM, msg);
|
||||
break;
|
||||
|
||||
case CMD_HALT:
|
||||
c = kill(1, SIGUSR1);
|
||||
if (do_halt(NULL))
|
||||
do_kill(SIGUSR1, msg);
|
||||
break;
|
||||
|
||||
case CMD_POWEROFF:
|
||||
c = kill(1, SIGUSR2);
|
||||
if (do_poweroff(NULL))
|
||||
do_kill(SIGUSR2, msg);
|
||||
break;
|
||||
|
||||
case CMD_SUSPEND:
|
||||
@@ -196,16 +219,15 @@ int main(int argc, char *argv[])
|
||||
* Only initctl supports suspend, we avoid adding
|
||||
* another signal to finit for compat reasons.
|
||||
*/
|
||||
do_suspend(NULL);
|
||||
break;
|
||||
|
||||
|
||||
case CMD_UNKNOWN:
|
||||
errx(1, "Invalid command");
|
||||
break;
|
||||
}
|
||||
|
||||
if (c)
|
||||
err(1, "Failed signalling init to %s", msg);
|
||||
do_sleep(5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user