[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