[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
From:       Deb McLemore <debmc () linux ! vnet ! ibm ! com>
Date:       2017-11-25 2:09:15
Message-ID: 1511575755-29439-1-git-send-email-debmc () linux ! vnet ! ibm ! com
[Download RAW message or body]

Add an abstract socket to synchronize the readiness of init to receive
the SIGUSR2 to catch poweroff/reboot during an IPL phase (e.g. soft power
off via BMC).

Signed-off-by: Deb McLemore <debmc@linux.vnet.ibm.com>
---
 include/libbb.h |  5 +++++
 init/halt.c     | 33 +++++++++++++++++++++++++++++++++
 init/init.c     | 22 ++++++++++++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/include/libbb.h b/include/libbb.h
index daccf15..9f9bfc2 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -174,6 +174,11 @@
 # define STRERROR_ERRNO  ,strerror(errno)
 #endif
 
+#ifdef __linux
+#define BB_SIGNALS_SOCKET_STRING "\0bb_signals"
+#define BB_SIGNALS_SOCKET_STR_LEN 11
+#endif
+
 
 /* Some libc's forget to declare these, do it ourself */
 
diff --git a/init/halt.c b/init/halt.c
index c6c857f..47252e6 100644
--- a/init/halt.c
+++ b/init/halt.c
@@ -83,6 +83,10 @@
 #include "libbb.h"
 #include "reboot.h"
 
+#ifdef __linux__
+#include <sys/un.h>
+#endif
+
 #if ENABLE_FEATURE_WTMP
 #include <sys/utsname.h>
 
@@ -112,6 +116,13 @@ static void write_wtmp(void)
 int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int halt_main(int argc UNUSED_PARAM, char **argv)
 {
+
+#ifdef __linux__
+	struct sockaddr_un bb_addr2 = { .sun_family = AF_UNIX,
+				.sun_path = BB_SIGNALS_SOCKET_STRING };
+	int fdBB2 = 0;
+	int fdrc = 0;
+#endif
 	static const int magic[] = {
 		RB_HALT_SYSTEM,
 		RB_POWER_OFF,
@@ -170,6 +181,28 @@ int halt_main(int argc UNUSED_PARAM, char **argv)
 			/* talk to init */
 			if (!ENABLE_FEATURE_CALL_TELINIT) {
 				/* bbox init assumed */
+
+				/* Use socket connect to INIT to assure that
+				 * signal handlers are ready
+				 */
+				#ifdef __linux__
+				while (1) {
+					fdBB2 = socket(AF_UNIX,
+						SOCK_CLOEXEC | SOCK_DGRAM, 0);
+					if (fdBB2 != -1)
+						break;
+					sleep(1);
+				}
+				while (1) {
+					fdrc = connect(fdBB2,
+					(struct sockaddr *)&bb_addr2,
+					sizeof(sa_family_t) +
+						BB_SIGNALS_SOCKET_STR_LEN);
+					if (fdrc == 0)
+						break;
+					sleep(1);
+				}
+				#endif
 				rc = kill(1, signals[which]);
 			} else {
 				/* SysV style init assumed */
diff --git a/init/init.c b/init/init.c
index 6f3374e..4461fb6 100644
--- a/init/init.c
+++ b/init/init.c
@@ -133,6 +133,7 @@
 #ifdef __linux__
 # include <linux/vt.h>
 # include <sys/sysinfo.h>
+# include <sys/un.h>
 #endif
 #include "reboot.h" /* reboot() constants */
 
@@ -1046,6 +1047,13 @@ static void sleep_much(void)
 int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int init_main(int argc UNUSED_PARAM, char **argv)
 {
+
+#ifdef __linux__
+	struct sockaddr_un bb_addr = { .sun_family = AF_UNIX,
+			.sun_path = BB_SIGNALS_SOCKET_STRING };
+	int fdBB = 0;
+#endif
+
 	if (argv[1] && strcmp(argv[1], "-q") == 0) {
 		return kill(1, SIGHUP);
 	}
@@ -1191,6 +1199,20 @@ int init_main(int argc UNUSED_PARAM, char **argv)
 		sigprocmask_allsigs(SIG_UNBLOCK);
 	}
 
+#ifdef __linux__
+	/* Create an abstract socket to use for synchronizing poweroff and
+	 * reboot which could be kicked at IPL before the INIT process
+	 * completes signal setup to listen for the signals
+	 * Ignore failures and keep on, this just helps
+	 * close the exposed window when nothing will get signaled
+	 * The abstract socket needs to stay persistent, so no cleanup
+	 */
+	fdBB = socket(AF_UNIX, SOCK_CLOEXEC | SOCK_DGRAM, 0);
+	if (fdBB != -1)
+		bind(fdBB, (struct sockaddr *)&bb_addr,
+		sizeof(sa_family_t) + BB_SIGNALS_SOCKET_STR_LEN);
+#endif
+
 	/* Now run everything that needs to be run */
 	/* First run the sysinit command */
 	run_actions(SYSINIT);
-- 
2.7.4

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic