diff --git a/examples/var_service/README_distro_proposal.txt b/examples/var_service/README_distro_proposal.txt index ec887b4e1..f161406a7 100644 --- a/examples/var_service/README_distro_proposal.txt +++ b/examples/var_service/README_distro_proposal.txt @@ -246,7 +246,8 @@ relative to the system-wide service directory. This proposal asks developers of other daemontools implementations to add "svc" command to their projects] -The "svok DIR" tool exits 0 if service is running, and nonzero if not. +The "svok DIR" tool exits 0 if service supervisor is running +(with service itself either running or stopped), and nonzero if not. Other tools with different names and APIs may exist; however for portability scripts should use the above tools. diff --git a/examples/var_service/ifplugd_if/run b/examples/var_service/ifplugd_if/run index fade8b98d..5d1d4e355 100755 --- a/examples/var_service/ifplugd_if/run +++ b/examples/var_service/ifplugd_if/run @@ -16,7 +16,7 @@ exec \ env - PATH="$PATH" \ softlimit \ setuidgid root \ -ifplugd -apqlns -t3 -u8 -d8 -i "$if" -r "$pwd/ifplugd_handler" +ifplugd -aqlns -t3 -u8 -d8 -i "$if" -r "$pwd/ifplugd_handler" # We use -t3 to wake ifplugd up less often. # If after three tests (3*3=9 > 8) link state seen to be different, @@ -24,6 +24,12 @@ ifplugd -apqlns -t3 -u8 -d8 -i "$if" -r "$pwd/ifplugd_handler" # IOW: short link losses will be ignored, longer ones # will trigger DHCP reconfiguration and such (see handler code). +# -l makes ifplugd run either "up" or "down" script on startup. +# For example, if wired eth cable is unplugged, this stops dhcp service +# from pointlessly trying to get a lease. +# -q means that stopping monitoring does not stop dhcp/zcip/etc: +# presumably, admin decided to control them manually. + #-a Don't up interface automatically #-p Don't run "up" script on startup #-q Don't run "down" script on exit diff --git a/runit/sv.c b/runit/sv.c index dc5dcceb3..86d181872 100644 --- a/runit/sv.c +++ b/runit/sv.c @@ -163,7 +163,7 @@ Exit Codes //config:config SV_DEFAULT_SERVICE_DIR //config: string "Default directory for services" //config: default "/var/service" -//config: depends on SV +//config: depends on SV || SVC || SVOK //config: help //config: Default directory for services. //config: Defaults to "/var/service" @@ -173,13 +173,22 @@ Exit Codes //config: default y //config: help //config: svc controls the state of services monitored by the runsv supervisor. -//config: It is comaptible with daemontools command with the same name. +//config: It is compatible with daemontools command with the same name. +//config: +//config:config SVOK +//config: bool "svok" +//config: default y +//config: help +//config: svok checks whether runsv supervisor is running. +//config: It is compatible with daemontools command with the same name. -//applet:IF_SV( APPLET_NOEXEC(sv, sv, BB_DIR_USR_BIN, BB_SUID_DROP, sv )) -//applet:IF_SVC(APPLET_NOEXEC(svc, svc, BB_DIR_USR_BIN, BB_SUID_DROP, svc)) +//applet:IF_SV( APPLET_NOEXEC(sv, sv, BB_DIR_USR_BIN, BB_SUID_DROP, sv )) +//applet:IF_SVC( APPLET_NOEXEC(svc, svc, BB_DIR_USR_BIN, BB_SUID_DROP, svc )) +//applet:IF_SVOK(APPLET_NOEXEC(svok, svok, BB_DIR_USR_BIN, BB_SUID_DROP, svok)) //kbuild:lib-$(CONFIG_SV) += sv.o //kbuild:lib-$(CONFIG_SVC) += sv.o +//kbuild:lib-$(CONFIG_SVOK) += sv.o #include #include "libbb.h" @@ -615,7 +624,7 @@ static int sv(char **argv) service = argv; while ((x = *service) != NULL) { if (x[0] != '/' && x[0] != '.' - && x[0] != '\0' && x[strlen(x) - 1] != '/' + && !last_char_is(x, '/') ) { if (chdir(varservice) == -1) goto chdir_failed_0; @@ -742,3 +751,41 @@ int svc_main(int argc UNUSED_PARAM, char **argv) return 0; } #endif + +//usage:#define svok_trivial_usage +//usage: "SERVICE_DIR" +//usage:#define svok_full_usage "\n\n" +//usage: "Check whether runsv supervisor is running.\n" +//usage: "Exit code is 0 if it does, 100 if it does not,\n" +//usage: "111 (with error message) if SERVICE_DIR does not exist." +#if ENABLE_SVOK +int svok_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int svok_main(int argc UNUSED_PARAM, char **argv) +{ + const char *dir = argv[1]; + + if (!dir) + bb_show_usage(); + + xfunc_error_retval = 111; + + /* + * daemontools has no concept of "default service dir", runit does. + * Let's act as runit. + */ + if (dir[0] != '/' && dir[0] != '.' + && !last_char_is(dir, '/') + ) { + xchdir(CONFIG_SV_DEFAULT_SERVICE_DIR); + } + + xchdir(dir); + if (open("supervise/ok", O_WRONLY) < 0) { + if (errno == ENOENT || errno == ENXIO) + return 100; + bb_perror_msg_and_die("can't open '%s'", "supervise/ok"); + } + + return 0; +} +#endif