RC_DEPEND_STRICT now controls dependency strictness.

If yes then we only use services in the boot and default runlevels,
regradless of service state.
If no then we take into account coldplugged services and the state
of currently running services.
Fixes #185640.
This commit is contained in:
Roy Marples 2007-07-21 12:49:51 +00:00
parent 76f2391ece
commit 6343b48893
5 changed files with 709 additions and 675 deletions

View File

@ -1,6 +1,15 @@
# ChangeLog for Gentoo System Intialization ("rc") scripts
# Copyright 1999-2007 Gentoo Foundation; Distributed under the GPLv2
21 Jul 2007; Roy Marples <uberlord@gentoo.org>:
RC_DEPEND_STRICT now controls dependency strictness.
If yes then we only use services in the boot and default runlevels,
regradless of service state.
If no then we take into account coldplugged services and the state
of currently running services.
Fixes #185640.
15 Jul 2007; Roy Marples <uberlord@gentoo.org>:
adsl module now finds the correct exe, #185276 thanks to Marcello Laganà.

View File

@ -22,11 +22,11 @@ RC_QUIET="no"
# Do we allow any started service in the runlevel to satisfy the depedency
# or do we want all of them regardless of state? For example, if net.eth0
# and net.eth0 are in the default runlevel then with RC_STRICT_DEPEND="no"
# and net.eth0 are in the default runlevel then with RC_DEPEND_STRICT="no"
# both will be started, but services that depend on 'net' will work if either
# one comes up. With RC_STRICT_DEPEND="yes" we would require them both to
# one comes up. With RC_DEPEND_STRICT="yes" we would require them both to
# come up.
RC_STRICT_DEPEND="no"
RC_DEPEND_STRICT="no"
# Do we allow services to be hotplugged? If not, set to RC_HOTPLUG="no"
# NOTE: This does not affect anything hotplug/udev/devd related, just the

View File

