[PATCH v2] inotifyd: -x: new option

2015-08-25 Thread Bartosz Golaszewski
Add -x option which allows to specify the exit status of PROG for which
inotifyd should exit.

An example use case for this change is writing parallel system startup
scripts with busybox' runit: inotifyd can be used to wait for a specific
pid-file to appear in /var/run and then exit, allowing the blocked script
to proceed.

function old new   delta
inotifyd_main653 742 +89
.rodata   157197  157261 +64
packed_usage   30460   30516 +56
--
(add/remove: 0/0 grow/shrink: 3/0 up/down: 209/0) Total: 209 bytes

Signed-off-by: Bartosz Golaszewski 
---
v2:
- don't call xstrtol_range() if -x is not specified

v1:
http://lists.busybox.net/pipermail/busybox/2015-August/083219.html

 miscutils/inotifyd.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c
index 7a1a6a2..e142668 100644
--- a/miscutils/inotifyd.c
+++ b/miscutils/inotifyd.c
@@ -28,7 +28,7 @@
  */
 
 //usage:#define inotifyd_trivial_usage
-//usage:   "PROG FILE1[:MASK]..."
+//usage:   "[OPTS] PROG FILE1[:MASK]..."
 //usage:#define inotifyd_full_usage "\n\n"
 //usage:   "Run PROG on filesystem changes."
 //usage: "\nWhen a filesystem event matching MASK occurs on FILEn,"
@@ -52,12 +52,17 @@
 //usage: "\n   n   Subfile is created"
 //usage: "\n   d   Subfile is deleted"
 //usage: "\n"
+//usage: "\nOptions:"
+//usage: "\n   -x STATUS   Exit if PROG returns STATUS"
+//usage: "\n"
 //usage: "\ninotifyd waits for PROG to exit."
 //usage: "\nWhen x event happens for all FILEs, inotifyd exits."
 
 #include "libbb.h"
 #include 
 
+#define OPT_x (1 << 0)
+
 static const char mask_names[] ALIGN1 =
