aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2007-12-05 17:48:07 +0000
committerRoy Marples <roy@marples.name>2007-12-05 17:48:07 +0000
commit0490a9290a6af4a4923cc79fd380bc00a0a702e3 (patch)
tree5848bf69e4dc0357cc092ed30c974d20154c6469 /src
parentf40f7528be64269af7a5401af95dd37d398a5b31 (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.c26
-rw-r--r--src/librc.c54
-rw-r--r--src/librc.h2
-rw-r--r--src/rc.h13
-rw-r--r--src/rc.map2
-rw-r--r--src/runscript.c78
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)
diff --git a/src/rc.h b/src/rc.h
index 8d5f32ea..6a53e7ce 100644
--- a/src/rc.h
+++ b/src/rc.h
@@ -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
diff --git a/src/rc.map b/src/rc.map
index b487b663..e5f8ee34 100644
--- a/src/rc.map
+++ b/src/rc.map
@@ -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);