author | Olivier Brunel
<jjk@jjacky.com> 2015-03-16 18:52:38 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2015-04-04 12:47:36 UTC |
parent | 48002be7c7d01076740f5d77b9b87f320672df83 |
doc/aa-setready.pod | +85 | -0 |
package/modes | +1 | -0 |
package/targets.mak | +2 | -0 |
src/utils/aa-setready.c | +114 | -0 |
src/utils/deps-exe/aa-setready | +3 | -0 |
diff --git a/doc/aa-setready.pod b/doc/aa-setready.pod new file mode 100644 index 0000000..7c8e66a --- /dev/null +++ b/doc/aa-setready.pod @@ -0,0 +1,85 @@ +=head1 NAME + +aa-setready - Set a service (un)ready + +=head1 SYNOPSIS + +B<aa-setready> [B<-U> | B<-D>] I<SERVICEDIR> + +=head1 OPTIONS + +=over + +=item B<-U, --ready> + +Mark the service ready, i.e. create the I<ready> file and emit event 'U' on +I<event> fifodir. This is the default. + +=item B<-h, --help> + +Show help screen and exit. + +=item B<-D, --unready> + +Mark the service unready, i.e. remove the I<ready> file (if exists) and emit +event 'D' on I<event> fifodir. + +=item B<-V, --version> + +Show version information and exit. + +=back + +=head1 DESCRIPTION + +B<aa-setready>(1) is a simple tool to mark a long-running service ready or +"unready". + +Marking a service ready means create the I<ready> file (used by B<s6>) and emit +event U on the service's fifodir I<event>. This is similar to what +B<s6-notifywhenup> does. + +Marking a service unready means remove the I<ready> file if it exists, and emit +event D on the service's fifodir I<event>. This is meant for service that can +stay up (running) but lose their ready state (e.g. connection dropped). + +Obviously you need to have the appropriate permissions to perform all the needed +tasks. + +=head2 RETURN VALUE + +B<aa-setready>(1) will return 0 on success. If an error occurs one or more +warning messages will be shown on stderr, and it will return: + +=over + +=item B<1> + +Syntax error (e.g. unknown option) + +=item B<2> + +Failed to init timestamp (needed to write the I<ready> file) + +=item B<3> + +Failed to create I<ready> file + +=item B<4> + +Failed to remove the I<ready> file + +=item B<10> + +Failed to sent the event on I<event> fifodir + +=back + +It can also return a value higher than 10 if more than one error occurs, e.g. 13 +if it couldn't create the I<ready> file nor emit the event, or 14 if it couldn't +remove the I<ready> file nor emit the event (Note that this doesn't occur when +the file doesn't exist, which is not treated as an error.). + +Note that 1 and 2 will always causes immediate termination, i.e. +B<aa-setready>(1) stops its execution right away (and therefore cannot return 11 +or 12). diff --git a/package/modes b/package/modes index 0eee9a1..e9045c4 100644 --- a/package/modes +++ b/package/modes @@ -8,6 +8,7 @@ aa-mvlog 0755 aa-pivot 0755 aa-reboot 0755 aa-service 0755 +aa-setready 0755 aa-shutdown 0755 aa-stage0 0755 aa-stage1 0755 diff --git a/package/targets.mak b/package/targets.mak index eb86a32..263627e 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -9,6 +9,7 @@ aa-mvlog \ aa-pivot \ aa-reboot \ aa-service \ +aa-setready \ aa-start \ aa-stop \ aa-sync \ @@ -38,6 +39,7 @@ aa-mvlog.1 \ aa-pivot.1 \ aa-reboot.1 \ aa-service.1 \ +aa-setready.1 \ aa-shutdown.1 \ aa-stage0.1 \ aa-stage1.1 \ diff --git a/src/utils/aa-setready.c b/src/utils/aa-setready.c new file mode 100644 index 0000000..20b6258 --- /dev/null +++ b/src/utils/aa-setready.c @@ -0,0 +1,114 @@ + +#include <getopt.h> +#include <errno.h> +#include <unistd.h> +#include <skalibs/strerr2.h> +#include <skalibs/djbunix.h> +#include <s6/ftrigw.h> +#include <s6/s6-supervise.h> +#include <anopa/common.h> + +extern char const *PROG; + +static void +dieusage (int rc) +{ + aa_die_usage (rc, "[OPTION] SERVICEDIR", + " -U, --ready Mark service ready; This is the default.\n" + " -D, --unready Mark service not ready\n" + "\n" + " -h, --help Show this help screen and exit\n" + " -V, --version Show version information and exit\n" + ); +} + +int +main (int argc, char * const argv[]) +{ + PROG = "aa-setready"; + int ready = 1; + int r = 0; + + for (;;) + { + struct option longopts[] = { + { "unready", no_argument, NULL, 'D' }, + { "help", no_argument, NULL, 'h' }, + { "ready", no_argument, NULL, 'U' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, 0, 0 } + }; + int c; + + c = getopt_long (argc, argv, "DhUV", longopts, NULL); + if (c == -1) + break; + switch (c) + { + case 'D': + ready = 0; + break; + + case 'h': + dieusage (0); + + case 'U': + ready = 1; + break; + + case 'V': + aa_die_version (); + + default: + dieusage (1); + } + } + argc -= optind; + argv += optind; + + if (argc != 1) + dieusage (1); + + { + int l = strlen (argv[0]); + char fifodir[l + 1 + sizeof (S6_SUPERVISE_EVENTDIR)]; + char readyfile[l + 1 + sizeof (S6_SUPERVISE_READY_FILENAME)]; + + byte_copy (fifodir, l, argv[0]); + fifodir[l] = '/'; + byte_copy (fifodir + l + 1, sizeof (S6_SUPERVISE_EVENTDIR), S6_SUPERVISE_EVENTDIR); + + byte_copy (readyfile, l, argv[0]); + readyfile[l] = '/'; + byte_copy (readyfile + l + 1, sizeof (S6_SUPERVISE_READY_FILENAME), S6_SUPERVISE_READY_FILENAME); + + if (ready) + { + char data[TAIN_PACK]; + + if (!tain_now_g()) + strerr_diefu1sys (2, "tain_now"); + tain_pack (data, &STAMP); + + if (!openwritenclose_suffix (readyfile, data, TAIN_PACK, ".new")) + { + r = 3; + strerr_warnwu2sys ("create ", readyfile); + } + } + else + if (unlink (readyfile) < 0 && errno != ENOENT) + { + r = 4; + strerr_warnwu2sys ("remove ", readyfile); + } + + if (ftrigw_notify (fifodir, (ready) ? 'U' : 'D') < 0) + { + r += 10; + strerr_warnwu4sys ("send event ", (ready) ? "U": "D" , " via ", fifodir); + } + } + + return r; +} diff --git a/src/utils/deps-exe/aa-setready b/src/utils/deps-exe/aa-setready new file mode 100644 index 0000000..9d65c4b --- /dev/null +++ b/src/utils/deps-exe/aa-setready @@ -0,0 +1,3 @@ +${LIBANOPA} +-ls6 +-lskarnet