"a" // 0x0001   File was accessed
"c" // 0x0002   File was modified
@@ -84,17 +89,21 @@ enum {
 int inotifyd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int inotifyd_main(int argc, char **argv)
 {
-   int n;
-   unsigned mask;
+   int n, exp_st, st;
+   unsigned mask, opts;
struct pollfd pfd;
char **watches; // names of files being watched
const char *args[5];
+   char *opt_x_str;
+
+   opts = getopt32(argv, "x:", &opt_x_str);
+   argc -= optind;
+   argv += optind;
 
// sanity check: agent and at least one watch must be given
-   if (!argv[1] || !argv[2])
+   if (!argv[0] || !argv[1])
bb_show_usage();
 
-   argv++;
// inotify_add_watch will number watched files
// starting from 1, thus watches[0] is unimportant,
// and 1st file name is watches[1].
@@ -190,7 +199,12 @@ int inotifyd_main(int argc, char **argv)
args[1] = events;
args[2] = watches[ie->wd];
args[3] = ie->len ? ie->name : NULL;
-   spawn_and_wait((char **)args);
+   st = spawn_and_wait((char **)args);
+   if (opts & OPT_x) {
+   exp_st = 
xstrtol_range(opt_x_str, 10, 0, 255);
+   if (st == exp_st)
+   goto done;
+   }
}
// we are done if all files got final x event
if (ie->mask & 0x8000) {
-- 
2.1.4

___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-09-15 Thread Bartosz Gołaszewski
2015-08-25 15:39 GMT+02:00 Bartosz Golaszewski :
> Add -x option which allows to specify the exit status of PROG for which
> inotifyd should exit.
>
> An example use case for this change is writing parallel system startup
> scripts with busybox' runit: inotifyd can be used to wait for a specific
> pid-file to appear in /var/run and then exit, allowing the blocked script
> to proceed.

Is there any chance of merging this? I suppose inotifyd in busybox is
loosely based on inotifywait from inotify-tools which has an option to
exit upon receiving an event. It's also much cleaner then killing
inotifyd from spawned processes.

-- 
Best regards,
Bartosz Golaszewski

> function old new   delta
> inotifyd_main653 742 +89
> .rodata   157197  157261 +64
> packed_usage   30460 30516 +56
> --
> (add/remove: 0/0 grow/shrink: 3/0 up/down: 209/0) Total: 209 bytes
>
> Signed-off-by: Bartosz Golaszewski 
> ---
> v2:
> - don't call xstrtol_range() if -x is not specified
>
> v1:
> http://lists.busybox.net/pipermail/busybox/2015-August/083219.html
>
>  miscutils/inotifyd.c | 26 --
>  1 file changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c
> index 7a1a6a2..e142668 100644
> --- a/miscutils/inotifyd.c
> +++ b/miscutils/inotifyd.c
> @@ -28,7 +28,7 @@
>   */
>
>  //usage:#define inotifyd_trivial_usage
> -//usage:   "PROG FILE1[:MASK]..."
> +//usage:   "[OPTS] PROG FILE1[:MASK]..."
>  //usage:#define inotifyd_full_usage "\n\n"
>  //usage:   "Run PROG on filesystem changes."
>  //usage: "\nWhen a filesystem event matching MASK occurs on FILEn,"
> @@ -52,12 +52,17 @@
>  //usage: "\n   n   Subfile is created"
>  //usage: "\n   d   Subfile is deleted"
>  //usage: "\n"
> +//usage: "\nOptions:"
> +//usage: "\n   -x STATUS   Exit if PROG returns STATUS"
> +//usage: "\n"
>  //usage: "\ninotifyd waits for PROG to exit."
>  //usage: "\nWhen x event happens for all FILEs, inotifyd exits."
>
>  #include "libbb.h"
>  #include 
>
> +#define OPT_x (1 << 0)
> +
>  static const char mask_names[] ALIGN1 =
> "a" // 0x0001   File was accessed
> "c" // 0x0002   File was modified
> @@ -84,17 +89,21 @@ enum {
>  int inotifyd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
>  int inotifyd_main(int argc, char **argv)
>  {
> -   int n;
> -   unsigned mask;
> +   int n, exp_st, st;
> +   unsigned mask, opts;
> struct pollfd pfd;
> char **watches; // names of files being watched
> const char *args[5];
> +   char *opt_x_str;
> +
> +   opts = getopt32(argv, "x:", &opt_x_str);
> +   argc -= optind;
> +   argv += optind;
>
> // sanity check: agent and at least one watch must be given
> -   if (!argv[1] || !argv[2])
> +   if (!argv[0] || !argv[1])
> bb_show_usage();
>
> -   argv++;
> // inotify_add_watch will number watched files
> // starting from 1, thus watches[0] is unimportant,
> // and 1st file name is watches[1].
> @@ -190,7 +199,12 @@ int inotifyd_main(int argc, char **argv)
> args[1] = events;
> args[2] = watches[ie->wd];
> args[3] = ie->len ? ie->name : NULL;
> -   spawn_and_wait((char **)args);
> +   st = spawn_and_wait((char **)args);
> +   if (opts & OPT_x) {
> +   exp_st = 
> xstrtol_range(opt_x_str, 10, 0, 255);
> +   if (st == exp_st)
> +   goto done;
> +   }
> }
> // we are done if all files got final x event
> if (ie->mask & 0x8000) {
> --
> 2.1.4
>
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-16 Thread Denys Vlasenko
On Tue, Sep 15, 2015 at 12:21 PM, Bartosz Gołaszewski
 wrote:
> 2015-08-25 15:39 GMT+02:00 Bartosz Golaszewski :
>> Add -x option which allows to specify the exit status of PROG for which
>> inotifyd should exit.
>>
>> An example use case for this change is writing parallel system startup
>> scripts with busybox' runit: inotifyd can be used to wait for a specific
>> pid-file to appear in /var/run and then exit, allowing the blocked script
>> to proceed.
>
> Is there any chance of merging this? I suppose inotifyd in busybox is
> loosely based on inotifywait from inotify-tools which has an option to
> exit upon receiving an event.

No, I was not aware inotifywait exists.

> It's also much cleaner then killing inotifyd from spawned processes.

I think killing $PPID from children is a completely legitimate approach.

Are you sure you aren't just feeling attachment to the work you did?
This happens to me too.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Re: [PATCH v2] inotifyd: -x: new option

2015-10-16 Thread Laurent Bercot

On 16/10/2015 20:29, Denys Vlasenko wrote:

I think killing $PPID from children is a completely legitimate approach.


 FWIW, I dislike parricide. The flow of information is backwards; it
forces the child to know in what context it is run.
 I agree with Bartosz in that it is much cleaner to encode information
in the child's return code, and have the parent explicitly support a
code that makes itexit.

--
 Laurent

___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-17 Thread Denys Vlasenko
On Fri, Oct 16, 2015 at 10:49 PM, Laurent Bercot
 wrote:
> On 16/10/2015 20:29, Denys Vlasenko wrote:
>>
>> I think killing $PPID from children is a completely legitimate approach.
>
>
>  FWIW, I dislike parricide. The flow of information is backwards; it
> forces the child to know in what context it is run.

If you have a program which does not know that it is being run by inotifyd,
you can create a shim which does know that:

#!/bin/sh
PROG "$@"
test "$?" = 111 && kill $PPID

>  I agree with Bartosz in that it is much cleaner to encode information
> in the child's return code, and have the parent explicitly support a
> code that makes itexit.

This does not sound like technical argument, it's an aesthetic one.
You propose to add complexity to inotifyd because it's looks "cleaner".
I don't see it as "cleaner", I see both ways as legitimate.
But your way requires additional code.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-17 Thread Laurent Bercot

On 17/10/2015 09:47, Denys Vlasenko wrote:

If you have a program which does not know that it is being run by inotifyd,
you can create a shim which does know that:

#!/bin/sh
PROG "$@"
test "$?" = 111 && kill $PPID


 Yes. You still have to know which program needs it and which one does
not, and you have to run that shim for every program that does. This
is code - a longer code path than Bartosz's patch, and that has to be
maintained separately.



This does not sound like technical argument, it's an aesthetic one.


 Indeed, but aesthetics usually translate to very tangible, technical
benefits: either shorter code paths, or better maintainability. Here,
it translates to both.



You propose to add complexity to inotifyd because it's looks "cleaner".
I don't see it as "cleaner", I see both ways as legitimate.
But your way requires additional code.


 It requires additional code in inotifyd, yes. But it factorizes code
that you would have had to run anyway, in scripting the child. It also
allows you to make the natural assumption that a child cannot impact
its parent (except by returning a certain exit code), which I find
makes scripts easier to understand, so more maintainable. It is not
intuitive, when reading the script, to think "ah, inotifyd can be
killed by its child" - the mechanism works, and is legitimate as you
put it, but the information flow is more convoluted and requires more
effort to understand than just following the exit codes trail.

--
 Laurent

___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-20 Thread Denys Vlasenko
On Sat, Oct 17, 2015 at 12:38 PM, Laurent Bercot
 wrote:
> On 17/10/2015 09:47, Denys Vlasenko wrote:
>>
>> If you have a program which does not know that it is being run by
>> inotifyd,
>> you can create a shim which does know that:
>>
>> #!/bin/sh
>> PROG "$@"
>> test "$?" = 111 && kill $PPID
>
>
>  Yes. You still have to know which program needs it and which one does
> not, and you have to run that shim for every program that does. This
> is code - a longer code path than Bartosz's patch, and that has to be
> maintained separately.

inotifyd syntax is "inotifyd PROG FILE1[:MASK]...",
and PROG is run with

PROG ACTUAL_EVENTS FILEn [SUBFILE]

This severely limits the number of unmodified PROGs you can run
to achieve some useful result. For example, even cat'ting newly
created files to stdout can't be done by PROG=cat, you need
to massage argv's

IOW: in practice, you always need a shim.

>> You propose to add complexity to inotifyd because it's looks "cleaner".
>> I don't see it as "cleaner", I see both ways as legitimate.
>> But your way requires additional code.
>
>  It requires additional code in inotifyd, yes. But it factorizes code
> that you would have had to run anyway, in scripting the child. It also
> allows you to make the natural assumption that a child cannot impact
> its parent (except by returning a certain exit code), which I find
> makes scripts easier to understand, so more maintainable.

Sorry, but I don't agree to this view even after you repeat it.
Here is an example where this idiom of "killing the parent"
is used already:

busybox/examples/var_service/ntpd/ntp.script
...
if test x"$1" = x"unsync"; then
# No replies for our NTP requests were seen for some time.
#
# Among more mundate cases like network outages, this happens
# if we ran for a LONG time (days) and ntp server's IP has changed.
# ntpd has no code to re-resolve peers' addresses to IPs,
# we need to help it:
#
echo "$dt: $1"\
"syncronization lost, restarting ntpd"\
>>"$0.log.$$"
mv -- "$0.log.$$" "$0.log"
kill $PPID
exit
fi
...

Can you point me to the software you are working on so that
I can look on a wider picture of the problem you are trying to solve?
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-20 Thread Laurent Bercot

On 20/10/2015 13:17, Denys Vlasenko wrote:

inotifyd syntax is "inotifyd PROG FILE1[:MASK]...",
and PROG is run with

 PROG ACTUAL_EVENTS FILEn [SUBFILE]

This severely limits the number of unmodified PROGs you can run
to achieve some useful result. (...)
IOW: in practice, you always need a shim.


 Ah, indeed. It's a shame PROG is a single argument, though:
I very much prefer executing whole command lines. If you have
to tailor PROG to inotifyd's needs anyway, the "it's less code"
argument falls.



Sorry, but I don't agree to this view even after you repeat it.
Here is an example where this idiom of "killing the parent"
is used already:


 Well, giving me another example of this idiom doesn't convince
me that it's a good one either. :P
 ntpd, just like inotifyd, can be killed by one of its children?
I still don't like it. I'm a Unix traditionalist and reactionary:
parents should have control over their children, not the other way
round.



Can you point me to the software you are working on so that
I can look on a wider picture of the problem you are trying to solve?


 That would be Bartosz. I'm not working on any software using inotifyd,
I was just adding my support to his proposal from a pure "Unix software
design" point of view. But for me it's theoretical, and borderline
bikeshedding, and I can work with your design even if it's not my
preferred one - so if you won't be convinced, that's ok too, and I'll
just drop it. :)

--
 Laurent

___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-21 Thread Bartosz Gołaszewski
2015-10-20 13:17 GMT+02:00 Denys Vlasenko :
>
> inotifyd syntax is "inotifyd PROG FILE1[:MASK]...",
> and PROG is run with
>
> PROG ACTUAL_EVENTS FILEn [SUBFILE]
>
> This severely limits the number of unmodified PROGs you can run
> to achieve some useful result. For example, even cat'ting newly
> created files to stdout can't be done by PROG=cat, you need
> to massage argv's
>
> IOW: in practice, you always need a shim.

I agree that the functionality of inotifyd is limited. I tried working
with what's available.

Would you be willing to accept patches that expand this applet? Like
for example being able to redirect the events to stdout instead of
only being able to pass them as arguments to PROG? This is how
inotifywait works BTW.

Other than that: I'm late to the party - I don't have anything more to
add than what Laurent already said. I don't like the idea of a child
killing its parents - I prefer strict hierarchy.

Best regards,
Bartosz Golaszewski
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH v2] inotifyd: -x: new option

2015-10-22 Thread Denys Vlasenko
On Wed, Oct 21, 2015 at 11:56 AM, Bartosz Gołaszewski
 wrote:
> 2015-10-20 13:17 GMT+02:00 Denys Vlasenko :
>>
>> inotifyd syntax is "inotifyd PROG FILE1[:MASK]...",
>> and PROG is run with
>>
>> PROG ACTUAL_EVENTS FILEn [SUBFILE]
>>
>> This severely limits the number of unmodified PROGs you can run
>> to achieve some useful result. For example, even cat'ting newly
>> created files to stdout can't be done by PROG=cat, you need
>> to massage argv's
>>
>> IOW: in practice, you always need a shim.
>
> I agree that the functionality of inotifyd is limited. I tried working
> with what's available.
>
> Would you be willing to accept patches that expand this applet?

Yes.

> Like
> for example being able to redirect the events to stdout instead of
> only being able to pass them as arguments to PROG? This is how
> inotifywait works BTW.

It already does that:

BusyBox v1.25.0.git (2015-10-19 04:25:25 CEST) multi-call binary.

Usage: inotifyd PROG FILE1[:MASK]...

Run PROG on filesystem changes.
When a filesystem event matching MASK occurs on FILEn,
PROG ACTUAL_EVENTS FILEn [SUBFILE] is run.
If PROG is -, events are sent to stdout.
^

# inotifyd - /etc:r
r/etc
r/etcld.so.cache
r/etcld.so.cache
r/etcld.so.cache
r/etcld.so.cache
r/etcld.so.cache
r/etcmagic
r/etcbashrc
r/etcbashrc
...
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Re: [PATCH v2] inotifyd: -x: new option

2015-10-23 Thread Bartosz Gołaszewski
2015-10-22 16:46 GMT+02:00 Denys Vlasenko :
> On Wed, Oct 21, 2015 at 11:56 AM, Bartosz Gołaszewski
>  wrote:
>> 2015-10-20 13:17 GMT+02:00 Denys Vlasenko :
>>>
>>> inotifyd syntax is "inotifyd PROG FILE1[:MASK]...",
>>> and PROG is run with
>>>
>>> PROG ACTUAL_EVENTS FILEn [SUBFILE]
>>>
>>> This severely limits the number of unmodified PROGs you can run
>>> to achieve some useful result. For example, even cat'ting newly
>>> created files to stdout can't be done by PROG=cat, you need
>>> to massage argv's
>>>
>>> IOW: in practice, you always need a shim.
>>
>> I agree that the functionality of inotifyd is limited. I tried working
>> with what's available.
>>
>> Would you be willing to accept patches that expand this applet?
>
> Yes.
>
>> Like
>> for example being able to redirect the events to stdout instead of
>> only being able to pass them as arguments to PROG? This is how
>> inotifywait works BTW.
>
> It already does that:
>
> BusyBox v1.25.0.git (2015-10-19 04:25:25 CEST) multi-call binary.
>
> Usage: inotifyd PROG FILE1[:MASK]...
>
> Run PROG on filesystem changes.
> When a filesystem event matching MASK occurs on FILEn,
> PROG ACTUAL_EVENTS FILEn [SUBFILE] is run.
> If PROG is -, events are sent to stdout.
> ^
>
> # inotifyd - /etc:r
> r/etc
> r/etcld.so.cache
> r/etcld.so.cache
> r/etcld.so.cache
> r/etcld.so.cache
> r/etcld.so.cache
> r/etcmagic
> r/etcbashrc
> r/etcbashrc
> ...

Indeed, I forgot.

Just to clarify - is it a definite no to the patch?

-- 
Best regards,
Bartosz Golaszewski
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Re: [PATCH v2] inotifyd: -x: new option

2015-10-23 Thread Denys Vlasenko
On Fri, Oct 23, 2015 at 3:14 PM, Bartosz Gołaszewski
 wrote:
>>> Like
>>> for example being able to redirect the events to stdout instead of
>>> only being able to pass them as arguments to PROG? This is how
>>> inotifywait works BTW.
>>
>> It already does that:
>>
>> BusyBox v1.25.0.git (2015-10-19 04:25:25 CEST) multi-call binary.
>>
>> Usage: inotifyd PROG FILE1[:MASK]...
>>
>> Run PROG on filesystem changes.
>> When a filesystem event matching MASK occurs on FILEn,
>> PROG ACTUAL_EVENTS FILEn [SUBFILE] is run.
>> If PROG is -, events are sent to stdout.
>> ^
>>
>> # inotifyd - /etc:r
>> r/etc
>> r/etcld.so.cache
>> r/etcld.so.cache
>> r/etcld.so.cache
>> r/etcld.so.cache
>> r/etcld.so.cache
>> r/etcmagic
>> r/etcbashrc
>> r/etcbashrc
>> ...
>
> Indeed, I forgot.
>
> Just to clarify - is it a definite no to the patch?

I want to help you by looking at actual setup you want to speed up.

By seeing your problem, I might be convinced that your solution
is indeed necessary ;)
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Re: [PATCH v2] inotifyd: -x: new option

2015-10-24 Thread Bartosz Gołaszewski
2015-10-24 4:26 GMT+02:00 Denys Vlasenko :
> On Fri, Oct 23, 2015 at 3:14 PM, Bartosz Gołaszewski
>  wrote:
 Like
 for example being able to redirect the events to stdout instead of
 only being able to pass them as arguments to PROG? This is how
 inotifywait works BTW.
>>>
>>> It already does that:
>>>
>>> BusyBox v1.25.0.git (2015-10-19 04:25:25 CEST) multi-call binary.
>>>
>>> Usage: inotifyd PROG FILE1[:MASK]...
>>>
>>> Run PROG on filesystem changes.
>>> When a filesystem event matching MASK occurs on FILEn,
>>> PROG ACTUAL_EVENTS FILEn [SUBFILE] is run.
>>> If PROG is -, events are sent to stdout.
>>> ^
>>>
>>> # inotifyd - /etc:r
>>> r/etc
>>> r/etcld.so.cache
>>> r/etcld.so.cache
>>> r/etcld.so.cache
>>> r/etcld.so.cache
>>> r/etcld.so.cache
>>> r/etcmagic
>>> r/etcbashrc
>>> r/etcbashrc
>>> ...
>>
>> Indeed, I forgot.
>>
>> Just to clarify - is it a definite no to the patch?
>
> I want to help you by looking at actual setup you want to speed up.

This is not speeding anything up - it's rather to have an elegant
process startup. I start several processes that need xserver to be
running (fail if the xserver socket is not present). The start-up
scripts start inotifyd to wait for the socket to appear and then
continue the execution immediately. Otherwise I'd have to loop the
process execution until they don't fail to start.

> By seeing your problem, I might be convinced that your solution
> is indeed necessary ;)

I don't like the idea of a shim script killing inotifyd - its parent -
that's all. It would be nice to have this functionality if it doesn't
increase the default size (it's n by default in Kconfig). Additionally
if you would have the shim script drop privileges for any reason (I
know it's unlikely ;)) it would fail to signal inotifyd.

-- 
Best regards,
Bartosz Golaszewski
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox