author | Olivier Brunel
<jjk@jjacky.com> 2015-03-15 20:06:21 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2015-04-04 12:47:36 UTC |
parent | 0d3e5ea8c32a426fe3cecc0d52c9ace4ae1ef9bf |
doc/aa-start.pod | +10 | -3 |
doc/anopa.pod | +6 | -0 |
src/anopa/start-stop.c | +19 | -2 |
src/include/anopa/service.h | +3 | -0 |
src/libanopa/exec_longrun.c | +13 | -1 |
src/libanopa/service.c | +7 | -3 |
diff --git a/doc/aa-start.pod b/doc/aa-start.pod index 2605481..f426f97 100644 --- a/doc/aa-start.pod +++ b/doc/aa-start.pod @@ -58,9 +58,16 @@ fifodir of the service, then checks (with B<s6>) if the service is already up or not. If so, it disconnects and the service is announced as already up and process continues as expected. -If not, B<aa-start>(1) sends the command to bring it up and removes the I<down> -file (if present). It then waits for event 'u' to be triggered, to (disconnect -and) announce the service as started. +If not, B<aa-start>(1) then checks whether there's a file I<gets-ready> in the +servicedir. It then sends the command to bring it up and removes the I<down> +file (if present). + +If there was no I<gets-ready> file, it waits for event 'u' to be triggered, then +(disconnects from the fifodir and) announce the service as started. If there was +one, it will then wait for event 'U' to be triggered instead, announcing the +service as ready instead. (A message will be shown on event 'u' as information +only. Note that should event 'd' occur, a message will also be shown, but +B<aa-start>(1) will still keep waiting for event 'U'.) =head1 STARTING A ONE-SHOT SERVICE diff --git a/doc/anopa.pod b/doc/anopa.pod index 2122219..9af8976 100644 --- a/doc/anopa.pod +++ b/doc/anopa.pod @@ -128,6 +128,12 @@ used to send notifications when the service goes up/down. If such a file exists, the default state of the service is considered down, not up, and it isn't automatically started by B<s6-supervise>. +=item An optional, empty, regular file named I<gets-ready> + +This is B<anopa>-specific, and if present indicates to B<aa-start>(1) that the +service supports readiness, so it will wait for event 'U' (instead of 'u') when +starting it. + =back =head2 ONE-SHOT SERVICES diff --git a/src/anopa/start-stop.c b/src/anopa/start-stop.c index 9eb052e..8795fd7 100644 --- a/src/anopa/start-stop.c +++ b/src/anopa/start-stop.c @@ -685,10 +685,27 @@ handle_longrun (aa_mode mode, uint16 id, char event) } si = list_get (&aa_main_list, i); - aa_service (si)->ft_id = 0; + if (mode == AA_MODE_START && aa_service (si)->gets_ready) + { + if (event == 'u' || event == 'd') + { + clear_draw (); + aa_bs_noflush (AA_OUT, aa_service_name (aa_service (si))); + aa_bs_noflush (AA_OUT, ": "); + aa_bs_flush (AA_OUT, (event == 'u') + ? "Started; Getting ready...\n" + : "Down; Will restart...\n"); + return 0; + } + /* event == 'U' */ + aa_unsubscribe_for (id); + } + aa_service (si)->ft_id = 0; put_title (1, aa_service_name (aa_service (si)), - (mode == AA_MODE_START) ? "Started" : "Stopped", 1); + (mode == AA_MODE_START) ? + ((aa_service (si)->gets_ready) ? "Ready" : "Started") + : "Stopped", 1); ++nb_done; --nb_wait_longrun; diff --git a/src/include/anopa/service.h b/src/include/anopa/service.h index 0e73b0d..38503c0 100644 --- a/src/include/anopa/service.h +++ b/src/include/anopa/service.h @@ -11,6 +11,7 @@ #define AA_START_FILENAME "start" #define AA_STOP_FILENAME "stop" +#define AA_GETS_READY_FILENAME "gets-ready" extern genalloc aa_services; extern stralloc aa_names; @@ -60,6 +61,7 @@ typedef struct aa_service_status st; /* longrun */ uint16 ft_id; + int gets_ready; /* oneshot */ int fd_in; int fd_out; @@ -84,5 +86,6 @@ extern int aa_prepare_mainlist (aa_prepare_cb prepare_cb, aa_exec_cb exec_cb); extern void aa_scan_mainlist (aa_scan_cb scan_cb, aa_mode mode); extern int aa_exec_service (int si, aa_mode mode); extern int aa_get_longrun_info (uint16 *id, char *event); +extern int aa_unsubscribe_for (uint16 id); #endif /* AA_SERVICE_H */ diff --git a/src/libanopa/exec_longrun.c b/src/libanopa/exec_longrun.c index 8dd0e62..c867648 100644 --- a/src/libanopa/exec_longrun.c +++ b/src/libanopa/exec_longrun.c @@ -28,7 +28,10 @@ _exec_longrun (int si, aa_mode mode) byte_copy (fifodir + l_sn + 1, sizeof (S6_SUPERVISE_EVENTDIR), S6_SUPERVISE_EVENTDIR); tain_addsec_g (&deadline, 1); - s->ft_id = ftrigr_subscribe_g (&_aa_ft, fifodir, event, 0, &deadline); + s->ft_id = ftrigr_subscribe_g (&_aa_ft, fifodir, + (is_start && s->gets_ready) ? "[udU]" : event, + (is_start && s->gets_ready) ? FTRIGR_REPEAT : 0, + &deadline); if (s->ft_id == 0) { /* this could happen e.g. if the servicedir isn't in scandir, if @@ -186,3 +189,12 @@ aa_get_longrun_info (uint16 *id, char *event) i = -1; return 0; } + +int +aa_unsubscribe_for (uint16 id) +{ + tain_t deadline; + + tain_addsec_g (&deadline, 1); + return ftrigr_unsubscribe_g (&_aa_ft, id, &deadline); +} diff --git a/src/libanopa/service.c b/src/libanopa/service.c index 76114d7..491395d 100644 --- a/src/libanopa/service.c +++ b/src/libanopa/service.c @@ -138,14 +138,13 @@ aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_load_fail_cb lf { aa_service_status *svst = &aa_service (si)->st; - struct stat st; int l_sn = strlen (aa_service_name (aa_service (si))); - char buf[l_sn + 5]; + char buf[l_sn + 1 + sizeof (AA_GETS_READY_FILENAME)]; byte_copy (buf, l_sn, aa_service_name (aa_service (si))); byte_copy (buf + l_sn, 5, "/run"); - if (stat (buf, &st) < 0) + if (access (buf, F_OK) < 0) { if (errno != ENOENT) return -ERR_IO; @@ -153,7 +152,12 @@ aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_load_fail_cb lf svst->type = AA_TYPE_ONESHOT; } else + { svst->type = AA_TYPE_LONGRUN; + + byte_copy (buf + l_sn, 1 + sizeof (AA_GETS_READY_FILENAME), "/" AA_GETS_READY_FILENAME); + aa_service (si)->gets_ready = (access (buf, F_OK) == 0) ? 1 : 0; + } } {