aboutsummaryrefslogtreecommitdiff
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
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.
-rwxr-xr-xinit.d/bootmisc1
-rwxr-xr-xinit.d/checkfs1
-rwxr-xr-xinit.d/checkroot4
-rwxr-xr-xinit.d/local1
-rwxr-xr-xsh/gendepends.sh6
-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
11 files changed, 115 insertions, 73 deletions
diff --git a/init.d/bootmisc b/init.d/bootmisc
index 3ac53a22..f57a7086 100755
--- a/init.d/bootmisc
+++ b/init.d/bootmisc
@@ -29,6 +29,7 @@ depend() {
need localmount
before logger
after clock sysctl
+ keywords notimeout
}
cleanup_tmp_dir() {
diff --git a/init.d/checkfs b/init.d/checkfs
index 4174b9b4..c29c519a 100755
--- a/init.d/checkfs
+++ b/init.d/checkfs
@@ -30,6 +30,7 @@ optionally repair them."
depend() {
need checkroot
after modules
+ keywords notimeout
}
do_checkfs() {
diff --git a/init.d/checkroot b/init.d/checkroot
index 1397374a..acfb914a 100755
--- a/init.d/checkroot
+++ b/init.d/checkroot
@@ -27,6 +27,10 @@
description="Check the root filesystem according to /etc/fstab for errors \
and optionally repair them."
+depend() {
+ keywords notimeout
+}
+
do_mtab() {
# Don't create mtab if /etc is readonly
if ! printf "" 2>/dev/null >/etc/mtab; then
diff --git a/init.d/local b/init.d/local
index 461b4aff..d1c30d40 100755
--- a/init.d/local
+++ b/init.d/local
@@ -29,6 +29,7 @@ and /etc/conf.d/local.stop when stopping."
depend() {
after *
+ keywords notimeout
}
start() {
diff --git a/sh/gendepends.sh b/sh/gendepends.sh
index eac247dc..4fb2c8ed 100755
--- a/sh/gendepends.sh
+++ b/sh/gendepends.sh
@@ -45,7 +45,10 @@ after() {
}
provide() {
[ -n "$*" ] && echo "${SVCNAME} iprovide $*" >&3
-}
+}
+keywords() {
+ [ -n "$*" ] && echo "${SVCNAME} keywords $*" >&3
+}
depend() {
:
}
@@ -83,6 +86,7 @@ for SVCNAME in *; do
before ${rc_before} ${RC_BEFORE}
after ${rc_after} ${RC_AFTER}
provide ${rc_provide} ${RC_PROVIDE}
+ keywords ${rc_keywords} ${RC_KEYWORDS}
fi
)
done
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);