author | Olivier Brunel
<jjk@jjacky.com> 2015-10-16 14:02:10 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2015-11-12 17:04:19 UTC |
parent | 73dc448268120587efc65b2adb6430b9b8104091 |
doc/aa-enable.pod | +6 | -0 |
doc/aa-status.pod | +19 | -1 |
doc/aa-stop.pod | +7 | -11 |
doc/anopa.pod | +17 | -0 |
src/anopa/aa-status.c | +85 | -15 |
src/anopa/aa-stop.c | +29 | -2 |
src/include/anopa/enable_service.h | +2 | -1 |
src/libanopa/enable_service.c | +90 | -53 |
src/libanopa/exec_longrun.c | +2 | -14 |
src/libanopa/service.c | +26 | -0 |
src/libanopa/service_internal.h | +2 | -0 |
src/libanopa/service_name.c | +4 | -1 |
src/libanopa/service_start.c | +9 | -5 |
src/libanopa/service_stop.c | +8 | -3 |
diff --git a/doc/aa-enable.pod b/doc/aa-enable.pod index c9e2525..9630277 100644 --- a/doc/aa-enable.pod +++ b/doc/aa-enable.pod @@ -194,6 +194,12 @@ Note that you can also still provide files from the configuration directory in listdir, since it is copied last (and that this always includes providing a new I<run> file). +The servicedir of the logger is treated as such, meaning dependencies ("needs" +and "wants") will be auto-enabled as needed, you can remove/append to files +from the configuration directory as described below, and a file I<down> will be +created, as well as a folder I<supervise> (unless B<--no-supervise> was +specified). + Lastly, B<aa-enable>(1)'s last step when creating a servicedir is to check for a regular file I<log/run-args> in the newly created servicedir, and if found to append its content to I<log/run> diff --git a/doc/aa-status.pod b/doc/aa-status.pod index 457463f..aba0268 100644 --- a/doc/aa-status.pod +++ b/doc/aa-status.pod @@ -111,6 +111,20 @@ To only process oneshot services. To only process longrun services. +=item I<all>; I<os+lr+log> + +To process all services: oneshots, longruns, and loggers. By default, only +oneshots and longruns are shown. + +=item I<log> + +To only process loggers (i.e. I<*/log> services) + +=item I<logged>; I<lr+log> + +To only process longruns and loggers. Note that this also include longruns +without loggers. + =back =head2 Filter by status @@ -150,7 +164,7 @@ The same could be done using e.g: aa-status -Laf fail -f os -To show statues of all longrun process currently up: +To show statues of all longrun services currently up: aa-status -a -f longrun -f started @@ -159,6 +173,10 @@ both of the same kind) : aa-status -Laf longrun --filter os +To list all services, including loggers, that are up: + + aa-status -Laf all -f up + =head1 POSSIBLE STATUSES diff --git a/doc/aa-stop.pod b/doc/aa-stop.pod index 17fdafe..90f726f 100644 --- a/doc/aa-stop.pod +++ b/doc/aa-stop.pod @@ -92,19 +92,15 @@ following differences : B<aa-stop>(1) will check if the service is running, and if not simply announce it as not up. -When B<--all> is used, if the service has a logger then command 'x' will be sent -to said logger's B<s6-supervise> first, so that when the logger exits it isn't -restarted and B<s6-supervise> exits as well instead. - -Similarly, instead of 'd' the commands 'dx' are sent to the service's -B<s6-supervise>, so that after bringing the service down it exits as well. This -is obviously all intended to bring the supervised tree all down, as is expected -when using B<--all> (usually from stage 3). +When B<--all> is used, instead of 'd' the commands 'dx' are sent to the +service's B<s6-supervise>, so that after bringing the service down it exits as +well. This is obviously all intended to bring the supervised tree all down, as +is expected when using B<--all> (usually from stage 3). Note that if a service was not running, no 'x' command is sent so the -B<s6-supervise> process of the service - and of its logger, if any - are kept -running. This isn't a problem, since they'll simply exit when sending SIGTERM to -all process further down in stage 3. +B<s6-supervise> process of the service are kept running. This isn't a problem, +since they'll simply exit when sending SIGTERM to all process further down in +stage 3. =head2 Service not up diff --git a/doc/anopa.pod b/doc/anopa.pod index dc88b5a..28ef7a2 100644 --- a/doc/anopa.pod +++ b/doc/anopa.pod @@ -110,6 +110,9 @@ be logged; the I<log> service is called the service's logger. See B<aa-enable>(1) for how you can use a file instead, to automatically use the same logger for all services. +Note that by default, B<aa-status>(1) only list oneshots & longruns, excluding +such loggers. Refer to its option B<--filter> to include/list them. + =item An optional regular file named I<notification-fd> If such a file exists, it means that the service supports readiness @@ -280,6 +283,20 @@ It should also be noted that a long-run service will be considered started once the event 'u' is received; Should the service actually fail right after will have no consequences on the rest of the B<aa-start>(1) process. +=head3 Dependencies and Loggers + +Loggers (I<*/log> services) are special in that they're not in the +repodir/scandir directly, and also not listed by B<aa-status>(1) by default (See +its B<--filter> for more). + +However, they're not ignored by anopa, and every longrun service with a logger +will automatically have a dependency ("needs") on its logger. This means that +e.g. to start I<foobar>, I<foobar/log> will first be started, as expected. + +They can also contain user-defined dependencies, exactly as with any other +services. It is not, however, possible to add a dependency onto such a logger +(due to the slash in its name). + =head1 SERVICE REPOSITORY (AND SCANDIR) B<s6-svscan> will supervise all services found in its scandir. Obviously, diff --git a/src/anopa/aa-status.c b/src/anopa/aa-status.c index 403c9cf..b2749ee 100644 --- a/src/anopa/aa-status.c +++ b/src/anopa/aa-status.c @@ -36,6 +36,7 @@ #include <skalibs/djbunix.h> #include <skalibs/genalloc.h> #include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> #include <skalibs/uint.h> #include <skalibs/djbtime.h> #include <skalibs/tai.h> @@ -77,9 +78,16 @@ struct serv enum { FILTER_NONE = 0, + /* status */ FILTER_UP, FILTER_DOWN, - FILTER_ERROR + FILTER_ERROR, + /* type */ + FILTER_ONESHOT, + FILTER_LONGRUN, + FILTER_LOGGED, + FILTER_LOG, + FILTER_ALL }; enum @@ -90,7 +98,7 @@ enum static genalloc ga_serv = GENALLOC_ZERO; -static unsigned int filter_type = AA_TYPE_UNKNOWN; +static unsigned int filter_type = FILTER_NONE; static unsigned int filter_status = FILTER_NONE; static unsigned int sort_order = SORT_ASC; @@ -525,14 +533,35 @@ match_status (struct serv *serv, unsigned int filter) case AA_EVT_STOP_FAILED: return filter == FILTER_ERROR || filter == FILTER_UP; - case _AA_NB_EVT: /* silence warning */ + /* silence warnings */ + case _AA_NB_EVT: + default: + current = FILTER_NONE; break; } return current == filter; } -static void +static inline unsigned int +filter_to_type (unsigned int filter) +{ + switch (filter) + { + case FILTER_ONESHOT: + return AA_TYPE_ONESHOT; + + case FILTER_LONGRUN: + case FILTER_LOGGED: + case FILTER_LOG: + return AA_TYPE_LONGRUN; + + default: + return AA_TYPE_UNKNOWN; + } +} + +static int load_service (const char *name, struct config *cfg) { aa_service *s; @@ -543,14 +572,14 @@ load_service (const char *name, struct config *cfg) if (r < 0) { aa_put_err (name, errmsg[-r], 1); - return; + return -1; } r = aa_preload_service (serv.si); if (r < 0) { aa_put_err (name, errmsg[-r], 1); - return; + return -1; } s = aa_service (serv.si); @@ -561,11 +590,14 @@ load_service (const char *name, struct config *cfg) aa_put_err (name, "Failed to read service status file: ", 0); aa_bs_noflush (AA_ERR, error_str (e)); aa_end_err (); - return; + return -1; } - if (filter_type != AA_TYPE_UNKNOWN && s->st.type != filter_type) - return; + if (filter_type != FILTER_NONE && filter_type != FILTER_ALL + && s->st.type != filter_to_type (filter_type)) + return -1; + if (filter_type == FILTER_LOG && aa_service_name (s)[strlen (aa_service_name (s)) - 4] != '/') + return -1; if (s->st.type == AA_TYPE_LONGRUN) { @@ -578,7 +610,7 @@ load_service (const char *name, struct config *cfg) aa_put_err (name, "Unable to read s6 status: ", 0); aa_bs_noflush (AA_ERR, error_str (e)); aa_end_err (); - return; + return -1; } } else if (tain_less (&s->st.stamp, &serv.st6.stamp)) @@ -594,7 +626,7 @@ load_service (const char *name, struct config *cfg) serv.stamp = s->st.stamp; if (filter_status != FILTER_NONE && !match_status (&serv, filter_status)) - return; + return -1; if (cfg->mode == MODE_LIST) { @@ -605,14 +637,44 @@ load_service (const char *name, struct config *cfg) } genalloc_append (struct serv, &ga_serv, &serv); + return serv.si; } static int it_all (direntry *d, void *data) { + int si; + if (*d->d_name == '.' || d->d_type != DT_DIR) return 0; - load_service (d->d_name, data); + + si = load_service (d->d_name, data); + if ((filter_type == FILTER_ALL || filter_type == FILTER_LOG + || filter_type == FILTER_LOGGED) + /* si < 0 could be a error, or just that it was filtered out */ + && (si < 0 || aa_service (si)->st.type == AA_TYPE_LONGRUN)) + { + int l = satmp.len; + int ln = strlen (d->d_name); + int r; + + /* is this not a logger already? */ + if (ln < 5 || d->d_name[ln - 4] != '/') + { + stralloc_cats (&satmp, d->d_name); + stralloc_catb (&satmp, "/log/run", strlen ("/log/run") + 1); + r = access (satmp.s + l, F_OK); + if (r < 0 && (errno != ENOTDIR && errno != ENOENT)) + aa_strerr_diefu3sys (ERR_IO, "load service: access(", satmp.s + l, ")"); + else if (r == 0) + { + satmp.s[satmp.len - 5] = '\0'; + load_service (satmp.s + l, data); + } + } + satmp.len = l; + } + return 0; } @@ -628,10 +690,18 @@ it_listdir (direntry *d, void *data) static int set_filter (const char *filter) { + /* type */ if (str_equal (filter, "os") || str_equal (filter, "oneshot")) - filter_type = AA_TYPE_ONESHOT; + filter_type = FILTER_ONESHOT; else if (str_equal (filter, "lr") || str_equal (filter, "longrun")) - filter_type = AA_TYPE_LONGRUN; + filter_type = FILTER_LONGRUN; + else if (str_equal (filter, "all") || str_equal (filter, "os+lr+log")) + filter_type = FILTER_ALL; + else if (str_equal (filter, "log")) + filter_type = FILTER_LOG; + else if (str_equal (filter, "logged") || str_equal (filter, "lr+log")) + filter_type = FILTER_LOGGED; + /* status */ else if (str_equal (filter, "up") || str_equal (filter, "start") || str_equal (filter, "started")) filter_status = FILTER_UP; @@ -688,7 +758,7 @@ dieusage (int rc) " -l, --listdir DIR Use DIR to list services to get status of\n" " -a, --all Show status of all services\n" " -f, --filter FILTER Only process services matching FILTER, one of:\n" - " oneshot, longrun, up, down, error (see aa-status(1) for more)\n" + " oneshot, longrun, log, logged, all, up, down, error (see aa-status(1) for more)\n" " -s, --sort SORT Sort by SORT, one of: none, name, time (default)\n" " -R, --reverse Reverse sort order\n" " -N, --name Sort by name\n" diff --git a/src/anopa/aa-stop.c b/src/anopa/aa-stop.c index 5a1a02f..330fef9 100644 --- a/src/anopa/aa-stop.c +++ b/src/anopa/aa-stop.c @@ -31,6 +31,7 @@ #include <skalibs/bytestr.h> #include <skalibs/direntry.h> #include <skalibs/genalloc.h> +#include <skalibs/skamisc.h> #include <skalibs/error.h> #include <skalibs/uint.h> #include <skalibs/tai.h> @@ -80,8 +81,8 @@ preload_service (const char *name) r = aa_ensure_service_loaded (si, AA_MODE_STOP, 0, NULL); if (r < 0) { - /* there should be much errors possible here... basically only ERR_IO or - * ERR_NOT_UP should be possible, and the later should be silently + /* there shouldn't be much errors possible here... basically only ERR_IO + * or ERR_NOT_UP should be possible, and the later should be silently * ignored... so: */ if (r == -ERR_IO) { @@ -102,6 +103,32 @@ preload_service (const char *name) } } + /* r < 0 can mean different things (e.g. ERR_NOT_UP), including that we + * don't have a type set. Hence we only rely on it when possible, but we + * need to always check for a logger */ + if (r < 0 || aa_service (si)->st.type == AA_TYPE_LONGRUN) + { + int l = satmp.len; + + /* for longruns, even though the dependency of the logger is auto-added, + * we still need to ensure the service is loaded */ + stralloc_cats (&satmp, name); + /* is this not a logger already? */ + if (satmp.len - l < 5 || satmp.s[satmp.len - 4] != '/') + { + stralloc_catb (&satmp, "/log/run", strlen ("/log/run") + 1); + r = access (satmp.s + l, F_OK); + if (r < 0 && (errno != ENOTDIR && errno != ENOENT)) + aa_strerr_diefu3sys (ERR_IO, "preload services: access(", satmp.s + l, ")"); + else if (r == 0) + { + satmp.s[satmp.len - 5] = '\0'; + preload_service (satmp.s + l); + } + } + satmp.len = l; + } + return 0; } diff --git a/src/include/anopa/enable_service.h b/src/include/anopa/enable_service.h index 62c5d9a..322c106 100644 --- a/src/include/anopa/enable_service.h +++ b/src/include/anopa/enable_service.h @@ -36,7 +36,8 @@ typedef enum /* private */ _AA_FLAG_IS_SERVICEDIR = (1 << 5), _AA_FLAG_IS_CONFIGDIR = (1 << 6), - _AA_FLAG_IS_1OF4 = (1 << 7) + _AA_FLAG_IS_1OF4 = (1 << 7), + _AA_FLAG_IS_LOGGER = (1 << 8) } aa_enable_flags; extern stralloc aa_sa_sources; diff --git a/src/libanopa/enable_service.c b/src/libanopa/enable_service.c index ff4e5c0..762138a 100644 --- a/src/libanopa/enable_service.c +++ b/src/libanopa/enable_service.c @@ -56,9 +56,17 @@ copy_dir (const char *src, aa_auto_enable_cb ae_cb, const char *instance); +static int +do_auto_needs_wants (const char *name, aa_enable_flags flags, aa_auto_enable_cb ae_cb); + static int -copy_log (const char *name, const char *cfg, mode_t mode, aa_warn_fn warn_fn) +copy_log (const char *name, + const char *cfg, + mode_t mode, + aa_warn_fn warn_fn, + aa_enable_flags flags, + aa_auto_enable_cb ae_cb) { int fd; int r; @@ -79,13 +87,18 @@ copy_log (const char *name, const char *cfg, mode_t mode, aa_warn_fn warn_fn) return r; } + flags |= _AA_FLAG_IS_LOGGER; + /* this is a logger, so there's no autoenable of any kind; hence we can use * 0 for flags (don't process it as a servicedir either, since it doesn't * apply) and not bother with a callback */ - r = copy_from_source ("log", 3, warn_fn, 0, NULL); + r = copy_from_source ("log", 3, warn_fn, flags | _AA_FLAG_IS_SERVICEDIR, NULL); if (r >= 0 && cfg) - r = copy_dir (cfg, "log", mode, 0, warn_fn, 0, NULL, NULL); + r = copy_dir (cfg, "log", mode, 0, warn_fn, flags | _AA_FLAG_IS_CONFIGDIR, NULL, NULL); + + if (r >= 0 && ae_cb && flags & (AA_FLAG_AUTO_ENABLE_NEEDS | AA_FLAG_AUTO_ENABLE_WANTS)) + r = do_auto_needs_wants ("log", flags, ae_cb); e = errno; fd_chdir (fd); @@ -251,13 +264,23 @@ copy_dir (const char *src, == (_AA_FLAG_IS_SERVICEDIR | AA_FLAG_UPGRADE_SERVICEDIR)) { if (stat (dst, &st) < 0) - goto err; + { + /* logger might be new */ + if ((flags & _AA_FLAG_IS_LOGGER) && errno == ENOENT) + { + if (mkdir (dst, S_IRWXU) < 0) + goto err; + } + else + goto err; + } else if (!S_ISDIR (st.st_mode)) { errno = ENOTDIR; goto err; } - else if (clear_dir (dst, 1, warn_fn) < 0) + /* logger: was already cleared when processing main servicedir */ + else if (!(flags & _AA_FLAG_IS_LOGGER) && clear_dir (dst, 1, warn_fn) < 0) goto err; } else @@ -315,9 +338,10 @@ copy_dir (const char *src, if (S_ISREG (st.st_mode)) { - if (has.began && depth == 0 && str_equal (satmp.s + i, "log")) + if (has.began && depth == 0 && !(flags & _AA_FLAG_IS_LOGGER) + && str_equal (satmp.s + i, "log")) { - r = copy_log (dst, NULL, 0, warn_fn); + r = copy_log (dst, NULL, 0, warn_fn, flags, ae_cb); st.st_mode = 0755; } else if ((flags & _AA_FLAG_IS_CONFIGDIR) && len > 1 @@ -356,8 +380,9 @@ copy_dir (const char *src, } else if (S_ISDIR (st.st_mode)) { - if (has.began && depth == 0 && str_equal (satmp.s + i, "log")) - r = copy_log (dst, buf_src, st.st_mode, warn_fn); + if (has.began && depth == 0 && !(flags & _AA_FLAG_IS_LOGGER) + && str_equal (satmp.s + i, "log")) + r = copy_log (dst, buf_src, st.st_mode, warn_fn, flags, ae_cb); else { /* use depth because this is also enabled for the config part */ @@ -433,6 +458,7 @@ next: fd_close (fd); } + if (!(flags & _AA_FLAG_IS_LOGGER)) { char buf_lnk[3 + l_dst + 1]; char buf_dst[sizeof (AA_SCANDIR_DIRNAME) + l_dst + 1]; @@ -558,6 +584,60 @@ it_cb (direntry *d, void *_data) return 0; } +static int +do_auto_needs_wants (const char *name, aa_enable_flags flags, aa_auto_enable_cb ae_cb) +{ + stralloc sa = STRALLOC_ZERO; + struct { + aa_auto_enable_cb cb; + unsigned int flag; + } data = { .cb = ae_cb }; + int l_name = strlen (name); + int r = 0; + + if (!stralloc_catb (&sa, name, l_name)) + { + errno = ENOMEM; + return -1; + } + + if (flags & AA_FLAG_AUTO_ENABLE_NEEDS) + { + if (!stralloc_cats (&sa, "/needs") || !stralloc_0 (&sa)) + { + stralloc_free (&sa); + errno = ENOMEM; + return -1; + } + data.flag = AA_FLAG_AUTO_ENABLE_NEEDS; + r = aa_scan_dir (&sa, 1, it_cb, &data); + if (r == -ERR_IO && errno == ENOENT) + r = 0; + sa.len = l_name; + } + + if (r == 0 && flags & AA_FLAG_AUTO_ENABLE_WANTS) + { + if (!stralloc_cats (&sa, "/wants") || !stralloc_0 (&sa)) + { + stralloc_free (&sa); + errno = ENOMEM; + return -1; + } + data.flag = AA_FLAG_AUTO_ENABLE_WANTS; + r = aa_scan_dir (&sa, 1, it_cb, &data); + if (r == -ERR_IO && errno == ENOENT) + r = 0; + } + + { + int e = errno; + stralloc_free (&sa); + errno = e; + } + return r; +} + int aa_enable_service (const char *_name, aa_warn_fn warn_fn, @@ -645,50 +725,7 @@ aa_enable_service (const char *_name, } if (ae_cb && flags & (AA_FLAG_AUTO_ENABLE_NEEDS | AA_FLAG_AUTO_ENABLE_WANTS)) - { - stralloc sa = STRALLOC_ZERO; - struct { - aa_auto_enable_cb cb; - unsigned int flag; - } data = { .cb = ae_cb }; - - if (!stralloc_catb (&sa, name, l_name)) - { - errno = ENOMEM; - return -1; - } - - if (flags & AA_FLAG_AUTO_ENABLE_NEEDS) - { - if (!stralloc_cats (&sa, "/needs") || !stralloc_0 (&sa)) - { - stralloc_free (&sa); - errno = ENOMEM; - return -1; - } - data.flag = AA_FLAG_AUTO_ENABLE_NEEDS; - r = aa_scan_dir (&sa, 1, it_cb, &data); - if (r == -ERR_IO && errno == ENOENT) - r = 0; - sa.len = l_name; - } - - if (r == 0 && flags & AA_FLAG_AUTO_ENABLE_WANTS) - { - if (!stralloc_cats (&sa, "/wants") || !stralloc_0 (&sa)) - { - stralloc_free (&sa); - errno = ENOMEM; - return -1; - } - data.flag = AA_FLAG_AUTO_ENABLE_WANTS; - r = aa_scan_dir (&sa, 1, it_cb, &data); - if (r == -ERR_IO && errno == ENOENT) - r = 0; - } - - stralloc_free (&sa); - } + r = do_auto_needs_wants (name, flags, ae_cb); return r; } diff --git a/src/libanopa/exec_longrun.c b/src/libanopa/exec_longrun.c index e426f35..f8f43cf 100644 --- a/src/libanopa/exec_longrun.c +++ b/src/libanopa/exec_longrun.c @@ -89,13 +89,13 @@ _exec_longrun (int si, aa_mode mode) aa_strerr_warnu2sys ("write service status file for ", aa_service_name (s)); /* we still process it. Because we checked the service state (from s6) - * before adding it to the "treansaction" (i.e. in + * before adding it to the "transaction" (i.e. in * aa_ensure_service_loaded()) and it wasn't there already. * IOW this is likely e.g. that it crashed since then, but it isn't * really down, or something. So make sure we do send the request to * s6-supervise, so it isn't restarted, or indeed brought down if it's * happening right now. Also in STOP_ALL this sends the 'x' event to - * both supervise (logger & service) as needed as well. + * s6-supervise as needed as well. */ } else @@ -117,18 +117,6 @@ _exec_longrun (int si, aa_mode mode) } } - if (mode & AA_MODE_STOP_ALL) - { - char dir[l_sn + 5 + sizeof (S6_SUPERVISE_CTLDIR) + 8]; - - byte_copy (dir, l_sn, aa_service_name (s)); - byte_copy (dir + l_sn, 13 + sizeof (S6_SUPERVISE_CTLDIR), "/log/" S6_SUPERVISE_CTLDIR "/control"); - - /* ignore any error, starting with the fact that there might not be a - * logger for this service */ - s6_svc_write (dir, "x", 1); - } - { char dir[l_sn + 1 + sizeof (S6_SUPERVISE_CTLDIR) + 8]; int r; diff --git a/src/libanopa/service.c b/src/libanopa/service.c index 68b9613..34e9c8a 100644 --- a/src/libanopa/service.c +++ b/src/libanopa/service.c @@ -292,6 +292,32 @@ aa_ensure_service_loaded (int si, aa_mode mode, int no_wants, aa_load_fail_cb lf stralloc_cats (&sa, aa_service_name (aa_service (si))); + /* special case: for a longrun that's not a logger, we check if it has one, + * and if so auto-add needs & after on said logger */ + if (aa_service (si)->st.type == AA_TYPE_LONGRUN + /* because sa.s is the service name, and the only slashes allowed + * are for loggers, i.e. xxxx/log */ + && (sa.len < 5 || sa.s[sa.len - 4] != '/')) + { + stralloc_catb (&sa, "/log/run", strlen ("/log/run") + 1); + r = access (sa.s, F_OK); + if (r < 0 && (errno != ENOTDIR && errno != ENOENT)) + goto err; + + if (r == 0) + { + sa.s[sa.len - 5] = '\0'; + if (mode & AA_MODE_START) + r = _name_start_needs (sa.s, &it_data); + else + r = _name_stop_needs (sa.s, &it_data); + if (r < 0) + goto err; + } + + sa.len -= strlen ("/log/run") + 1; + } + stralloc_catb (&sa, "/needs", strlen ("/needs") + 1); r = aa_scan_dir (&sa, 1, (mode & AA_MODE_START) ? _it_start_needs : _it_stop_needs, diff --git a/src/libanopa/service_internal.h b/src/libanopa/service_internal.h index e173bb3..a2d5ab6 100644 --- a/src/libanopa/service_internal.h +++ b/src/libanopa/service_internal.h @@ -39,11 +39,13 @@ struct it_data extern int _is_valid_service_name (const char *name, int len); +extern int _name_start_needs (const char *name, struct it_data *it_data); extern int _it_start_needs (direntry *d, void *data); extern int _it_start_wants (direntry *d, void *data); extern int _it_start_after (direntry *d, void *data); extern int _it_start_before (direntry *d, void *data); +extern int _name_stop_needs (const char *name, struct it_data *it_data); extern int _it_stop_needs (direntry *d, void *data); extern int _it_stop_after (direntry *d, void *data); extern int _it_stop_before (direntry *d, void *data); diff --git a/src/libanopa/service_name.c b/src/libanopa/service_name.c index 32bad28..f81fe95 100644 --- a/src/libanopa/service_name.c +++ b/src/libanopa/service_name.c @@ -25,13 +25,16 @@ int _is_valid_service_name (const char *name, int len) { + int r; + if (len <= 0) return 0; if (name[0] == '.') return 0; if (name[0] == '@' || name[len - 1] == '@') return 0; - if (byte_chr (name, len, '/') < len) + r = byte_chr (name, len, '/'); + if (r < len && !str_equal (name + r, "/log")) return 0; return 1; } diff --git a/src/libanopa/service_start.c b/src/libanopa/service_start.c index 4bac929..7a558d9 100644 --- a/src/libanopa/service_start.c +++ b/src/libanopa/service_start.c @@ -73,15 +73,14 @@ aa_mark_service (aa_mode mode, int si, int in_main, int no_wants, aa_load_fail_c } int -_it_start_needs (direntry *d, void *data) +_name_start_needs (const char *name, struct it_data *it_data) { - struct it_data *it_data = data; int type; int sni; int r; tain_now_g (); - type = aa_get_service (d->d_name, &sni, 1); + type = aa_get_service (name, &sni, 1); if (type < 0) r = type; else @@ -100,7 +99,6 @@ _it_start_needs (direntry *d, void *data) if (!(it_data->mode & AA_MODE_IS_DRY)) { - const char *name = d->d_name; int l_n = strlen (name); int l_em = strlen (errmsg[-r]); char buf[l_n + 2 + l_em + 1]; @@ -115,7 +113,7 @@ _it_start_needs (direntry *d, void *data) } if (it_data->lf_cb) - it_data->lf_cb (it_data->si, AA_LOADFAIL_NEEDS, d->d_name, -r); + it_data->lf_cb (it_data->si, AA_LOADFAIL_NEEDS, name, -r); return -ERR_DEPEND; } @@ -125,6 +123,12 @@ _it_start_needs (direntry *d, void *data) return 0; } +int +_it_start_needs (direntry *d, void *data) +{ + return _name_start_needs (d->d_name, (struct it_data *) data); +} + int _it_start_wants (direntry *d, void *data) { diff --git a/src/libanopa/service_stop.c b/src/libanopa/service_stop.c index 6564144..84e9f52 100644 --- a/src/libanopa/service_stop.c +++ b/src/libanopa/service_stop.c @@ -26,14 +26,13 @@ #include "service_internal.h" int -_it_stop_needs (direntry *d, void *data) +_name_stop_needs (const char *name, struct it_data *it_data) { - struct it_data *it_data = data; int sni; int r; tain_now_g (); - r = aa_get_service (d->d_name, &sni, 0); + r = aa_get_service (name, &sni, 0); if (r < 0) return 0; @@ -42,6 +41,12 @@ _it_stop_needs (direntry *d, void *data) return 0; } +int +_it_stop_needs (direntry *d, void *data) +{ + return _name_stop_needs (d->d_name, (struct it_data *) data); +} + int _it_stop_after (direntry *d, void *data) {