Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
I suppose the abstract socket solution, which has been tested and closes the window where the orderly poweroff successfully executes reliably, is a solution with minimal impact. On 02/15/2018 05:09 PM, Denys Vlasenko wrote: > On Thu, Feb 15, 2018 at 10:52 PM, Deb McLemore > wrote: >> Any logic attempting to guess at the state of startup will give false >> confidence that the signaling setup is completed. > The case of init not being ready to handle its duties for an extremely > early process is in itself a rather corner case. I would imagine > some people seeing as a bug, and maybe even having kernel fixed > to avoid it. > > I can just disagree to cater for this case and propose people affected > by it to have a special /sbin/poweroff script with whatever magic they want. > E.g.: > > #!/bin/sh > while true; do > /bin/busybox poweroff "$@" > /bin/sleep 1 > done > > So far I'm open to adding a workaround in poweroff code, if it's not > adding stuff to the init per se - why add bloat to the process which > is always there? > ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On Thu, Feb 15, 2018 at 10:52 PM, Deb McLemore wrote: > Any logic attempting to guess at the state of startup will give false > confidence that the signaling setup is completed. The case of init not being ready to handle its duties for an extremely early process is in itself a rather corner case. I would imagine some people seeing as a bug, and maybe even having kernel fixed to avoid it. I can just disagree to cater for this case and propose people affected by it to have a special /sbin/poweroff script with whatever magic they want. E.g.: #!/bin/sh while true; do /bin/busybox poweroff "$@" /bin/sleep 1 done So far I'm open to adding a workaround in poweroff code, if it's not adding stuff to the init per se - why add bloat to the process which is always there? ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
Any logic attempting to guess at the state of startup will give false confidence that the signaling setup is completed. On 02/15/2018 01:42 PM, Denys Vlasenko wrote: > On Wed, Feb 14, 2018 at 6:53 PM, Deb McLemore > wrote: >> The only reproduction we were able to perform injected via a BMC soft >> poweroff being triggered. >> >> This then called into kernel/reboot.c (orderly_poweroff where the >> schedule_work was performed) utilizing the >> >> usermodehelper during the run_cmd /sbin/poweroff. > How about this? > > > +#if ENABLE_FEATURE_WAIT_FOR_INIT > +/* In Linux, "poweroff" may be spawned even before init. > + * For example, with ACPI: > + * linux/drivers/acpi/bus.c: > + * static void sb_notify_work(struct work_struct *dummy) > + * orderly_poweroff(true); > + * linux/kernel/reboot.c: > + * poweroff_cmd[] = "/sbin/poweroff"; > + * static int __orderly_poweroff(bool force) > + * ret = run_cmd(poweroff_cmd); > + * static int run_cmd(const char *cmd) > + * ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); > + * > + * We want to make sure init exists and listens to signals. > + */ > +static int init_was_not_there(void) > +{ > + enum { initial = 5 }; /* 5 seconds should be plenty for timeout */ > + int cnt = initial - 1; > + > + /* Just existence of PID 1 does not mean it installed > +* the handlers already. > +*/ > +#if 0 > + while (kill(1, 0) != 0 && --cnt >= 0) > + sleep(1); > +#endif > + /* ... so let's wait for some evidence a usual startup event, > +* mounting of /proc, happened. > +*/ > + while (access("/proc/meminfo", F_OK) != 0 && --cnt >= 0) > + sleep(1); > + > + /* Does it look like init wasn't there? */ > + return (cnt != initial - 1); > +} > +#else > +# define init_was_not_there() 0 > +#endif > > int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > int halt_main(int argc UNUSED_PARAM, char **argv) > @@ -171,6 +220,8 @@ int halt_main(int argc UNUSED_PARAM, char **argv) > if (!ENABLE_FEATURE_CALL_TELINIT) { > /* bbox init assumed */ > rc = kill(1, signals[which]); > + if (init_was_not_there()) > + rc = kill(1, signals[which]); > } else { > > > Even if the logic of waiting for "/proc/meminfo" fails > on a weird system which does _not_ mount /proc, > this will not make "poweroff" slow. It will poweroff at once, > then will try to send poweroff signal again a few seconds later > (in all likelihood, way too late in the afterlife). > ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On Wed, Feb 14, 2018 at 6:53 PM, Deb McLemore wrote: > The only reproduction we were able to perform injected via a BMC soft > poweroff being triggered. > > This then called into kernel/reboot.c (orderly_poweroff where the > schedule_work was performed) utilizing the > > usermodehelper during the run_cmd /sbin/poweroff. How about this? +#if ENABLE_FEATURE_WAIT_FOR_INIT +/* In Linux, "poweroff" may be spawned even before init. + * For example, with ACPI: + * linux/drivers/acpi/bus.c: + * static void sb_notify_work(struct work_struct *dummy) + * orderly_poweroff(true); + * linux/kernel/reboot.c: + * poweroff_cmd[] = "/sbin/poweroff"; + * static int __orderly_poweroff(bool force) + * ret = run_cmd(poweroff_cmd); + * static int run_cmd(const char *cmd) + * ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); + * + * We want to make sure init exists and listens to signals. + */ +static int init_was_not_there(void) +{ + enum { initial = 5 }; /* 5 seconds should be plenty for timeout */ + int cnt = initial - 1; + + /* Just existence of PID 1 does not mean it installed +* the handlers already. +*/ +#if 0 + while (kill(1, 0) != 0 && --cnt >= 0) + sleep(1); +#endif + /* ... so let's wait for some evidence a usual startup event, +* mounting of /proc, happened. +*/ + while (access("/proc/meminfo", F_OK) != 0 && --cnt >= 0) + sleep(1); + + /* Does it look like init wasn't there? */ + return (cnt != initial - 1); +} +#else +# define init_was_not_there() 0 +#endif int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int halt_main(int argc UNUSED_PARAM, char **argv) @@ -171,6 +220,8 @@ int halt_main(int argc UNUSED_PARAM, char **argv) if (!ENABLE_FEATURE_CALL_TELINIT) { /* bbox init assumed */ rc = kill(1, signals[which]); + if (init_was_not_there()) + rc = kill(1, signals[which]); } else { Even if the logic of waiting for "/proc/meminfo" fails on a weird system which does _not_ mount /proc, this will not make "poweroff" slow. It will poweroff at once, then will try to send poweroff signal again a few seconds later (in all likelihood, way too late in the afterlife). ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
The abstract socket is the indicator that the state of Busybox is ready to accept the signal that triggers the Busybox poweroff sequence, this handshake between the kernel userhelper and Busybox is indicator that Busybox is ready to accept the signal and then process the signal properly is the linkage desired (otherwise windows are still exposed). ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On 11/24/2017 9:09 PM, Deb McLemore wrote: + while (1) { + fdrc = connect(fdBB2, + (struct sockaddr *)&bb_addr2, + sizeof(sa_family_t) + + BB_SIGNALS_SOCKET_STR_LEN); + if (fdrc == 0) + break; + sleep(1); + } On 2/14/2018 1:58 PM, Michael Conrad wrote: This will give you even better "instant boot sequence abort" performance than you would get with the design you're proposing, unless you have some insanely high polling rate in the reboot_helper that you think can actually deliver the signal before init has even forked for the first time. Sorry, I wasn't paying close enough attention to what you were proposing. If you have a 1-second sleep, then you're really not trying to block the startup sequence, you're just looking for a way to make sure the signal gets delivered? ...then just /bin/reboot: #! /bin/sh while ! -d /proc; do sleep 1; done; /bin/busybox reboot ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On 2/14/2018 12:53 PM, Deb McLemore wrote: The only reproduction we were able to perform injected via a BMC soft poweroff being triggered. This then called into kernel/reboot.c (orderly_poweroff where the schedule_work was performed) utilizing the usermodehelper during the run_cmd /sbin/poweroff. I'd like to point out that there's still a race condition, since when init starts it might kick off the rest of your startup sequence before the idle reboot process gets a time slice to discover that init is alive and send the signal. Would it maybe be better to have the main script that initializes your system check for the existence of the socket, and if found, stop everything and tell init to shutdown? Also, why not have the reboot process look for something in the filesystem to indicate whether the system has started booting? Before init starts, there won't be anything in the filesystem, but that's not a problem because you can just wait until there is. To make a complete proposal, why not: reboot_helper: 1) create abstract socket 2) wait for any filesystem path that indicates init sequence has started (/proc maybe) 3) send reboot signal to init init_userspace.sh 1) check for abstract socket, and if exists, send signal to init and then exit 2) else run startup sequence This will give you even better "instant boot sequence abort" performance than you would get with the design you're proposing, unless you have some insanely high polling rate in the reboot_helper that you think can actually deliver the signal before init has even forked for the first time. -Mike ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
The only reproduction we were able to perform injected via a BMC soft poweroff being triggered. This then called into kernel/reboot.c (orderly_poweroff where the schedule_work was performed) utilizing the usermodehelper during the run_cmd /sbin/poweroff. On 02/14/2018 09:44 AM, Laurent Bercot wrote: >> When PID=0 in early kernel_init, PID=1 has a skeleton running, this >> detection is not >> >> the Busybox /sbin/init, but a place holder for when the real Busybox >> /sbin/init is do_execve'd > > Are you saying the kernel could spawn a /sbin/reboot process *before* > kernel_init execs into the userspace init? > > If it's the case (and Denys' test will verify it), it's violently out > of spec. There should be no other userspace processes present before > init, and if there are, the behaviour is totally undefined, and things > should very much be expected to fail. It is basically impossible to > program under Unix if you cannot assume there is a pid 1 present that > will reap zombies. > > It would be worth it to report the situation to the kernel maintainers > so they make sure the spawning of userspace processes (triggered by > soft-poweroff or anything else) is deferred until after /sbin/init has > been do_execve()'d. > > -- > Laurent > ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On Wed, Feb 14, 2018 at 4:44 PM, Laurent Bercot wrote: >> When PID=0 in early kernel_init, PID=1 has a skeleton running, this >> detection is not >> >> the Busybox /sbin/init, but a place holder for when the real Busybox >> /sbin/init is do_execve'd > > > Are you saying the kernel could spawn a /sbin/reboot process *before* > kernel_init execs into the userspace init? Probably a hotplug helper of some sort ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
When PID=0 in early kernel_init, PID=1 has a skeleton running, this detection is not the Busybox /sbin/init, but a place holder for when the real Busybox /sbin/init is do_execve'd Are you saying the kernel could spawn a /sbin/reboot process *before* kernel_init execs into the userspace init? If it's the case (and Denys' test will verify it), it's violently out of spec. There should be no other userspace processes present before init, and if there are, the behaviour is totally undefined, and things should very much be expected to fail. It is basically impossible to program under Unix if you cannot assume there is a pid 1 present that will reap zombies. It would be worth it to report the situation to the kernel maintainers so they make sure the spawning of userspace processes (triggered by soft-poweroff or anything else) is deferred until after /sbin/init has been do_execve()'d. -- Laurent ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On Wed, Feb 14, 2018 at 2:49 PM, Deb McLemore wrote: > When PID=0 in early kernel_init, PID=1 has a skeleton running, this detection > is not > > the Busybox /sbin/init, but a place holder for when the real Busybox > /sbin/init is do_execve'd > > and then the kernel flushes all the old process table information on the > place holder of PID=1, > > then the real Busybox /sbin/init starts its life all fresh from the > do_execve, no state remains. I would like to reproduce it. I use a tiny qemu environment for my tests, see attached. Can you modify it so that a process is started before init? testing_in_qemu.tar.gz Description: GNU Zip compressed data ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
When PID=0 in early kernel_init, PID=1 has a skeleton running, this detection is not the Busybox /sbin/init, but a place holder for when the real Busybox /sbin/init is do_execve'd and then the kernel flushes all the old process table information on the place holder of PID=1, then the real Busybox /sbin/init starts its life all fresh from the do_execve, no state remains. On 02/14/2018 06:49 AM, Denys Vlasenko wrote: > On Wed, Feb 14, 2018 at 4:29 AM, Deb McLemore > wrote: >> On 02/13/2018 08:32 PM, Laurent Bercot wrote: Even when process=1 is started, it still leaves a window when the signal handler setup has not been completed. >>> Yes, but you can still use kill(pid, 0) to check whether init is >>> ready to receive signals: doublefork a zombie and repeatedly kill it >>> with signal 0. When you get -1 ESRCH, it means init has reapt the >>> zombie, so it's in its reaping loop, and at that point you know it >>> has installed its signal handlers. >>> >>> See http://lists.busybox.net/pipermail/busybox/2017-October/085888.html >>> >>> That's arguably uglier than using abstract sockets, but it can >>> be done without modifying the init code at all. >> From the original thread, we tried the suggestion, but when the do_execve is >> done from kernel_init >> >> for Busybox /sbin/init (to start PID=1) all process zombies are flushed (the >> usermode helper that kicks >> >> Busybox /sbin/poweroff started by PID=2, before PID=1 is do_execve'd from >> kernel init). So when the line is crossed >> >> when PID=1 begins all zombies and pre-work are flushed, so nothing is >> carried over into the life of PID=1 >> to synchronize with or detect when the signals are properly setup. > You can detect this: before init is started, kill(1,0) should be giving ESRCH. > Thus: first wait for kill(1,0) to return 0. > Then, do a child reaping test. Or just sleep(1). :] > ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On Wed, Feb 14, 2018 at 4:29 AM, Deb McLemore wrote: > On 02/13/2018 08:32 PM, Laurent Bercot wrote: >>> Even when process=1 is started, it still leaves a window when the >>> signal handler setup has not been completed. >> >> Yes, but you can still use kill(pid, 0) to check whether init is >> ready to receive signals: doublefork a zombie and repeatedly kill it >> with signal 0. When you get -1 ESRCH, it means init has reapt the >> zombie, so it's in its reaping loop, and at that point you know it >> has installed its signal handlers. >> >> See http://lists.busybox.net/pipermail/busybox/2017-October/085888.html >> >> That's arguably uglier than using abstract sockets, but it can >> be done without modifying the init code at all. > From the original thread, we tried the suggestion, but when the do_execve is > done from kernel_init > > for Busybox /sbin/init (to start PID=1) all process zombies are flushed (the > usermode helper that kicks > > Busybox /sbin/poweroff started by PID=2, before PID=1 is do_execve'd from > kernel init). So when the line is crossed > > when PID=1 begins all zombies and pre-work are flushed, so nothing is carried > over into the life of PID=1 > to synchronize with or detect when the signals are properly setup. You can detect this: before init is started, kill(1,0) should be giving ESRCH. Thus: first wait for kill(1,0) to return 0. Then, do a child reaping test. Or just sleep(1). :] ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
>From the original thread, we tried the suggestion, but when the do_execve is >done from kernel_init for Busybox /sbin/init (to start PID=1) all process zombies are flushed (the usermode helper that kicks Busybox /sbin/poweroff started by PID=2, before PID=1 is do_execve'd from kernel init). So when the line is crossed when PID=1 begins all zombies and pre-work are flushed, so nothing is carried over into the life of PID=1 to synchronize with or detect when the signals are properly setup. The only solution which worked was doing the abstract socket handshake which stays persistent across the boundary from PID=0 heritage to when PID=1 is properly instantiated. proc_flush_task_mnt from linux/fs/proc/base.c On 02/13/2018 08:32 PM, Laurent Bercot wrote: >> Even when process=1 is started, it still leaves a window when the >> signal handler setup has not been completed. > > Yes, but you can still use kill(pid, 0) to check whether init is > ready to receive signals: doublefork a zombie and repeatedly kill it > with signal 0. When you get -1 ESRCH, it means init has reapt the > zombie, so it's in its reaping loop, and at that point you know it > has installed its signal handlers. > > See http://lists.busybox.net/pipermail/busybox/2017-October/085888.html > > That's arguably uglier than using abstract sockets, but it can > be done without modifying the init code at all. > > -- > Laurent > ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
Even when process=1 is started, it still leaves a window when the signal handler setup has not been completed. Yes, but you can still use kill(pid, 0) to check whether init is ready to receive signals: doublefork a zombie and repeatedly kill it with signal 0. When you get -1 ESRCH, it means init has reapt the zombie, so it's in its reaping loop, and at that point you know it has installed its signal handlers. See http://lists.busybox.net/pipermail/busybox/2017-October/085888.html That's arguably uglier than using abstract sockets, but it can be done without modifying the init code at all. -- Laurent ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
+ fdrc = connect(fdBB2, + (struct sockaddr *)&bb_addr2, + sizeof(sa_family_t) + + BB_SIGNALS_SOCKET_STR_LEN); + if (fdrc == 0) + break; This will not work, because connect() will not succeed if the server does not listen(). And you cannot listen() in init without significantly rewriting its execution flow. However, you can still use this: connect() on an unbound socket will return -1 ENOENT, connect() on a bound socket that is not listening will return -1 ECONNREFUSED. So if you change your fdrc test to an (errno == ECONNREFUSED) test, it should work. See http://lists.busybox.net/pipermail/busybox/2017-October/085893.html and the whole surrounding thread. -- Laurent ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
Even when process=1 is started, it still leaves a window when the signal handler setup has not been completed. bb_signals is for all signal handling setup. On 02/13/2018 02:41 PM, Denys Vlasenko wrote: > On Sat, Nov 25, 2017 at 3:09 AM, Deb McLemore > wrote: >> 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 >> --- >> 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" > Probably should be "\0bb_init_signals". > > But I wonder. Can't you probe for existence of process 1 > using kill(1,0) syscall returning 0 or ESRCH? > ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup
On Sat, Nov 25, 2017 at 3:09 AM, Deb McLemore wrote: > 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 > --- > 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" Probably should be "\0bb_init_signals". But I wonder. Can't you probe for existence of process 1 using kill(1,0) syscall returning 0 or ESRCH? ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] init: Add handshake to poweroff/reboot for signal handler setup
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 --- 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 +#endif + #if ENABLE_FEATURE_WTMP #include @@ -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 # include +# include #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