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.
This commit is contained in:
parent
f40f7528be
commit
0490a9290a
@ -29,6 +29,7 @@ depend() {
|
||||
need localmount
|
||||
before logger
|
||||
after clock sysctl
|
||||
keywords notimeout
|
||||
}
|
||||
|
||||
cleanup_tmp_dir() {
|
||||
|
@ -30,6 +30,7 @@ optionally repair them."
|
||||
depend() {
|
||||
need checkroot
|
||||
after modules
|
||||
keywords notimeout
|
||||
}
|
||||
|
||||
do_checkfs() {
|
||||
|
@ -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
|
||||
|
@ -29,6 +29,7 @@ and /etc/conf.d/local.stop when stopping."
|
||||
|
||||
depend() {
|
||||
after *
|
||||
keywords notimeout
|
||||
}
|
||||
|
||||
start() {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
54
src/librc.c
54
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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
13
src/rc.h
13
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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user