aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-03-25 13:10:13 +0200
committerDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-03-25 13:28:07 +0200
commit021f091082a74d5bd5503a3a3c7a569eee9c6d8f (patch)
tree5a1c742a3e4a1933ed3a54f39a7069f97e2500f1
parent0a280740716bde571c0f0db64d78a7f2141b56f4 (diff)
Use services to implement shutdown/reboot sequence
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
-rw-r--r--.gitignore5
-rw-r--r--configure.ac5
-rw-r--r--initd/Makemodule.am2
-rw-r--r--initd/init.h10
-rw-r--r--initd/main.c16
-rw-r--r--initd/shutdown.c54
-rw-r--r--services/Makemodule.am2
-rw-r--r--services/reboot.in8
-rw-r--r--services/shutdown.in8
-rw-r--r--services/sigkill.in9
-rw-r--r--services/sigterm.in10
-rw-r--r--services/sync.in9
12 files changed, 61 insertions, 77 deletions
diff --git a/.gitignore b/.gitignore
index 2f392f9..7ee6330 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,8 @@ services/hostname
services/loopback
services/sysctl
services/hwclock
+services/shutdown
+services/reboot
+services/sigkill
+services/sigterm
+services/sync
diff --git a/configure.ac b/configure.ac
index d22cec3..d72097a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,5 +23,10 @@ AC_CONFIG_FILES([services/hostname])
AC_CONFIG_FILES([services/loopback])
AC_CONFIG_FILES([services/sysctl])
AC_CONFIG_FILES([services/hwclock])
+AC_CONFIG_FILES([services/reboot])
+AC_CONFIG_FILES([services/shutdown])
+AC_CONFIG_FILES([services/sigkill])
+AC_CONFIG_FILES([services/sigterm])
+AC_CONFIG_FILES([services/sync])
AC_OUTPUT([Makefile])
diff --git a/initd/Makemodule.am b/initd/Makemodule.am
index 423c8eb..f6fa1da 100644
--- a/initd/Makemodule.am
+++ b/initd/Makemodule.am
@@ -1,5 +1,5 @@
init_SOURCES = initd/main.c initd/runlst.c initd/init.h initd/setup_tty.c
-init_SOURCES += initd/status.c initd/mksock.c initd/shutdown.c initd/svclist.c
+init_SOURCES += initd/status.c initd/mksock.c initd/svclist.c
init_CPPFLAGS = $(AM_CPPFLAGS)
init_CFLAGS = $(AM_CFLAGS)
init_LDFLAGS = $(AM_LDFLAGS)
diff --git a/initd/init.h b/initd/init.h
index dee0b00..826af0f 100644
--- a/initd/init.h
+++ b/initd/init.h
@@ -98,16 +98,6 @@ void print_status(const char *msg, int type, bool update);
*/
int mksock(void);
-/********** shutdown.c **********/
-
-/*
- Kindly tell all processes to go kill themselves, then send
- a SIGKILL if they don't and perform system shutdown.
-
- The argument is passed directly to the reboot() syscall.
-*/
-NORETURN void do_shutdown(int type);
-
/********** svclist.c **********/
/*
diff --git a/initd/main.c b/initd/main.c
index d3e22b6..c4b796c 100644
--- a/initd/main.c
+++ b/initd/main.c
@@ -226,18 +226,10 @@ int main(void)
pfd[0].events = pfd[1].events = POLLIN;
for (;;) {
- if (!svclist_have_singleshot()) {
- if (target != runlevel) {
- start_runlevel(target);
- runlevel = target;
- continue;
- }
-
- if (runlevel == TGT_SHUTDOWN)
- do_shutdown(RB_POWER_OFF);
-
- if (runlevel == TGT_REBOOT)
- do_shutdown(RB_AUTOBOOT);
+ if (!svclist_have_singleshot() && target != runlevel) {
+ start_runlevel(target);
+ runlevel = target;
+ continue;
}
ret = poll(pfd, sizeof(pfd) / sizeof(pfd[0]), -1);
diff --git a/initd/shutdown.c b/initd/shutdown.c
deleted file mode 100644
index 1ee68c2..0000000
--- a/initd/shutdown.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * Copyright (C) 2018 - David Oberhollenzer
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdio.h>
-#include <errno.h>
-#include <time.h>
-
-#include "init.h"
-
-void do_shutdown(int type)
-{
- struct timespec req, rem;
-
- print_status("sending SIGTERM to all processes", STATUS_WAIT, false);
- kill(-1, SIGTERM);
-
- memset(&req, 0, sizeof(req));
- memset(&rem, 0, sizeof(rem));
- req.tv_sec = 5; /* TODO: make configurable? */
-
- while (nanosleep(&req, &rem) != 0 && errno == EINTR)
- req = rem;
-
- print_status("sending SIGTERM to all processes", STATUS_OK, true);
- kill(-1, SIGKILL);
- print_status("sending SIGKILL to remaining processes",
- STATUS_OK, false);
-
- print_status("sync", STATUS_WAIT, false);
- sync();
- print_status("sync", STATUS_OK, true);
-
- reboot(type);
- perror("reboot system call");
- exit(EXIT_FAILURE);
-}
diff --git a/services/Makemodule.am b/services/Makemodule.am
index 88c34a4..c9eeeec 100644
--- a/services/Makemodule.am
+++ b/services/Makemodule.am
@@ -1,5 +1,7 @@
initdir = @TEMPLATEDIR@
init_DATA = services/agetty services/hostname services/loopback
init_DATA += services/sysctl services/hwclock services/sysinit
+init_DATA += services/reboot services/shutdown services/sigkill
+init_DATA += services/sigterm services/sync
EXTRA_DIST += services/sysinit
diff --git a/services/reboot.in b/services/reboot.in
new file mode 100644
index 0000000..f913013
--- /dev/null
+++ b/services/reboot.in
@@ -0,0 +1,8 @@
+name = "reboot"
+description = "system reboot"
+exec = "@SBINPATH@/shutdown -nrf"
+type = wait
+target = reboot
+after = "sync"
+after = "sigkill"
+after = "sigterm"
diff --git a/services/shutdown.in b/services/shutdown.in
new file mode 100644
index 0000000..c97cde9
--- /dev/null
+++ b/services/shutdown.in
@@ -0,0 +1,8 @@
+name = "shutdown"
+description = "system shutdown"
+exec = "@SBINPATH@/shutdown -npf"
+type = wait
+target = shutdown
+after = "sync"
+after = "sigkill"
+after = "sigterm"
diff --git a/services/sigkill.in b/services/sigkill.in
new file mode 100644
index 0000000..24677e4
--- /dev/null
+++ b/services/sigkill.in
@@ -0,0 +1,9 @@
+name = "sigkill"
+description = "send SIGKILL to remaining processes"
+exec = "@SCRIPTDIR@/killall5 9"
+type = wait
+target = "%0"
+after = "sigterm"
+before = "sync"
+before = "shutdown"
+before = "reboot"
diff --git a/services/sigterm.in b/services/sigterm.in
new file mode 100644
index 0000000..c98e037
--- /dev/null
+++ b/services/sigterm.in
@@ -0,0 +1,10 @@
+name = "sigterm"
+description = "send SIGTERM to all processes"
+exec = "@SCRIPTDIR@/killall5 15"
+exec = "@BINPATH@/sleep 5"
+type = wait
+target = "%0"
+before = "sigkill"
+before = "sync"
+before = "reboot"
+before = "shutdown"
diff --git a/services/sync.in b/services/sync.in
new file mode 100644
index 0000000..7371b56
--- /dev/null
+++ b/services/sync.in
@@ -0,0 +1,9 @@
+name = "sync"
+description = "sync"
+exec = "@BINPATH@/sync"
+type = wait
+target = "%0"
+after = "sigkill"
+after = "sigterm"
+before = "reboot"
+before = "shutdown"