Re: [PATCH] init: Add handshake to poweroff/reboot for signal handler setup

2018-02-15 Thread Deb McLemore
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

2018-02-15 Thread Denys Vlasenko
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

2018-02-15 Thread Deb McLemore
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

2018-02-15 Thread Denys Vlasenko
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

2018-02-15 Thread Deb McLemore
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

2018-02-14 Thread Michael Conrad

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

2018-02-14 Thread Michael Conrad

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

2018-02-14 Thread Deb McLemore
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

2018-02-14 Thread Denys Vlasenko
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

2018-02-14 Thread Laurent Bercot
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

2018-02-14 Thread Denys Vlasenko
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

2018-02-14 Thread Deb McLemore
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

2018-02-14 Thread Denys Vlasenko
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

2018-02-13 Thread Deb McLemore
>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

2018-02-13 Thread Laurent Bercot

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

2018-02-13 Thread Laurent Bercot

+   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

2018-02-13 Thread Deb McLemore
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

2018-02-13 Thread Denys Vlasenko
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

2017-11-24 Thread Deb McLemore
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