rc_service_state now returns the state as a mask, which means that we can do things with just the one call making is more efficient.

This commit is contained in:
Roy Marples
2007-09-28 14:53:38 +00:00
parent befddaf241
commit 7274301be2
7 changed files with 136 additions and 140 deletions

View File

@ -3,6 +3,8 @@
28 Sep 2007; Roy Marples <uberlord@gentoo.org>: 28 Sep 2007; Roy Marples <uberlord@gentoo.org>:
rc_service_state now returns the state as a mask, which means that
we can do things with just the one call making is more efficient.
keymaps now sets unicode keyboard on all defined ttys, #192442 keymaps now sets unicode keyboard on all defined ttys, #192442
thanks to Pacho Ramos. thanks to Pacho Ramos.
net.sh now checks to see if root is net mounted if no predown function net.sh now checks to see if root is net mounted if no predown function

View File

@ -184,11 +184,13 @@ librc_hidden_def(rc_get_deptype)
static bool valid_service (const char *runlevel, const char *service) static bool valid_service (const char *runlevel, const char *service)
{ {
rc_service_state_t state = rc_service_state (service);
return ((strcmp (runlevel, bootlevel) != 0 && return ((strcmp (runlevel, bootlevel) != 0 &&
rc_service_in_runlevel (service, bootlevel)) || rc_service_in_runlevel (service, bootlevel)) ||
rc_service_in_runlevel (service, runlevel) || rc_service_in_runlevel (service, runlevel) ||
rc_service_state (service, RC_SERVICE_COLDPLUGGED) || state & RC_SERVICE_COLDPLUGGED ||
rc_service_state (service, RC_SERVICE_STARTED)); state & RC_SERVICE_STARTED);
} }
static bool get_provided1 (const char *runlevel, struct lhead *providers, static bool get_provided1 (const char *runlevel, struct lhead *providers,
@ -203,10 +205,11 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
STRLIST_FOREACH (deptype->services, service, i) STRLIST_FOREACH (deptype->services, service, i)
{ {
bool ok = true; bool ok = true;
rc_service_state_t s = rc_service_state (service);
if (level) if (level)
ok = rc_service_in_runlevel (service, level); ok = rc_service_in_runlevel (service, level);
else if (coldplugged) else if (coldplugged)
ok = (rc_service_state (service, RC_SERVICE_COLDPLUGGED) && ok = (s & RC_SERVICE_COLDPLUGGED &&
! rc_service_in_runlevel (service, runlevel) && ! rc_service_in_runlevel (service, runlevel) &&
! rc_service_in_runlevel (service, bootlevel)); ! rc_service_in_runlevel (service, bootlevel));
@ -215,14 +218,14 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
switch (state) { switch (state) {
case RC_SERVICE_STARTED: case RC_SERVICE_STARTED:
ok = rc_service_state (service, state); ok = (s & RC_SERVICE_STARTED);
break; break;
case RC_SERVICE_INACTIVE: case RC_SERVICE_INACTIVE:
case RC_SERVICE_STARTING: case RC_SERVICE_STARTING:
case RC_SERVICE_STOPPING: case RC_SERVICE_STOPPING:
ok = (rc_service_state (service, RC_SERVICE_STARTING) || ok = (s & RC_SERVICE_STARTING ||
rc_service_state (service, RC_SERVICE_STOPPING) || s & RC_SERVICE_STOPPING ||
rc_service_state (service, RC_SERVICE_INACTIVE)); s & RC_SERVICE_INACTIVE);
break; break;
default: default:
break; break;

View File

@ -23,6 +23,8 @@ typedef struct rc_service_state_name {
const char *name; const char *name;
} rc_service_state_name_t; } rc_service_state_name_t;
/* We MUST list the states below 0x10 first
* The rest can be in any order */
static const rc_service_state_name_t rc_service_state_names[] = { static const rc_service_state_name_t rc_service_state_names[] = {
{ RC_SERVICE_STARTED, "started" }, { RC_SERVICE_STARTED, "started" },
{ RC_SERVICE_STOPPED, "stopped" }, { RC_SERVICE_STOPPED, "stopped" },
@ -428,43 +430,39 @@ bool rc_mark_service (const char *service, const rc_service_state_t state)
} }
librc_hidden_def(rc_mark_service) librc_hidden_def(rc_mark_service)
bool rc_service_state (const char *service, const rc_service_state_t state) rc_service_state_t rc_service_state (const char *service)
{ {
char *file; int i;
bool retval; int state = RC_SERVICE_STOPPED;
char *svc; char *svc = rc_xstrdup (service);
/* If the init script does not exist then we are stopped */ for (i = 0; rc_service_state_names[i].name; i++) {
if (! rc_service_exists (service)) char *file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[i].name,
return (state == RC_SERVICE_STOPPED ? true : false); basename (svc), (char*) NULL);
if (rc_exists (file)) {
if (rc_service_state_names[i].state <= 0x10)
state = rc_service_state_names[i].state;
else
state |= rc_service_state_names[i].state;
}
free (file);
}
free (svc);
/* We check stopped state by not being in any of the others */ if (state & RC_SERVICE_STOPPED) {
if (state == RC_SERVICE_STOPPED)
return ( ! (rc_service_state (service, RC_SERVICE_STARTED) ||
rc_service_state (service, RC_SERVICE_STARTING) ||
rc_service_state (service, RC_SERVICE_STOPPING) ||
rc_service_state (service, RC_SERVICE_INACTIVE)));
/* The crashed state and scheduled states are virtual */
if (state == RC_SERVICE_CRASHED)
return (rc_service_daemons_crashed (service));
else if (state == RC_SERVICE_SCHEDULED) {
char **services = rc_services_scheduled_by (service); char **services = rc_services_scheduled_by (service);
retval = (services); if (services) {
if (services) state |= RC_SERVICE_SCHEDULED;
free (services); free (services);
return (retval); }
} }
/* Now we just check if a file by the service name rc_exists if (state & RC_SERVICE_STARTED && geteuid () == 0) {
in the state dir */ if (rc_service_daemons_crashed (service))
svc = rc_xstrdup (service); state |= RC_SERVICE_CRASHED;
file = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (state), }
basename (svc), (char*) NULL);
free (svc); return (state);
retval = rc_exists (file);
free (file);
return (retval);
} }
librc_hidden_def(rc_service_state) librc_hidden_def(rc_service_state)
@ -585,7 +583,7 @@ librc_hidden_def(rc_waitpid)
pid_t rc_stop_service (const char *service) pid_t rc_stop_service (const char *service)
{ {
if (rc_service_state (service, RC_SERVICE_STOPPED)) if (rc_service_state (service) & RC_SERVICE_STOPPED)
return (0); return (0);
return (_exec_service (service, "stop")); return (_exec_service (service, "stop"));
@ -594,7 +592,7 @@ librc_hidden_def(rc_stop_service)
pid_t rc_start_service (const char *service) pid_t rc_start_service (const char *service)
{ {
if (! rc_service_state (service, RC_SERVICE_STOPPED)) if (! rc_service_state (service) & RC_SERVICE_STOPPED)
return (0); return (0);
return (_exec_service (service, "start")); return (_exec_service (service, "start"));

View File

@ -31,22 +31,23 @@ static void print_service (char *service)
{ {
char status[10]; char status[10];
int cols = printf (" %s\n", service); int cols = printf (" %s\n", service);
rc_service_state_t state = rc_service_state (service);
einfo_color_t color = ECOLOR_BAD; einfo_color_t color = ECOLOR_BAD;
if (rc_service_state (service, RC_SERVICE_STOPPING)) if (state & RC_SERVICE_STOPPING)
snprintf (status, sizeof (status), "stopping "); snprintf (status, sizeof (status), "stopping ");
else if (rc_service_state (service, RC_SERVICE_STARTING)) { else if (state & RC_SERVICE_STARTING) {
snprintf (status, sizeof (status), "starting "); snprintf (status, sizeof (status), "starting ");
color = ECOLOR_WARN; color = ECOLOR_WARN;
} else if (rc_service_state (service, RC_SERVICE_INACTIVE)) { } else if (state & RC_SERVICE_INACTIVE) {
snprintf (status, sizeof (status), "inactive "); snprintf (status, sizeof (status), "inactive ");
color = ECOLOR_WARN; color = ECOLOR_WARN;
} else if (geteuid () == 0 && rc_service_state (service, RC_SERVICE_CRASHED)) } else if (state & RC_SERVICE_CRASHED)
snprintf (status, sizeof (status), " crashed "); snprintf (status, sizeof (status), " crashed ");
else if (rc_service_state (service, RC_SERVICE_STARTED)) { else if (state & RC_SERVICE_STARTED) {
snprintf (status, sizeof (status), " started "); snprintf (status, sizeof (status), " started ");
color = ECOLOR_GOOD; color = ECOLOR_GOOD;
} else if (rc_service_state (service, RC_SERVICE_SCHEDULED)) { } else if (state & RC_SERVICE_SCHEDULED) {
snprintf (status, sizeof (status), "scheduled"); snprintf (status, sizeof (status), "scheduled");
color = ECOLOR_WARN; color = ECOLOR_WARN;
} else } else

View File

@ -269,19 +269,19 @@ static int do_service (int argc, char **argv)
eerrorx ("%s: no service specified", applet); eerrorx ("%s: no service specified", applet);
if (strcmp (applet, "service_started") == 0) if (strcmp (applet, "service_started") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_STARTED); ok = (rc_service_state (argv[0]) & RC_SERVICE_STARTED);
else if (strcmp (applet, "service_stopped") == 0) else if (strcmp (applet, "service_stopped") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_STOPPED); ok = (rc_service_state (argv[0]) & RC_SERVICE_STOPPED);
else if (strcmp (applet, "service_inactive") == 0) else if (strcmp (applet, "service_inactive") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_INACTIVE); ok = (rc_service_state (argv[0]) & RC_SERVICE_INACTIVE);
else if (strcmp (applet, "service_starting") == 0) else if (strcmp (applet, "service_starting") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_STOPPING); ok = (rc_service_state (argv[0]) & RC_SERVICE_STOPPING);
else if (strcmp (applet, "service_stopping") == 0) else if (strcmp (applet, "service_stopping") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_STOPPING); ok = (rc_service_state (argv[0]) & RC_SERVICE_STOPPING);
else if (strcmp (applet, "service_coldplugged") == 0) else if (strcmp (applet, "service_coldplugged") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_COLDPLUGGED); ok = (rc_service_state (argv[0]) & RC_SERVICE_COLDPLUGGED);
else if (strcmp (applet, "service_wasinactive") == 0) else if (strcmp (applet, "service_wasinactive") == 0)
ok = rc_service_state (argv[0], RC_SERVICE_WASINACTIVE); ok = (rc_service_state (argv[0]) & RC_SERVICE_WASINACTIVE);
else if (strcmp (applet, "service_started_daemon") == 0) { else if (strcmp (applet, "service_started_daemon") == 0) {
int idx = 0; int idx = 0;
if (argc > 2) if (argc > 2)
@ -1180,7 +1180,7 @@ int main (int argc, char **argv)
char *svc2 = NULL; char *svc2 = NULL;
int k; int k;
if (rc_service_state (service, RC_SERVICE_STOPPED)) if (rc_service_state (service) & RC_SERVICE_STOPPED)
continue; continue;
/* We always stop the service when in these runlevels */ /* We always stop the service when in these runlevels */
@ -1224,7 +1224,7 @@ int main (int argc, char **argv)
} }
} else { } else {
/* Allow coldplugged services not to be in the runlevels list */ /* Allow coldplugged services not to be in the runlevels list */
if (rc_service_state (service, RC_SERVICE_COLDPLUGGED)) if (rc_service_state (service) & RC_SERVICE_COLDPLUGGED)
continue; continue;
} }
@ -1324,7 +1324,7 @@ int main (int argc, char **argv)
STRLIST_FOREACH (start_services, service, i) { STRLIST_FOREACH (start_services, service, i) {
if (rc_service_state (service, RC_SERVICE_STOPPED)) { if (rc_service_state (service) & RC_SERVICE_STOPPED) {
pid_t pid; pid_t pid;
if (! interactive) if (! interactive)

View File

@ -44,22 +44,22 @@ typedef enum
{ {
/* These are actual states /* These are actual states
* The service has to be in one only at all times */ * The service has to be in one only at all times */
RC_SERVICE_STARTED = 0x0001, RC_SERVICE_STOPPED = 0x0001,
RC_SERVICE_STOPPED = 0x0002, RC_SERVICE_STARTED = 0x0002,
RC_SERVICE_STARTING = 0x0003,
RC_SERVICE_STOPPING = 0x0004, RC_SERVICE_STOPPING = 0x0004,
RC_SERVICE_INACTIVE = 0x0005, RC_SERVICE_STARTING = 0x0008,
RC_SERVICE_INACTIVE = 0x0010,
/* Service may or may not have been coldplugged */ /* Service may or may not have been coldplugged */
RC_SERVICE_COLDPLUGGED = 0x0010, RC_SERVICE_COLDPLUGGED = 0x0100,
/* Optional states service could also be in */ /* Optional states service could also be in */
RC_SERVICE_FAILED = 0x0100, RC_SERVICE_FAILED = 0x0200,
RC_SERVICE_SCHEDULED = 0x0101, RC_SERVICE_SCHEDULED = 0x0400,
RC_SERVICE_WASINACTIVE = 0x0102, RC_SERVICE_WASINACTIVE = 0x0800,
/* Regardless of state, service may have crashed daemons */ /* Regardless of state, service may have crashed daemons */
RC_SERVICE_CRASHED = 0x1000 RC_SERVICE_CRASHED = 0x1000
} rc_service_state_t; } rc_service_state_t;
/*! Resolves a service name to its full path. /*! Resolves a service name to its full path.
@ -90,9 +90,8 @@ bool rc_service_in_runlevel (const char *service, const char *runlevel);
/*! Checks if a service in in a state /*! Checks if a service in in a state
* @param service to check * @param service to check
* @param state service should be in * @return state of the service */
* @return true if service is in the requested state, otherwise false */ rc_service_state_t rc_service_state (const char *service);
bool rc_service_state (const char *service, rc_service_state_t state);
/*! Marks the service state /*! Marks the service state
* @param service to mark * @param service to mark

View File

@ -189,7 +189,7 @@ static bool in_control ()
if (! mtime_test || ! rc_exists (mtime_test)) if (! mtime_test || ! rc_exists (mtime_test))
return (false); return (false);
if (rc_service_state (applet, RC_SERVICE_STOPPED)) if (rc_service_state (applet) & RC_SERVICE_STOPPED)
return (false); return (false);
if (! (mtime = get_mtime (mtime_test, false))) if (! (mtime = get_mtime (mtime_test, false)))
@ -220,24 +220,23 @@ static void uncoldplug ()
} }
static void start_services (char **list) { static void start_services (char **list) {
bool inactive;
char *svc; char *svc;
int i; int i;
rc_service_state_t state = rc_service_state (service);
if (! list) if (! list)
return; return;
inactive = rc_service_state (service, RC_SERVICE_INACTIVE); if ((state & RC_SERVICE_INACTIVE ||
if (! inactive) state & RC_SERVICE_WASINACTIVE) &&
inactive = rc_service_state (service, RC_SERVICE_WASINACTIVE); ((state & RC_SERVICE_STARTING) ||
(state & RC_SERVICE_STARTED)))
if (inactive ||
rc_service_state (service, RC_SERVICE_STARTING) ||
rc_service_state (service, RC_SERVICE_STARTED))
{ {
STRLIST_FOREACH (list, svc, i) { STRLIST_FOREACH (list, svc, i) {
if (rc_service_state (svc, RC_SERVICE_STOPPED)) { if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
if (inactive) { if (state & RC_SERVICE_INACTIVE ||
state & RC_SERVICE_WASINACTIVE)
{
rc_schedule_start_service (service, svc); rc_schedule_start_service (service, svc);
ewarn ("WARNING: %s is scheduled to started when %s has started", ewarn ("WARNING: %s is scheduled to started when %s has started",
svc, applet); svc, applet);
@ -272,25 +271,19 @@ static void cleanup (void)
free (ibsave); free (ibsave);
if (! rc_in_plugin && in_control ()) { if (! rc_in_plugin && in_control ()) {
if (rc_service_state (applet, RC_SERVICE_STOPPING)) { rc_service_state_t state = rc_service_state (applet);
if (state & RC_SERVICE_STOPPING) {
/* If the we're shutting down, do it cleanly */ /* If the we're shutting down, do it cleanly */
if ((softlevel && if ((softlevel &&
rc_runlevel_stopping () && rc_runlevel_stopping () &&
(strcmp (softlevel, RC_LEVEL_SHUTDOWN) == 0 || (strcmp (softlevel, RC_LEVEL_SHUTDOWN) == 0 ||
strcmp (softlevel, RC_LEVEL_REBOOT) == 0))) strcmp (softlevel, RC_LEVEL_REBOOT) == 0)))
rc_mark_service (applet, RC_SERVICE_STOPPED); rc_mark_service (applet, RC_SERVICE_STOPPED);
else if (rc_service_state (applet, RC_SERVICE_WASINACTIVE)) else if (state & RC_SERVICE_WASINACTIVE)
rc_mark_service (applet, RC_SERVICE_INACTIVE); rc_mark_service (applet, RC_SERVICE_INACTIVE);
else else
rc_mark_service (applet, RC_SERVICE_STARTED); rc_mark_service (applet, RC_SERVICE_STARTED);
} }
else if (rc_service_state (applet, RC_SERVICE_STOPPING))
{
if (rc_service_state (applet, RC_SERVICE_WASINACTIVE))
rc_mark_service (applet, RC_SERVICE_INACTIVE);
else
rc_mark_service (applet, RC_SERVICE_STOPPED);
}
if (exclusive && rc_exists (exclusive)) if (exclusive && rc_exists (exclusive))
unlink (exclusive); unlink (exclusive);
} }
@ -455,32 +448,27 @@ static rc_service_state_t svc_status ()
char status[10]; char status[10];
int (*e) (const char *fmt, ...) = &einfo; int (*e) (const char *fmt, ...) = &einfo;
rc_service_state_t retval = RC_SERVICE_STOPPED; rc_service_state_t state = rc_service_state (service);
if (rc_service_state (service, RC_SERVICE_STOPPING)) { if (state & RC_SERVICE_STOPPING) {
snprintf (status, sizeof (status), "stopping"); snprintf (status, sizeof (status), "stopping");
e = &ewarn; e = &ewarn;
retval = RC_SERVICE_STOPPING; } else if (state & RC_SERVICE_STOPPING) {
} else if (rc_service_state (service, RC_SERVICE_STOPPING)) {
snprintf (status, sizeof (status), "starting"); snprintf (status, sizeof (status), "starting");
e = &ewarn; e = &ewarn;
retval = RC_SERVICE_STOPPING; } else if (state & RC_SERVICE_INACTIVE) {
} else if (rc_service_state (service, RC_SERVICE_INACTIVE)) {
snprintf (status, sizeof (status), "inactive"); snprintf (status, sizeof (status), "inactive");
e = &ewarn; e = &ewarn;
retval = RC_SERVICE_INACTIVE; } else if (state & RC_SERVICE_CRASHED) {
} else if (rc_service_state (service, RC_SERVICE_CRASHED)) {
snprintf (status, sizeof (status), "crashed"); snprintf (status, sizeof (status), "crashed");
e = &eerror; e = &eerror;
retval = RC_SERVICE_CRASHED; } else if (state & RC_SERVICE_STARTED) {
} else if (rc_service_state (service, RC_SERVICE_STARTED)) {
snprintf (status, sizeof (status), "started"); snprintf (status, sizeof (status), "started");
retval = RC_SERVICE_STARTED;
} else } else
snprintf (status, sizeof (status), "stopped"); snprintf (status, sizeof (status), "stopped");
e ("status: %s", status); e ("status: %s", status);
return (retval); return (state);
} }
static void make_exclusive () static void make_exclusive ()
@ -554,25 +542,27 @@ static void svc_start (bool deps)
int i; int i;
int j; int j;
int depoptions = RC_DEP_TRACE; int depoptions = RC_DEP_TRACE;
rc_service_state_t state;
rc_plugin_run (RC_HOOK_SERVICE_START_IN, applet); rc_plugin_run (RC_HOOK_SERVICE_START_IN, applet);
hook_out = RC_HOOK_SERVICE_START_OUT; hook_out = RC_HOOK_SERVICE_START_OUT;
state = rc_service_state (service);
if (rc_env_bool ("IN_HOTPLUG") || in_background) { if (rc_env_bool ("IN_HOTPLUG") || in_background) {
if (! rc_service_state (service, RC_SERVICE_INACTIVE) && if (! state & RC_SERVICE_INACTIVE &&
! rc_service_state (service, RC_SERVICE_STOPPED)) ! state & RC_SERVICE_STOPPED)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
background = true; background = true;
} }
if (rc_service_state (service, RC_SERVICE_STARTED)) { if (state & RC_SERVICE_STARTED) {
ewarn ("WARNING: %s has already been started", applet); ewarn ("WARNING: %s has already been started", applet);
return; return;
} else if (rc_service_state (service, RC_SERVICE_STOPPING)) } else if (state & RC_SERVICE_STOPPING)
ewarnx ("WARNING: %s is already starting", applet); ewarnx ("WARNING: %s is already starting", applet);
else if (rc_service_state (service, RC_SERVICE_STOPPING)) else if (state & RC_SERVICE_STOPPING)
ewarnx ("WARNING: %s is stopping", applet); ewarnx ("WARNING: %s is stopping", applet);
else if (rc_service_state (service, RC_SERVICE_INACTIVE) && ! background) else if (state & RC_SERVICE_INACTIVE && ! background)
ewarnx ("WARNING: %s has already started, but is inactive", applet); ewarnx ("WARNING: %s has already started, but is inactive", applet);
if (! rc_mark_service (service, RC_SERVICE_STOPPING)) if (! rc_mark_service (service, RC_SERVICE_STOPPING))
@ -624,7 +614,7 @@ static void svc_start (bool deps)
if (! rc_runlevel_starting ()) { if (! rc_runlevel_starting ()) {
STRLIST_FOREACH (use_services, svc, i) STRLIST_FOREACH (use_services, svc, i)
if (rc_service_state (svc, RC_SERVICE_STOPPED)) { if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
pid_t pid = rc_start_service (svc); pid_t pid = rc_start_service (svc);
if (! rc_env_bool ("RC_PARALLEL")) if (! rc_env_bool ("RC_PARALLEL"))
rc_waitpid (pid); rc_waitpid (pid);
@ -641,13 +631,14 @@ static void svc_start (bool deps)
tmplist = NULL; tmplist = NULL;
STRLIST_FOREACH (services, svc, i) { STRLIST_FOREACH (services, svc, i) {
if (rc_service_state (svc, RC_SERVICE_STARTED)) rc_service_state_t svcs = rc_service_state (svc);
if (svcs & RC_SERVICE_STARTED)
continue; continue;
/* Don't wait for services which went inactive but are now in /* Don't wait for services which went inactive but are now in
* starting state which we are after */ * starting state which we are after */
if (rc_service_state (svc, RC_SERVICE_STOPPING) && if (svcs & RC_SERVICE_STOPPING &&
rc_service_state(svc, RC_SERVICE_WASINACTIVE)) { svcs & RC_SERVICE_WASINACTIVE) {
bool use = false; bool use = false;
STRLIST_FOREACH (use_services, svc2, j) STRLIST_FOREACH (use_services, svc2, j)
if (strcmp (svc, svc2) == 0) { if (strcmp (svc, svc2) == 0) {
@ -660,13 +651,13 @@ static void svc_start (bool deps)
if (! rc_wait_service (svc)) if (! rc_wait_service (svc))
eerror ("%s: timed out waiting for %s", applet, svc); eerror ("%s: timed out waiting for %s", applet, svc);
if (rc_service_state (svc, RC_SERVICE_STARTED)) if ((svcs = rc_service_state (svc)) & RC_SERVICE_STARTED)
continue; continue;
STRLIST_FOREACH (need_services, svc2, j) STRLIST_FOREACH (need_services, svc2, j)
if (strcmp (svc, svc2) == 0) { if (strcmp (svc, svc2) == 0) {
if (rc_service_state (svc, RC_SERVICE_INACTIVE) || if (svcs & RC_SERVICE_INACTIVE ||
rc_service_state (svc, RC_SERVICE_WASINACTIVE)) svcs & RC_SERVICE_WASINACTIVE)
rc_strlist_add (&tmplist, svc); rc_strlist_add (&tmplist, svc);
else else
eerrorx ("ERROR: cannot start %s as %s would not start", eerrorx ("ERROR: cannot start %s as %s would not start",
@ -736,7 +727,7 @@ static void svc_start (bool deps)
if (in_control ()) { if (in_control ()) {
if (! started) { if (! started) {
if (rc_service_state (service, RC_SERVICE_WASINACTIVE)) if (rc_service_state (service) & RC_SERVICE_WASINACTIVE)
rc_mark_service (service, RC_SERVICE_INACTIVE); rc_mark_service (service, RC_SERVICE_INACTIVE);
else { else {
rc_mark_service (service, RC_SERVICE_STOPPED); rc_mark_service (service, RC_SERVICE_STOPPED);
@ -751,7 +742,7 @@ static void svc_start (bool deps)
rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet); rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet);
} else { } else {
rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet); rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet);
if (rc_service_state (service, RC_SERVICE_INACTIVE)) if (rc_service_state (service) & RC_SERVICE_INACTIVE)
ewarnx ("WARNING: %s has started, but is inactive", applet); ewarnx ("WARNING: %s has started, but is inactive", applet);
else else
ewarnx ("WARNING: %s not under our control, aborting", applet); ewarnx ("WARNING: %s not under our control, aborting", applet);
@ -761,7 +752,7 @@ static void svc_start (bool deps)
rc_strlist_free (services); rc_strlist_free (services);
services = rc_services_scheduled (service); services = rc_services_scheduled (service);
STRLIST_FOREACH (services, svc, i) STRLIST_FOREACH (services, svc, i)
if (rc_service_state (svc, RC_SERVICE_STOPPED)) if (rc_service_state (svc) & RC_SERVICE_STOPPED)
rc_start_service (svc); rc_start_service (svc);
rc_strlist_free (services); rc_strlist_free (services);
services = NULL; services = NULL;
@ -780,7 +771,7 @@ static void svc_start (bool deps)
rc_strlist_free (services); rc_strlist_free (services);
services = rc_services_scheduled (svc2); services = rc_services_scheduled (svc2);
STRLIST_FOREACH (services, svc, i) STRLIST_FOREACH (services, svc, i)
if (rc_service_state (svc, RC_SERVICE_STOPPED)) if (rc_service_state (svc) & RC_SERVICE_STOPPED)
rc_start_service (svc); rc_start_service (svc);
} }
@ -791,22 +782,23 @@ static void svc_start (bool deps)
static void svc_stop (bool deps) static void svc_stop (bool deps)
{ {
bool stopped; bool stopped;
rc_service_state_t state = rc_service_state (service);
hook_out = RC_HOOK_SERVICE_STOP_OUT; hook_out = RC_HOOK_SERVICE_STOP_OUT;
if (rc_runlevel_stopping () && if (rc_runlevel_stopping () &&
rc_service_state (service, RC_SERVICE_FAILED)) state & RC_SERVICE_FAILED)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
if (rc_env_bool ("IN_HOTPLUG") || in_background) if (rc_env_bool ("IN_HOTPLUG") || in_background)
if (! rc_service_state (service, RC_SERVICE_STARTED) && if (! (state & RC_SERVICE_STARTED) &&
! rc_service_state (service, RC_SERVICE_INACTIVE)) ! (state & RC_SERVICE_INACTIVE))
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
if (rc_service_state (service, RC_SERVICE_STOPPED)) { if (state & RC_SERVICE_STOPPED) {
ewarn ("WARNING: %s is already stopped", applet); ewarn ("WARNING: %s is already stopped", applet);
return; return;
} else if (rc_service_state (service, RC_SERVICE_STOPPING)) } else if (state & RC_SERVICE_STOPPING)
ewarnx ("WARNING: %s is already stopping", applet); ewarnx ("WARNING: %s is already stopping", applet);
if (! rc_mark_service (service, RC_SERVICE_STOPPING)) if (! rc_mark_service (service, RC_SERVICE_STOPPING))
@ -818,7 +810,7 @@ static void svc_stop (bool deps)
rc_service_in_runlevel (service, RC_LEVEL_BOOT)) rc_service_in_runlevel (service, RC_LEVEL_BOOT))
ewarn ("WARNING: you are stopping a boot service"); ewarn ("WARNING: you are stopping a boot service");
if (deps && ! rc_service_state (service, RC_SERVICE_WASINACTIVE)) { if (deps && ! (state & RC_SERVICE_WASINACTIVE)) {
int depoptions = RC_DEP_TRACE; int depoptions = RC_DEP_TRACE;
char *svc; char *svc;
int i; int i;
@ -845,12 +837,14 @@ static void svc_stop (bool deps)
softlevel, depoptions); softlevel, depoptions);
rc_strlist_reverse (services); rc_strlist_reverse (services);
STRLIST_FOREACH (services, svc, i) { STRLIST_FOREACH (services, svc, i) {
if (rc_service_state (svc, RC_SERVICE_STARTED) || rc_service_state_t svcs = rc_service_state (svc);
rc_service_state (svc, RC_SERVICE_INACTIVE)) if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
{ {
rc_wait_service (svc); rc_wait_service (svc);
if (rc_service_state (svc, RC_SERVICE_STARTED) || svcs = rc_service_state (svc);
rc_service_state (svc, RC_SERVICE_INACTIVE)) if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
{ {
pid_t pid = rc_stop_service (svc); pid_t pid = rc_stop_service (svc);
if (! rc_env_bool ("RC_PARALLEL")) if (! rc_env_bool ("RC_PARALLEL"))
@ -863,13 +857,12 @@ static void svc_stop (bool deps)
services = NULL; services = NULL;
STRLIST_FOREACH (tmplist, svc, i) { STRLIST_FOREACH (tmplist, svc, i) {
if (rc_service_state (svc, RC_SERVICE_STOPPED)) if (rc_service_state (svc) & RC_SERVICE_STOPPED)
continue; continue;
/* We used to loop 3 times here - maybe re-do this if needed */ /* We used to loop 3 times here - maybe re-do this if needed */
rc_wait_service (svc); rc_wait_service (svc);
if (! rc_service_state (svc, RC_SERVICE_STOPPED)) { if (! (rc_service_state (svc) & RC_SERVICE_STOPPED)) {
if (rc_runlevel_stopping ()) { if (rc_runlevel_stopping ()) {
/* If shutting down, we should stop even if a dependant failed */ /* If shutting down, we should stop even if a dependant failed */
if (softlevel && if (softlevel &&
@ -894,7 +887,7 @@ static void svc_stop (bool deps)
services = rc_get_depends (deptree, types, svclist, services = rc_get_depends (deptree, types, svclist,
softlevel, depoptions); softlevel, depoptions);
STRLIST_FOREACH (services, svc, i) { STRLIST_FOREACH (services, svc, i) {
if (rc_service_state (svc, RC_SERVICE_STOPPED)) if (rc_service_state (svc) & RC_SERVICE_STOPPED)
continue; continue;
rc_wait_service (svc); rc_wait_service (svc);
} }
@ -918,7 +911,7 @@ static void svc_stop (bool deps)
} }
if (! stopped) { if (! stopped) {
if (rc_service_state (service, RC_SERVICE_WASINACTIVE)) if (rc_service_state (service) & RC_SERVICE_WASINACTIVE)
rc_mark_service (service, RC_SERVICE_INACTIVE); rc_mark_service (service, RC_SERVICE_INACTIVE);
else else
rc_mark_service (service, RC_SERVICE_STARTED); rc_mark_service (service, RC_SERVICE_STARTED);
@ -948,15 +941,15 @@ static void svc_restart (bool deps)
our status is invalid. our status is invalid.
One workaround would be to introduce a new status, or status locking. */ One workaround would be to introduce a new status, or status locking. */
if (! deps) { if (! deps) {
if (rc_service_state (service, RC_SERVICE_STARTED) || rc_service_state_t state = rc_service_state (service);
rc_service_state (service, RC_SERVICE_INACTIVE)) if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
svc_exec ("stop", "start"); svc_exec ("stop", "start");
else else
svc_exec ("start", NULL); svc_exec ("start", NULL);
return; return;
} }
if (! rc_service_state (service, RC_SERVICE_STOPPED)) { if (! (rc_service_state (service) & RC_SERVICE_STOPPED)) {
get_started_services (); get_started_services ();
svc_stop (deps); svc_stop (deps);
} }
@ -1122,7 +1115,7 @@ int runscript (int argc, char **argv)
setenv ("RC_DEBUG", "yes", 1); setenv ("RC_DEBUG", "yes", 1);
break; break;
case 's': case 's':
if (! rc_service_state (service, RC_SERVICE_STARTED)) if (! (rc_service_state (service) & RC_SERVICE_STARTED))
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
break; break;
case 'D': case 'D':
@ -1226,7 +1219,7 @@ int runscript (int argc, char **argv)
if (strcmp (optarg, "conditionalrestart") == 0 || if (strcmp (optarg, "conditionalrestart") == 0 ||
strcmp (optarg, "condrestart") == 0) strcmp (optarg, "condrestart") == 0)
{ {
if (rc_service_state (service, RC_SERVICE_STARTED)) if (rc_service_state (service) & RC_SERVICE_STARTED)
svc_restart (deps); svc_restart (deps);
} else if (strcmp (optarg, "restart") == 0) { } else if (strcmp (optarg, "restart") == 0) {
svc_restart (deps); svc_restart (deps);
@ -1241,15 +1234,15 @@ int runscript (int argc, char **argv)
if (deps) { if (deps) {
if (! in_background && if (! in_background &&
! rc_runlevel_stopping () && ! rc_runlevel_stopping () &&
rc_service_state (service, RC_SERVICE_STOPPED)) rc_service_state (service) & RC_SERVICE_STOPPED)
uncoldplug (); uncoldplug ();
if (in_background && if (in_background &&
rc_service_state (service, RC_SERVICE_INACTIVE)) rc_service_state (service) & RC_SERVICE_INACTIVE)
{ {
int j; int j;
STRLIST_FOREACH (restart_services, svc, j) STRLIST_FOREACH (restart_services, svc, j)
if (rc_service_state (svc, RC_SERVICE_STOPPED)) if (rc_service_state (svc) & RC_SERVICE_STOPPED)
rc_schedule_start_service (service, svc); rc_schedule_start_service (service, svc);
} }
} }