@ -8,6 +8,8 @@
#define GENDEP RC_LIBDIR "/sh/gendepends.sh"
static const char *bootlevel = NULL;
/* We use this so we can pass our char array through many functions */
struct lhead
{
@ -180,8 +182,8 @@ librc_hidden_def(rc_get_deptype)
static bool valid_service (const char *runlevel, const char *service)
{
return ((strcmp (runlevel, RC_LEVEL_BOOT) != 0 &&
rc_service_in_runlevel (service, RC_LEVEL_BOOT)) ||
return ((strcmp (runlevel, bootlevel) != 0 &&
rc_service_in_runlevel (service, bootlevel)) ||
rc_service_in_runlevel (service, runlevel) ||
rc_service_state (service, rc_service_coldplugged) ||
rc_service_state (service, rc_service_started));
@ -195,7 +197,6 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
char *service;
int i;
bool retval = false;
char *bootlevel = getenv ("RC_BOOTLEVEL");
STRLIST_FOREACH (deptype->services, service, i)
{
@ -251,7 +252,6 @@ static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo,
struct lhead providers;
char *service;
int i;
char *bootlevel;
if (! deptree || ! depinfo)
return (NULL);
@ -274,11 +274,13 @@ static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo,
return (providers.list);
}
/* If we're strict, then only use what we have in our runlevel */
/* If we're strict, then only use what we have in our runlevel
* and bootlevel */
if (options & RC_DEP_STRICT)
{
STRLIST_FOREACH (dt->services, service, i)
if (rc_service_in_runlevel (service, runlevel))
if (rc_service_in_runlevel (service, runlevel) ||
rc_service_in_runlevel (service, bootlevel))
providers.list = rc_strlist_add (providers.list, service);
if (providers.list)
@ -316,7 +318,6 @@ static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo,
return (providers.list);
/* Check bootlevel if we're not in it */
bootlevel = getenv ("RC_BOOTLEVEL");
if (bootlevel && strcmp (runlevel, bootlevel) != 0)
{
if (get_provided1 (runlevel, &providers, dt, bootlevel, false, rc_service_started))
@ -451,6 +452,10 @@ char **rc_get_depends (rc_depinfo_t *deptree,
memset (&sorted, 0, sizeof (struct lhead));
memset (&visited, 0, sizeof (struct lhead));
bootlevel = getenv ("RC_BOOTLEVEL");
if (! bootlevel)
bootlevel = RC_LEVEL_BOOT;
STRLIST_FOREACH (services, service, i)
{
di = rc_get_depinfo (deptree, service);
@ -473,6 +478,10 @@ char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
if (! runlevel)
return (NULL);
bootlevel = getenv ("RC_BOOTLEVEL");
if (! bootlevel)
bootlevel = RC_LEVEL_BOOT;
/* When shutting down, list all running services */
if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0 ||
strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
@ -490,10 +499,11 @@ char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
/* Add coldplugged services */
list = rc_ls_dir (list, RC_SVCDIR_COLDPLUGGED, RC_LS_INITD);
/* If we're not the boot runlevel then add that too */
if (strcmp (runlevel, RC_LEVEL_BOOT) != 0)
if (strcmp (runlevel, bootlevel) != 0)
{
char *path = rc_strcatpaths (RC_RUNLEVELDIR, RC_LEVEL_BOOT,
char *path = rc_strcatpaths (RC_RUNLEVELDIR, bootlevel,
(char *) NULL);
list = rc_ls_dir (list, path, RC_LS_INITD);
free (path);

View File

@ -464,7 +464,7 @@ static void set_ksoftlevel (const char *runlevel)
FILE *fp;
if (! runlevel ||
strcmp (runlevel, RC_LEVEL_BOOT) == 0 ||
strcmp (runlevel, getenv ("RC_BOOTLEVEL")) == 0 ||
strcmp (runlevel, RC_LEVEL_SINGLE) == 0 ||
strcmp (runlevel, RC_LEVEL_SYSINIT) == 0)
{
@ -644,6 +644,7 @@ static struct option longopts[] = {
int main (int argc, char **argv)
{
char *runlevel = NULL;
const char *bootlevel = NULL;
char *newlevel = NULL;
char *service = NULL;
char **deporder = NULL;
@ -780,6 +781,7 @@ int main (int argc, char **argv)
rc_plugin_load ();
/* Load current softlevel */
bootlevel = getenv ("RC_BOOTLEVEL");
runlevel = rc_get_runlevel ();
/* Check we're in the runlevel requested, ie from
@ -965,7 +967,7 @@ int main (int argc, char **argv)
The only downside of this approach and ours is that we have to hard code
the device node to the init script to simulate the coldplug into
runlevel for our dependency tree to work. */
if (newlevel && strcmp (newlevel, RC_LEVEL_BOOT) == 0 &&
if (newlevel && strcmp (newlevel, bootlevel) == 0 &&
(strcmp (runlevel, RC_LEVEL_SINGLE) == 0 ||
strcmp (runlevel, RC_LEVEL_SYSINIT) == 0) &&
rc_is_env ("RC_COLDPLUG", "yes"))
@ -1015,7 +1017,7 @@ int main (int argc, char **argv)
types = rc_strlist_add (types, "iuse");
types = rc_strlist_add (types, "iafter");
deporder = rc_get_depends (deptree, types, stop_services,
runlevel, depoptions);
runlevel, depoptions | RC_DEP_STOP);
rc_strlist_free (stop_services);
rc_strlist_free (types);
stop_services = deporder;
@ -1029,7 +1031,7 @@ int main (int argc, char **argv)
/* Load our start services now.
We have different rules dependent on runlevel. */
if (newlevel && strcmp (newlevel, RC_LEVEL_BOOT) == 0) {
if (newlevel && strcmp (newlevel, bootlevel) == 0) {
if (coldplugged_services) {
einfon ("Device initiated services:");
STRLIST_FOREACH (coldplugged_services, service, i) {
@ -1051,15 +1053,16 @@ int main (int argc, char **argv)
strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
{
/* We need to include the boot runlevel services if we're not in it */
start_services = rc_ls_dir (start_services, RC_RUNLEVELDIR RC_LEVEL_BOOT,
RC_LS_INITD);
char **services = rc_services_in_runlevel (bootlevel);
start_services = rc_strlist_join (start_services, services);
services = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
start_services = rc_strlist_join (start_services, services);
services = NULL;
STRLIST_FOREACH (coldplugged_services, service, i)
start_services = rc_strlist_add (start_services, service);
tmp = rc_strcatpaths (RC_RUNLEVELDIR,
newlevel ? newlevel : runlevel, (char *) NULL);
start_services = rc_ls_dir (start_services, tmp, RC_LS_INITD);
CHAR_FREE (tmp);
}
}
@ -1199,7 +1202,7 @@ int main (int argc, char **argv)
types = rc_strlist_add (types, "iuse");
types = rc_strlist_add (types, "iafter");
deporder = rc_get_depends (deptree, types, start_services,
runlevel, depoptions);
runlevel, depoptions | RC_DEP_START);
rc_strlist_free (types);
types = NULL;
rc_strlist_free (start_services);
@ -1248,7 +1251,7 @@ interactive_option:
rc_plugin_run (rc_hook_runlevel_start_out, runlevel);
/* Store our interactive status for boot */
if (interactive && strcmp (runlevel, RC_LEVEL_BOOT) == 0)
if (interactive && strcmp (runlevel, bootlevel) == 0)
mark_interactive ();
else {
if (rc_exists (INTERACTIVE))

View File

@ -573,9 +573,6 @@ static void svc_start (bool deps)
rc_plugin_run (rc_hook_service_start_in, applet);
hook_out = rc_hook_service_start_out;
if (rc_is_env ("RC_STRICT_DEPEND", "yes"))
depoptions |= RC_DEP_STRICT;
if (rc_is_env ("IN_HOTPLUG", "1") || in_background) {
if (! rc_service_state (service, rc_service_inactive) &&
! rc_service_state (service, rc_service_stopped))
@ -598,6 +595,12 @@ static void svc_start (bool deps)
make_exclusive (service);
if (rc_is_env ("RC_DEPEND_STRICT", "yes"))
depoptions |= RC_DEP_STRICT;
if (rc_runlevel_starting ())
depoptions |= RC_DEP_START;
if (deps) {
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
eerrorx ("failed to load deptree");
@ -828,9 +831,12 @@ static void svc_stop (bool deps)
char *svc;
int i;
if (rc_is_env ("RC_STRICT_DEPEND", "yes"))
if (rc_is_env ("RC_DEPEND_STRICT", "yes"))
depoptions |= RC_DEP_STRICT;
if (rc_runlevel_stopping ())
depoptions |= RC_DEP_STOP;
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
eerrorx ("failed to load deptree");
@ -1180,6 +1186,11 @@ int main (int argc, char **argv)
strcmp (optarg, "iafter") == 0 ||
strcmp (optarg, "ibefore") == 0 ||
strcmp (optarg, "iprovide") == 0) {
int depoptions = RC_DEP_TRACE;
if (rc_is_env ("RC_DEPEND_STRICT", "yes"))
depoptions |= RC_DEP_STRICT;
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
eerrorx ("failed to load deptree");
@ -1188,7 +1199,8 @@ int main (int argc, char **argv)
rc_strlist_free (svclist);
svclist = rc_strlist_add (NULL, applet);
rc_strlist_free (services);
services = rc_get_depends (deptree, types, svclist, softlevel, 0);
services = rc_get_depends (deptree, types, svclist,
softlevel, depoptions);
STRLIST_FOREACH (services, svc, i)
printf ("%s%s", i == 1 ? "" : " ", svc);
printf ("\n");