diff options
author | Roy Marples <roy@marples.name> | 2007-12-05 17:48:07 +0000 |
---|---|---|
committer | Roy Marples <roy@marples.name> | 2007-12-05 17:48:07 +0000 |
commit | 0490a9290a6af4a4923cc79fd380bc00a0a702e3 (patch) | |
tree | 5848bf69e4dc0357cc092ed30c974d20154c6469 /src | |
parent | f40f7528be64269af7a5401af95dd37d398a5b31 (diff) |
Remove rc_service_wait as runscript.c should do the waiting. rc_deptree_depend now returns the exact depends as listed. This is so we can support a new 'keywords' directive. We can add whatever here, like 'notimeout' which means that an init script doesn't timeout. This removes the hardcoded check on checkfs and checkroot.
Diffstat (limited to 'src')
-rw-r--r-- | src/librc-depend.c | 26 | ||||
-rw-r--r-- | src/librc.c | 54 | ||||
-rw-r--r-- | src/librc.h | 2 | ||||
-rw-r--r-- | src/rc.h | 13 | ||||
-rw-r--r-- | src/rc.map | 2 | ||||
-rw-r--r-- | src/runscript.c | 78 |
6 files changed, 103 insertions, 72 deletions
diff --git a/src/librc-depend.c b/src/librc-depend.c index 5f0cacbb..ee6c79b7 100644 --- a/src/librc-depend.c +++ b/src/librc-depend.c @@ -467,10 +467,34 @@ static void visit_service (rc_depinfo_t *deptree, const char * const *types, rc_strlist_add (&sorted->list, depinfo->service); } +char **rc_deptree_depend (rc_depinfo_t *deptree, + const char *service, const char *type) +{ + rc_depinfo_t *di; + rc_deptype_t *dt; + char **svcs = NULL; + int i; + char *svc; + + if (! (di = get_depinfo (deptree, service)) || + ! (dt = get_deptype (di, type))) + { + errno = ENOENT; + return (NULL); + } + + /* For consistency, we copy the array */ + STRLIST_FOREACH (dt->services, svc, i) + rc_strlist_add (&svcs, svc); + + return (svcs); +} +librc_hidden_def(rc_deptree_depend) + char **rc_deptree_depends (rc_depinfo_t *deptree, const char **types, const char **services, const char *runlevel, int options) -{ +{ struct lhead sorted; struct lhead visited; rc_depinfo_t *di; diff --git a/src/librc.c b/src/librc.c index 0fdf6e09..e429318b 100644 --- a/src/librc.c +++ b/src/librc.c @@ -35,14 +35,6 @@ const char copyright[] = "Copyright (c) 2007 Gentoo Foundation\n" #include "librc.h" -/* usecs to wait while we poll the fifo */ -#define WAIT_INTERVAL 20000000 - -/* max secs to wait until a service comes up */ -#define WAIT_MAX 300 - -#define ONE_SECOND 1000000000 - #define SOFTLEVEL RC_SVCDIR "/softlevel" #ifndef S_IXUGO @@ -719,52 +711,6 @@ bool rc_service_schedule_clear (const char *service) } librc_hidden_def(rc_service_schedule_clear) -bool rc_service_wait (const char *service) -{ - char *svc; - char *base; - char *fifo; - struct timespec ts; - int nloops = WAIT_MAX * (ONE_SECOND / WAIT_INTERVAL); - bool retval = false; - bool forever = false; - - if (! service) - return (false); - - svc = xstrdup (service); - base = basename (svc); - fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL); - /* FIXME: find a better way of doing this - * Maybe a setting in the init script? */ - if (strcmp (base, "checkfs") == 0 || strcmp (base, "checkroot") == 0) - forever = true; - free (svc); - - ts.tv_sec = 0; - ts.tv_nsec = WAIT_INTERVAL; - - while (nloops) { - if (! exists (fifo)) { - retval = true; - break; - } - - if (nanosleep (&ts, NULL) == -1) { - if (errno != EINTR) - break; - } - - if (! forever) - nloops --; - } - - if (! exists (fifo)) - retval = true; - free (fifo); - return (retval); -} -librc_hidden_def(rc_service_wait) char **rc_services_in_runlevel (const char *runlevel) { diff --git a/src/librc.h b/src/librc.h index de035fd0..f3ebd596 100644 --- a/src/librc.h +++ b/src/librc.h @@ -76,6 +76,7 @@ librc_hidden_proto(rc_config_list) librc_hidden_proto(rc_config_load) librc_hidden_proto(rc_config_value) +librc_hidden_proto(rc_deptree_depend) librc_hidden_proto(rc_deptree_depends) librc_hidden_proto(rc_deptree_free) librc_hidden_proto(rc_deptree_load) @@ -104,7 +105,6 @@ librc_hidden_proto(rc_service_schedule_clear) librc_hidden_proto(rc_service_schedule_start) librc_hidden_proto(rc_service_start) librc_hidden_proto(rc_service_stop) -librc_hidden_proto(rc_service_wait) librc_hidden_proto(rc_services_in_runlevel) librc_hidden_proto(rc_services_in_state) librc_hidden_proto(rc_services_scheduled) @@ -211,11 +211,6 @@ char *rc_service_value_get (const char *service, const char *option); bool rc_service_value_set (const char *service, const char *option, const char *value); -/*! Wait for a service to finish - * @param service to wait for - * @return true if service finished before timeout, otherwise false */ -bool rc_service_wait (const char *service); - /*! List the services in a runlevel * @param runlevel to list * @return NULL terminated list of services */ @@ -275,6 +270,14 @@ bool rc_deptree_update_needed (void); * @return pointer to the dependency tree */ rc_depinfo_t *rc_deptree_load (void); +/*! List the depend for the type of service + * @param deptree to search + * @param type to use (keywords, etc) + * @param service to check + * @return NULL terminated list of services in order */ +char **rc_deptree_depend (rc_depinfo_t *deptree, + const char *type, const char *service); + /*! List all the services in order that the given services have * for the given types and options. * @param deptree to search @@ -3,6 +3,7 @@ global: rc_config_list; rc_config_load; rc_config_value; + rc_deptree_depend; rc_deptree_depends; rc_deptree_free; rc_deptree_load; @@ -32,7 +33,6 @@ global: rc_service_schedule_start; rc_service_start; rc_service_stop; - rc_service_wait; rc_services_in_runlevel; rc_services_in_state; rc_services_scheduled; diff --git a/src/runscript.c b/src/runscript.c index e58b1ed0..f81db232 100644 --- a/src/runscript.c +++ b/src/runscript.c @@ -68,6 +68,14 @@ #define PREFIX_LOCK RC_SVCDIR "/prefix.lock" +/* usecs to wait while we poll the fifo */ +#define WAIT_INTERVAL 20000000 + +/* max secs to wait until a service comes up */ +#define WAIT_MAX 300 + +#define ONE_SECOND 1000000000 + static char *applet = NULL; static char *service = NULL; static char *exclusive = NULL; @@ -98,7 +106,6 @@ static const char *types_b[] = { "broken", NULL }; static const char *types_n[] = { "ineed", NULL }; static const char *types_nu[] = { "ineed", "iuse", NULL }; static const char *types_nua[] = { "ineed", "iuse", "iafter", NULL }; -static const char *types_p[] = { "iprovide", NULL }; static const char *types_m[] = { "needsme", NULL }; static const char *types_mua[] = { "needsme", "usesme", "beforeme", NULL }; @@ -492,6 +499,60 @@ static bool svc_exec (const char *arg1, const char *arg2) return (execok); } +static bool svc_wait (rc_depinfo_t *depinfo, const char *svc) +{ + char *s; + char *base; + char *fifo; + struct timespec ts; + int nloops = WAIT_MAX * (ONE_SECOND / WAIT_INTERVAL); + bool retval = false; + bool forever = false; + char **keywords = NULL; + int i; + + if (! service) + return (false); + + /* Some services don't have a timeout, like checkroot and checkfs */ + keywords = rc_deptree_depend (deptree, svc, "keywords"); + STRLIST_FOREACH (keywords, s, i) { + if (strcmp (s, "notimeout") == 0) { + forever = true; + break; + } + } + rc_strlist_free (keywords); + + s = xstrdup (svc); + base = basename (s); + fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL); + free (s); + + ts.tv_sec = 0; + ts.tv_nsec = WAIT_INTERVAL; + + while (nloops) { + if (! exists (fifo)) { + retval = true; + break; + } + + if (nanosleep (&ts, NULL) == -1) { + if (errno != EINTR) + break; + } + + if (! forever) + nloops --; + } + + if (! exists (fifo)) + retval = true; + free (fifo); + return (retval); +} + static rc_service_state_t svc_status () { char status[10]; @@ -683,7 +744,7 @@ static void svc_start (bool deps) continue; } - if (! rc_service_wait (svc)) + if (! svc_wait (deptree, svc)) eerror ("%s: timed out waiting for %s", applet, svc); if ((svcs = rc_service_state (svc)) & RC_SERVICE_STARTED) continue; @@ -710,12 +771,9 @@ static void svc_start (bool deps) unlink_mtime_test (); STRLIST_FOREACH (tmplist, svc, i) { - const char *sl[] = { svc, NULL }; rc_service_schedule_start (svc, service); - rc_strlist_free (providelist); - providelist = rc_deptree_depends (deptree, types_p, sl, - softlevel, depoptions); + providelist = rc_deptree_depend (deptree, "iprovide", svc); STRLIST_FOREACH (providelist, svc2, j) rc_service_schedule_start (svc2, service); @@ -780,7 +838,7 @@ static void svc_start (bool deps) /* Do the same for any services we provide */ rc_strlist_free (tmplist); - tmplist = rc_deptree_depends (deptree, types_p, svcl, softlevel, depoptions); + tmplist = rc_deptree_depend (deptree, "iprovide", applet); STRLIST_FOREACH (tmplist, svc2, j) { rc_strlist_free (services); @@ -853,7 +911,7 @@ static void svc_stop (bool deps) if (svcs & RC_SERVICE_STARTED || svcs & RC_SERVICE_INACTIVE) { - rc_service_wait (svc); + svc_wait (deptree, svc); svcs = rc_service_state (svc); if (svcs & RC_SERVICE_STARTED || svcs & RC_SERVICE_INACTIVE) @@ -873,7 +931,7 @@ static void svc_stop (bool deps) continue; /* We used to loop 3 times here - maybe re-do this if needed */ - rc_service_wait (svc); + svc_wait (deptree, svc); if (! (rc_service_state (svc) & RC_SERVICE_STOPPED)) { if (rc_runlevel_stopping ()) { /* If shutting down, we should stop even if a dependant failed */ @@ -899,7 +957,7 @@ static void svc_stop (bool deps) STRLIST_FOREACH (services, svc, i) { if (rc_service_state (svc) & RC_SERVICE_STOPPED) continue; - rc_service_wait (svc); + svc_wait (deptree, svc); } rc_strlist_free (services); |