mirror of
https://github.com/troglobit/finit.git
synced 2026-11-09 16:21:24 +00:00
Change to runlevel 0/6 on reboot/halt/poweroff
This patch fixes a long-standing issue with how Finit handles shutdown, reboot and poweroff -- and even runlevel changes to runlevel 0 and 6. Prior to this patch sig.c:do_shutdown() was called immediately on any of the above events, disregarding any services that a user might have wanted to run as part of the shutdown/reboot. With this change the handling is unified in all frontends to instead do a runlevel change followed by the do_shutdown() action. Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
2c1e9877f9
commit
f7d6d269c7
6 files changed
+49
-50
No files matched your search
@@ -20,8 +20,6 @@ General
|
|||||||
|
|
||||||
* Add halt/poweroff/shutdown symlinks to finit and convert reboot, but
|
* Add halt/poweroff/shutdown symlinks to finit and convert reboot, but
|
||||||
only install symlinks if these tools don't already exist.
|
only install symlinks if these tools don't already exist.
|
||||||
* Step state machine at shutdown instead of killing, same as shifting to
|
|
||||||
runlevel 0 or 6, then call external (newly installed?) tool to reboot.
|
|
||||||
* Add support for timed shutdown in Finit, including cancelled shutdown.
|
* Add support for timed shutdown in Finit, including cancelled shutdown.
|
||||||
* SysV init and systemd use SIGUSR1 to restart their FIFO/D-Bus. Add
|
* SysV init and systemd use SIGUSR1 to restart their FIFO/D-Bus. Add
|
||||||
API restart to SIGHUP callback for the same functionality in Finit.
|
API restart to SIGHUP callback for the same functionality in Finit.
|
||||||
|
|||||||
@@ -217,9 +217,14 @@ static int do_handle_emit(char *buf, size_t len)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In contrast to the SysV compat handling in plugins/initctl.c, when
|
||||||
|
* `initctl runlevel 0` is issued we default to POWERDOWN the system
|
||||||
|
* instead of just halting.
|
||||||
|
*/
|
||||||
static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
int sd;
|
int sd, lvl;
|
||||||
struct init_request rq;
|
struct init_request rq;
|
||||||
|
|
||||||
sd = accept(w->fd, NULL, NULL);
|
sd = accept(w->fd, NULL, NULL);
|
||||||
@@ -255,26 +260,19 @@ static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
|||||||
switch (rq.cmd) {
|
switch (rq.cmd) {
|
||||||
case INIT_CMD_RUNLVL:
|
case INIT_CMD_RUNLVL:
|
||||||
switch (rq.runlevel) {
|
switch (rq.runlevel) {
|
||||||
case '0':
|
|
||||||
_d("Halting system (SIGUSR2)");
|
|
||||||
do_shutdown(SHUT_OFF);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
_d("Cannot enter bootstrap after boot ...");
|
rq.runlevel = '1'; /* Single user mode */
|
||||||
rq.runlevel = '1';
|
|
||||||
/* Fall through to regular processing */
|
/* Fall through to regular processing */
|
||||||
|
|
||||||
case '1'...'5':
|
case '0'...'9':
|
||||||
case '7'...'9':
|
|
||||||
_d("Setting new runlevel %c", rq.runlevel);
|
_d("Setting new runlevel %c", rq.runlevel);
|
||||||
service_runlevel(rq.runlevel - '0');
|
lvl = rq.runlevel - '0';
|
||||||
break;
|
if (lvl == 0)
|
||||||
|
halt = SHUT_OFF;
|
||||||
case '6':
|
if (lvl == 6)
|
||||||
_d("Rebooting system (SIGUSR1)");
|
halt = SHUT_REBOOT;
|
||||||
do_shutdown(SHUT_REBOOT);
|
service_runlevel(lvl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
+10
-21
@@ -39,13 +39,6 @@
|
|||||||
#include "../sig.h"
|
#include "../sig.h"
|
||||||
#include "../service.h"
|
#include "../service.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Old-style SysV shutdown sends a setenv cmd INIT_HALT with "=HALT",
|
|
||||||
* "=POWERDOWN", or "" to cancel shutdown, before requesting change to
|
|
||||||
* runlevel 6 over the /dev/initctl FIFO.
|
|
||||||
*/
|
|
||||||
shutop_t halt = SHUT_DEFAULT;
|
|
||||||
|
|
||||||
static void parse(void *arg, int fd, int events);
|
static void parse(void *arg, int fd, int events);
|
||||||
static void setup(void *arg);
|
static void setup(void *arg);
|
||||||
|
|
||||||
@@ -99,11 +92,15 @@ static void set_env(char *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Standard reboot/shutdown utilities talk to init using /dev/initctl.
|
* Standard reboot/shutdown utilities talk to init using /run/initctl.
|
||||||
* We should check if the fifo was recreated and reopen it.
|
* We should check if the fifo was recreated and reopen it.
|
||||||
|
*
|
||||||
|
* For SysV compatibility the default is to halt the system when issuing
|
||||||
|
* `init 0`, unless INIT_HALT=POWERDOWN, as performed by the SysV utils.
|
||||||
*/
|
*/
|
||||||
static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
|
static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
|
||||||
{
|
{
|
||||||
|
int lvl;
|
||||||
struct init_request rq;
|
struct init_request rq;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -132,25 +129,17 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
|
|||||||
switch (rq.cmd) {
|
switch (rq.cmd) {
|
||||||
case INIT_CMD_RUNLVL:
|
case INIT_CMD_RUNLVL:
|
||||||
switch (rq.runlevel) {
|
switch (rq.runlevel) {
|
||||||
case '0':
|
|
||||||
_d("Halting system (SIGUSR1 or SIGUSR2)");
|
|
||||||
do_shutdown(halt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
rq.runlevel = '1';
|
rq.runlevel = '1';
|
||||||
/* Fall through to regular processing */
|
/* Fall through to regular processing */
|
||||||
|
|
||||||
case '1'...'5':
|
case '0'...'9':
|
||||||
case '7'...'9':
|
|
||||||
_d("Setting new runlevel %c", rq.runlevel);
|
_d("Setting new runlevel %c", rq.runlevel);
|
||||||
service_runlevel(rq.runlevel - '0');
|
lvl = rq.runlevel - '0';
|
||||||
break;
|
if (lvl == 6)
|
||||||
|
halt = SHUT_REBOOT;
|
||||||
case '6':
|
service_runlevel(lvl);
|
||||||
_d("Rebooting system (SIGTERM)");
|
|
||||||
do_shutdown(SHUT_REBOOT);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -80,6 +80,13 @@
|
|||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "utmp-api.h"
|
#include "utmp-api.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Old-style SysV shutdown sends a setenv cmd INIT_HALT with "=HALT",
|
||||||
|
* "=POWERDOWN", or "" to cancel shutdown, before requesting change to
|
||||||
|
* runlevel 6 over the /dev/initctl FIFO. See plugins/initctl.c
|
||||||
|
*/
|
||||||
|
shutop_t halt = SHUT_DEFAULT;
|
||||||
|
|
||||||
static int stopped = 0;
|
static int stopped = 0;
|
||||||
static uev_t sigterm_watcher, sigusr1_watcher, sigusr2_watcher;
|
static uev_t sigterm_watcher, sigusr1_watcher, sigusr2_watcher;
|
||||||
static uev_t sighup_watcher, sigint_watcher, sigpwr_watcher;
|
static uev_t sighup_watcher, sigint_watcher, sigpwr_watcher;
|
||||||
@@ -184,7 +191,8 @@ static void sighup_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
|||||||
*/
|
*/
|
||||||
static void sigint_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
static void sigint_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
do_shutdown(SHUT_REBOOT);
|
halt = SHUT_REBOOT;
|
||||||
|
service_runlevel(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -192,7 +200,8 @@ static void sigint_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
|||||||
*/
|
*/
|
||||||
static void sigusr1_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
static void sigusr1_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
do_shutdown(SHUT_HALT);
|
halt = SHUT_HALT;
|
||||||
|
service_runlevel(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -200,7 +209,8 @@ static void sigusr1_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
|||||||
*/
|
*/
|
||||||
static void sigusr2_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
static void sigusr2_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
do_shutdown(SHUT_OFF);
|
halt = SHUT_OFF;
|
||||||
|
service_runlevel(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -208,7 +218,8 @@ static void sigusr2_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
|||||||
*/
|
*/
|
||||||
static void sigterm_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
static void sigterm_cb(uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
do_shutdown(SHUT_REBOOT);
|
halt = SHUT_REBOOT;
|
||||||
|
service_runlevel(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ typedef enum {
|
|||||||
SHUT_REBOOT
|
SHUT_REBOOT
|
||||||
} shutop_t;
|
} shutop_t;
|
||||||
|
|
||||||
|
extern shutop_t halt;
|
||||||
|
|
||||||
void do_shutdown (shutop_t op);
|
void do_shutdown (shutop_t op);
|
||||||
int sig_stopped (void);
|
int sig_stopped (void);
|
||||||
void sig_init (void);
|
void sig_init (void);
|
||||||
|
|||||||
@@ -160,13 +160,14 @@ restart:
|
|||||||
/* Cleanup stale services */
|
/* Cleanup stale services */
|
||||||
svc_clean_dynamic(service_unregister);
|
svc_clean_dynamic(service_unregister);
|
||||||
|
|
||||||
if (0 == runlevel) {
|
/*
|
||||||
do_shutdown(SHUT_OFF);
|
* "I've seen things you people wouldn't believe. Attack ships on fire off
|
||||||
sm->state = SM_RUNNING_STATE;
|
* the shoulder of Orion. I watched C-beams glitter in the dark near the
|
||||||
break;
|
* Tannhäuser Gate. All those .. moments .. will be lost in time, like
|
||||||
}
|
* tears ... in ... rain."
|
||||||
if (6 == runlevel) {
|
*/
|
||||||
do_shutdown(SHUT_REBOOT);
|
if (runlevel == 0 || runlevel == 6) {
|
||||||
|
do_shutdown(halt);
|
||||||
sm->state = SM_RUNNING_STATE;
|
sm->state = SM_RUNNING_STATE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user