summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/librc/librc-depend.c474
-rw-r--r--src/librc/rc.h.in51
-rw-r--r--src/openrc-run/openrc-run.c69
-rw-r--r--src/openrc/rc.c41
-rw-r--r--src/rc-depend/rc-depend.c40
-rw-r--r--src/rc-status/rc-status.c20
6 files changed, 316 insertions, 379 deletions
diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index ee6c056e..dc68ca6f 100644
--- a/src/librc/librc-depend.c
+++ b/src/librc/librc-depend.c
@@ -66,18 +66,19 @@ rc_deptree_free(RC_DEPTREE *deptree)
{
RC_DEPINFO *di;
RC_DEPINFO *di_save;
- RC_DEPTYPE *dt;
- RC_DEPTYPE *dt_save;
if (!deptree)
return;
TAILQ_FOREACH_SAFE(di, deptree, entries, di_save) {
- TAILQ_FOREACH_SAFE(dt, &di->depends, entries, dt_save) {
- TAILQ_REMOVE(&di->depends, dt, entries);
- rc_stringlist_free(dt->services);
- free(dt->type);
- free(dt);
+ for (size_t i = 0; i < RC_DEPTYPE_MAX; i++) {
+ struct rc_dep *dt;
+ struct rc_dep *dt_save;
+
+ TAILQ_FOREACH_SAFE(dt, &di->depends[i], entries, dt_save) {
+ TAILQ_REMOVE(&di->depends[i], dt, entries);
+ free(dt);
+ }
}
TAILQ_REMOVE(deptree, di, entries);
free(di->service);
@@ -104,35 +105,46 @@ static RC_DEPINFO *
make_depinfo(RC_DEPTREE *deptree, const char *service)
{
RC_DEPINFO *depinfo = xmalloc(sizeof(*depinfo));
- TAILQ_INIT(&depinfo->depends);
+ for (size_t i = 0; i < RC_DEPTYPE_MAX; i++)
+ TAILQ_INIT(&depinfo->depends[i]);
depinfo->service = xstrdup(service);
TAILQ_INSERT_TAIL(deptree, depinfo, entries);
return depinfo;
}
-static RC_DEPTYPE *
-get_deptype(const RC_DEPINFO *depinfo, const char *type)
-{
- RC_DEPTYPE *dt;
+const char *deptype_map[RC_DEPTYPE_MAX] = {
+ [RC_DEPTYPE_INEED] = "ineed",
+ [RC_DEPTYPE_NEEDSME] = "needsme",
+ [RC_DEPTYPE_IUSE] = "iuse",
+ [RC_DEPTYPE_USESME] = "usesme",
+ [RC_DEPTYPE_IWANT] = "iwant",
+ [RC_DEPTYPE_WANTSME] = "wantsme",
+ [RC_DEPTYPE_IAFTER] = "iafter",
+ [RC_DEPTYPE_AFTERME] = "afterme",
+ [RC_DEPTYPE_IBEFORE] = "ibefore",
+ [RC_DEPTYPE_BEFOREME] = "beforeme",
+ [RC_DEPTYPE_IPROVIDE] = "iprovide",
+ [RC_DEPTYPE_PROVIDEDBY] = "providedby",
+ [RC_DEPTYPE_BROKEN] = "broken",
+ [RC_DEPTYPE_KEYWORD] = "keyword",
+};
- if (depinfo) {
- TAILQ_FOREACH(dt, &depinfo->depends, entries)
- if (strcmp(dt->type, type) == 0)
- return dt;
- }
- return NULL;
+enum rc_deptype
+rc_deptype_parse(const char *type)
+{
+ for (size_t i = 0; i < RC_DEPTYPE_MAX; i++)
+ if (deptype_map[i] && strcmp(type, deptype_map[i]) == 0)
+ return i;
+ return RC_DEPTYPE_INVALID;
}
-static RC_DEPTYPE *
-make_deptype(RC_DEPINFO *depinfo, const char *type)
+static struct rc_dep *
+make_dep(RC_DEPINFO *service)
{
- RC_DEPTYPE *deptype = xmalloc(sizeof(*deptype));
- deptype->type = xstrdup(type);
- deptype->services = rc_stringlist_new();
- TAILQ_INSERT_TAIL(&depinfo->depends, deptype, entries);
-
- return deptype;
+ struct rc_dep *dep = xmalloc(sizeof(*dep));
+ dep->service = service;
+ return dep;
}
#ifdef HAVE_MALLOC_EXTENDED_ATTRIBUTE
@@ -162,8 +174,9 @@ rc_deptree_load_file(const char *deptree_file)
{
FILE *fp;
RC_DEPTREE *deptree;
- RC_DEPINFO *depinfo = NULL;
- RC_DEPTYPE *deptype = NULL;
+ RC_DEPINFO *depinfo = NULL, *depsvc;
+ struct rc_dep *dependency = NULL;
+ enum rc_deptype type_idx;
char *line = NULL;
size_t size;
char *type;
@@ -180,20 +193,27 @@ rc_deptree_load_file(const char *deptree_file)
e = strsep(&p, "_");
if (!e || strcmp(e, "depinfo") != 0)
continue;
+
e = strsep(&p, "_");
if (!e || sscanf(e, "%d", &i) != 1)
continue;
if (!(type = strsep(&p, "_=")))
continue;
+
if (strcmp(type, "service") == 0) {
/* Sanity */
e = get_shell_value(p);
if (!e || *e == '\0')
continue;
- depinfo = make_depinfo(deptree, e);
- deptype = NULL;
+ if (!(depinfo = get_depinfo(deptree, e)))
+ depinfo = make_depinfo(deptree, e);
+ dependency = NULL;
continue;
}
+
+ if ((type_idx = rc_deptype_parse(type)) == RC_DEPTYPE_INVALID)
+ continue;
+
e = strsep(&p, "=");
if (!e || sscanf(e, "%d", &i) != 1)
continue;
@@ -201,9 +221,11 @@ rc_deptree_load_file(const char *deptree_file)
e = get_shell_value(p);
if (!e || *e == '\0')
continue;
- if (!deptype || strcmp(deptype->type, type) != 0)
- deptype = make_deptype(depinfo, type);
- rc_stringlist_add(deptype->services, e);
+ if (!(depsvc = get_depinfo(deptree, e)))
+ depsvc = make_depinfo(deptree, e);
+ dependency = xmalloc(sizeof(*dependency));
+ dependency->service = depsvc;
+ TAILQ_INSERT_TAIL(&depinfo->depends[type_idx], dependency, entries);
}
fclose(fp);
free(line);
@@ -212,23 +234,28 @@ rc_deptree_load_file(const char *deptree_file)
}
static bool
-valid_service(const char *runlevel, const char *service, const char *type)
+valid_service(const char *runlevel, const char *service, enum rc_deptype type)
{
RC_SERVICE state;
- if (!runlevel ||
- strcmp(type, "ineed") == 0 ||
- strcmp(type, "needsme") == 0 ||
- strcmp(type, "iwant") == 0 ||
- strcmp(type, "wantsme") == 0)
+ if (!runlevel)
+ return true;
+
+ switch (type) {
+ case RC_DEPTYPE_INEED:
+ case RC_DEPTYPE_NEEDSME:
+ case RC_DEPTYPE_IWANT:
+ case RC_DEPTYPE_WANTSME:
return true;
+ default:
+ break;
+ }
if (rc_service_in_runlevel(service, runlevel))
return true;
- if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
+ if (type == RC_DEPTYPE_IAFTER && strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0)
return false;
- if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 &&
- strcmp(type, "iafter") == 0)
+ if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
return false;
if (strcmp(runlevel, bootlevel) != 0) {
if (rc_service_in_runlevel(service, bootlevel))
@@ -236,8 +263,7 @@ valid_service(const char *runlevel, const char *service, const char *type)
}
state = rc_service_state(service);
- if (state & RC_SERVICE_HOTPLUGGED ||
- state & RC_SERVICE_STARTED)
+ if (state & RC_SERVICE_HOTPLUGGED || state & RC_SERVICE_STARTED)
return true;
return false;
@@ -245,18 +271,17 @@ valid_service(const char *runlevel, const char *service, const char *type)
static bool
get_provided1(const char *runlevel, RC_STRINGLIST *providers,
- RC_DEPTYPE *deptype, const char *level,
- bool hotplugged, RC_SERVICE state)
+ const struct rc_deplist *deplist, const char *level, bool hotplugged, RC_SERVICE state)
{
- RC_STRING *service;
RC_SERVICE st;
+ struct rc_dep *service;
bool retval = false;
bool ok;
const char *svc;
- TAILQ_FOREACH(service, deptype->services, entries) {
+ TAILQ_FOREACH(service, deplist, entries) {
ok = true;
- svc = service->value;
+ svc = service->service->service;
st = rc_service_state(svc);
if (level)
@@ -302,32 +327,31 @@ get_provided1(const char *runlevel, RC_STRINGLIST *providers,
static RC_STRINGLIST *
get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
{
- RC_DEPTYPE *dt;
+ const struct rc_deplist *deplist = &depinfo->depends[RC_DEPTYPE_PROVIDEDBY];
RC_STRINGLIST *providers = rc_stringlist_new();
- RC_STRING *service;
+ struct rc_dep *dep;
- dt = get_deptype(depinfo, "providedby");
- if (!dt)
+ if (TAILQ_EMPTY(deplist))
return providers;
/* If we are stopping then all depends are true, regardless of state.
This is especially true for net services as they could force a restart
of the local dns resolver which may depend on net. */
if (options & RC_DEP_STOP) {
- TAILQ_FOREACH(service, dt->services, entries)
- rc_stringlist_add(providers, service->value);
+ TAILQ_FOREACH(dep, deplist, entries)
+ rc_stringlist_add(providers, dep->service->service);
return providers;
}
/* If we're strict or starting, then only use what we have in our
* runlevel and bootlevel. If we starting then check hotplugged too. */
if (options & RC_DEP_STRICT || options & RC_DEP_START) {
- TAILQ_FOREACH(service, dt->services, entries)
- if (rc_service_in_runlevel(service->value, runlevel) ||
- rc_service_in_runlevel(service->value, bootlevel) ||
- (options & RC_DEP_START &&
- rc_service_state(service->value) & RC_SERVICE_HOTPLUGGED))
- rc_stringlist_add(providers, service->value);
+ TAILQ_FOREACH(dep, deplist, entries) {
+ const char *svcname = dep->service->service;
+ if (rc_service_in_runlevel(svcname, runlevel) || rc_service_in_runlevel(svcname, bootlevel) ||
+ (options & RC_DEP_START && rc_service_state(svcname) & RC_SERVICE_HOTPLUGGED))
+ rc_stringlist_add(providers, svcname);
+ }
if (TAILQ_FIRST(providers))
return providers;
}
@@ -352,112 +376,97 @@ get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
}
/* Anything running has to come first */
- if (get_provided1(runlevel, providers, dt, runlevel, false, RC_SERVICE_STARTED))
+ if (get_provided1(runlevel, providers, deplist, runlevel, false, RC_SERVICE_STARTED))
{ DO }
- if (get_provided1(runlevel, providers, dt, NULL, true, RC_SERVICE_STARTED))
+ if (get_provided1(runlevel, providers, deplist, NULL, true, RC_SERVICE_STARTED))
{ DO }
if (bootlevel && strcmp(runlevel, bootlevel) != 0 &&
- get_provided1(runlevel, providers, dt, bootlevel, false, RC_SERVICE_STARTED))
+ get_provided1(runlevel, providers, deplist, bootlevel, false, RC_SERVICE_STARTED))
{ DO }
- if (get_provided1(runlevel, providers, dt, NULL, false, RC_SERVICE_STARTED))
+ if (get_provided1(runlevel, providers, deplist, NULL, false, RC_SERVICE_STARTED))
{ DO }
/* Check starting services */
- if (get_provided1(runlevel, providers, dt, runlevel, false, RC_SERVICE_STARTING))
+ if (get_provided1(runlevel, providers, deplist, runlevel, false, RC_SERVICE_STARTING))
return providers;
- if (get_provided1(runlevel, providers, dt, NULL, true, RC_SERVICE_STARTING))
+ if (get_provided1(runlevel, providers, deplist, NULL, true, RC_SERVICE_STARTING))
return providers;
if (bootlevel && strcmp(runlevel, bootlevel) != 0 &&
- get_provided1(runlevel, providers, dt, bootlevel, false, RC_SERVICE_STARTING))
+ get_provided1(runlevel, providers, deplist, bootlevel, false, RC_SERVICE_STARTING))
return providers;
- if (get_provided1(runlevel, providers, dt, NULL, false, RC_SERVICE_STARTING))
+ if (get_provided1(runlevel, providers, deplist, NULL, false, RC_SERVICE_STARTING))
return providers;
/* Nothing started then. OK, lets get the stopped services */
- if (get_provided1(runlevel, providers, dt, runlevel, false, RC_SERVICE_STOPPED))
+ if (get_provided1(runlevel, providers, deplist, runlevel, false, RC_SERVICE_STOPPED))
return providers;
- if (get_provided1(runlevel, providers, dt, NULL, true, RC_SERVICE_STOPPED))
+ if (get_provided1(runlevel, providers, deplist, NULL, true, RC_SERVICE_STOPPED))
{ DO }
if (bootlevel && (strcmp(runlevel, bootlevel) != 0) &&
- get_provided1(runlevel, providers, dt, bootlevel, false, RC_SERVICE_STOPPED))
+ get_provided1(runlevel, providers, deplist, bootlevel, false, RC_SERVICE_STOPPED))
return providers;
/* Still nothing? OK, list our first provided service. */
- service = TAILQ_FIRST(dt->services);
- if (service != NULL)
- rc_stringlist_add(providers, service->value);
+ if (!TAILQ_EMPTY(deplist))
+ rc_stringlist_add(providers, TAILQ_FIRST(deplist)->service->service);
return providers;
}
static void
-visit_service(const RC_DEPTREE *deptree,
- const RC_STRINGLIST *types,
- RC_STRINGLIST *sorted,
- RC_STRINGLIST *visited,
- const RC_DEPINFO *depinfo,
- const char *runlevel, int options)
+visit_service(const RC_DEPTREE *deptree, enum rc_deptype types, RC_STRINGLIST *sorted,
+ RC_DEPINFO *depinfo, const char *runlevel, int options, int idx)
{
- RC_STRING *type;
- RC_STRING *service;
- RC_DEPTYPE *dt;
RC_DEPINFO *di;
RC_STRINGLIST *provided;
RC_STRING *p;
const char *svcname;
/* Check if we have already visited this service or not */
- TAILQ_FOREACH(type, visited, entries)
- if (strcmp(type->value, depinfo->service) == 0)
- return;
- /* Add ourselves as a visited service */
- rc_stringlist_add(visited, depinfo->service);
+ if (depinfo->visited == idx)
+ return;
+ depinfo->visited = idx;
- TAILQ_FOREACH(type, types, entries)
- {
- if (!(dt = get_deptype(depinfo, type->value)))
+ for (size_t i = 0; i < RC_DEPTYPE_MAX; i++) {
+ struct rc_dep *dt;
+ if (!((types >> i) & 1))
continue;
- TAILQ_FOREACH(service, dt->services, entries) {
- if (!(options & RC_DEP_TRACE) ||
- strcmp(type->value, "iprovide") == 0)
- {
- rc_stringlist_add(sorted, service->value);
+ TAILQ_FOREACH(dt, &depinfo->depends[i], entries) {
+ svcname = dt->service->service;
+ if (!(options & RC_DEP_TRACE) || i == RC_DEPTYPE_IPROVIDE) {
+ rc_stringlist_add(sorted, svcname);
continue;
}
- if (!(di = get_depinfo(deptree, service->value)))
+ if (!(di = get_depinfo(deptree, svcname)))
continue;
provided = get_provided(di, runlevel, options);
if (TAILQ_FIRST(provided)) {
TAILQ_FOREACH(p, provided, entries) {
di = get_depinfo(deptree, p->value);
- if (di && valid_service(runlevel, di->service, type->value))
- visit_service(deptree, types, sorted, visited, di,
- runlevel, options | RC_DEP_TRACE);
+ if (di && valid_service(runlevel, di->service, i))
+ visit_service(deptree, types, sorted, di, runlevel, options | RC_DEP_TRACE, idx);
}
+ } else if (di && valid_service(runlevel, svcname, i)) {
+ visit_service(deptree, types, sorted, di, runlevel, options | RC_DEP_TRACE, idx);
}
- else if (di && valid_service(runlevel, service->value, type->value))
- visit_service(deptree, types, sorted, visited, di,
- runlevel, options | RC_DEP_TRACE);
rc_stringlist_free(provided);
}
}
/* Now visit the stuff we provide for */
- if (options & RC_DEP_TRACE &&
- (dt = get_deptype(depinfo, "iprovide")))
- {
- TAILQ_FOREACH(service, dt->services, entries) {
- if (!(di = get_depinfo(deptree, service->value)))
+ if (options & RC_DEP_TRACE) {
+ struct rc_dep *dt;
+ TAILQ_FOREACH(dt, &depinfo->depends[RC_DEPTYPE_IPROVIDE], entries) {
+ if (!(di = get_depinfo(deptree, dt->service->service)))
continue;
provided = get_provided(di, runlevel, options);
TAILQ_FOREACH(p, provided, entries)
if (strcmp(p->value, depinfo->service) == 0) {
- visit_service(deptree, types, sorted, visited, di,
- runlevel, options | RC_DEP_TRACE);
+ visit_service(deptree, types, sorted, di, runlevel, options | RC_DEP_TRACE, idx);
break;
}
rc_stringlist_free(provided);
@@ -468,44 +477,38 @@ visit_service(const RC_DEPTREE *deptree,
are also the service calling us or we are provided by something */
svcname = getenv("RC_SVCNAME");
if (!svcname || strcmp(svcname, depinfo->service) != 0) {
- if (!get_deptype(depinfo, "providedby"))
+ if (TAILQ_EMPTY(&depinfo->depends[RC_DEPTYPE_PROVIDEDBY]))
rc_stringlist_add(sorted, depinfo->service);
}
}
RC_STRINGLIST *
-rc_deptree_depend(const RC_DEPTREE *deptree,
- const char *service, const char *type)
+rc_deptree_depend(const RC_DEPTREE *deptree, const char *service, enum rc_deptype type)
{
RC_DEPINFO *di;
- RC_DEPTYPE *dt;
- RC_STRINGLIST *svcs;
- RC_STRING *svc;
+ struct rc_dep *dt;
+ RC_STRINGLIST *svcs = rc_stringlist_new();
- svcs = rc_stringlist_new();
- if (!(di = get_depinfo(deptree, service)) ||
- !(dt = get_deptype(di, type)))
+ if (type >= RC_DEPTYPE_MAX || !(di = get_depinfo(deptree, service)) || TAILQ_EMPTY(&di->depends[type]))
{
errno = ENOENT;
return svcs;
}
/* For consistency, we copy the array */
- TAILQ_FOREACH(svc, dt->services, entries)
- rc_stringlist_add(svcs, svc->value);
+ TAILQ_FOREACH(dt, &di->depends[type], entries)
+ rc_stringlist_add(svcs, dt->service->service);
return svcs;
}
RC_STRINGLIST *
-rc_deptree_depends(const RC_DEPTREE *deptree,
- const RC_STRINGLIST *types,
- const RC_STRINGLIST *services,
- const char *runlevel, int options)
+rc_deptree_depends(const RC_DEPTREE *deptree, enum rc_deptype types,
+ const RC_STRINGLIST *services, const char *runlevel, int options)
{
RC_STRINGLIST *sorted = rc_stringlist_new();
- RC_STRINGLIST *visited = rc_stringlist_new();
- RC_DEPINFO *di;
const RC_STRING *service;
+ RC_DEPINFO *di;
+ static int idx = 2;
bootlevel = getenv("RC_BOOTLEVEL");
if (!bootlevel)
@@ -515,11 +518,8 @@ rc_deptree_depends(const RC_DEPTREE *deptree,
errno = ENOENT;
continue;
}
- if (types)
- visit_service(deptree, types, sorted, visited,
- di, runlevel, options);
+ visit_service(deptree, types, sorted, di, runlevel, options, idx++);
}
- rc_stringlist_free(visited);
return sorted;
}
@@ -528,7 +528,7 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
{
RC_STRINGLIST *list;
RC_STRINGLIST *list2;
- RC_STRINGLIST *types;
+ enum rc_deptype types;
RC_STRINGLIST *services;
bootlevel = getenv("RC_BOOTLEVEL");
@@ -566,15 +566,10 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
/* Now we have our lists, we need to pull in any dependencies
and order them */
- types = rc_stringlist_new();
- rc_stringlist_add(types, "ineed");
- rc_stringlist_add(types, "iuse");
- rc_stringlist_add(types, "iwant");
- rc_stringlist_add(types, "iafter");
- services = rc_deptree_depends(deptree, types, list, runlevel,
- RC_DEP_STRICT | RC_DEP_TRACE | options);
+ types = RC_DEP(INEED) | RC_DEP(IUSE) | RC_DEP(IWANT) | RC_DEP(IAFTER);
+ services = rc_deptree_depends(deptree, types, list, runlevel, RC_DEP_STRICT | RC_DEP_TRACE | options);
+
rc_stringlist_free(list);
- rc_stringlist_free(types);
return services;
}
@@ -676,18 +671,17 @@ rc_older_than(const char *source, const char *target,
typedef struct deppair
{
- const char *depend;
- const char *addto;
+ enum rc_deptype depend;
+ enum rc_deptype addto;
} DEPPAIR;
static const DEPPAIR deppairs[] = {
- { "ineed", "needsme" },
- { "iuse", "usesme" },
- { "iwant", "wantsme" },
- { "iafter", "ibefore" },
- { "ibefore", "iafter" },
- { "iprovide", "providedby" },
- { NULL, NULL }
+ { RC_DEPTYPE_INEED, RC_DEPTYPE_NEEDSME },
+ { RC_DEPTYPE_IUSE, RC_DEPTYPE_USESME },
+ { RC_DEPTYPE_IWANT, RC_DEPTYPE_WANTSME },
+ { RC_DEPTYPE_IAFTER, RC_DEPTYPE_IBEFORE },
+ { RC_DEPTYPE_IBEFORE, RC_DEPTYPE_IAFTER },
+ { RC_DEPTYPE_IPROVIDE, RC_DEPTYPE_PROVIDEDBY },
};
static const char *const depdirs[] =
@@ -812,6 +806,18 @@ setup_environment(void) {
setenv("RC_UNAME", uts.sysname, 1);
}
+static void
+rc_deplist_delete(struct rc_deplist *list, struct rc_depinfo *svc)
+{
+ struct rc_dep *dep;
+ TAILQ_FOREACH(dep, list, entries)
+ if (dep->service == svc) {
+ TAILQ_REMOVE(list, dep, entries);
+ free(dep);
+ return;
+ }
+}
+
/* This is a 7 phase operation
Phase 1 is a shell script which loads each init script and config in turn
and echos their dependency info to stdout
@@ -828,11 +834,13 @@ rc_deptree_update(void)
{
FILE *fp;
- RC_DEPTREE *deptree, *providers;
+ RC_DEPTREE *deptree;
RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
- RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
- RC_STRINGLIST *config, *dupes, *types, *sorted, *visited;
- RC_STRING *s, *s2, *s2_np, *s3, *s4;
+ struct rc_deplist *deptype = NULL, *dt, *provide;
+ struct rc_dep *dep, *dep_np;
+ RC_STRINGLIST *config, *dupes, *sorted;
+ enum rc_deptype types;
+ RC_STRING *s, *s3;
char *line = NULL;
size_t size;
char *depend, *depends, *service, *type;
@@ -859,9 +867,10 @@ rc_deptree_update(void)
type = strsep(&depends, " ");
if (!depinfo || strcmp(depinfo->service, service) != 0) {
deptype = NULL;
- depinfo = get_depinfo(deptree, service);
- if (!depinfo)
+ if (!(depinfo = get_depinfo(deptree, service))) {
depinfo = make_depinfo(deptree, service);
+ depinfo->exists = true;
+ }
}
/* We may not have any depends */
@@ -870,11 +879,10 @@ rc_deptree_update(void)
/* Get the type */
if (strcmp(type, "config") != 0) {
- if (!deptype || strcmp(deptype->type, type) != 0) {
- deptype = get_deptype(depinfo, type);
- if (!deptype)
- deptype = make_deptype(depinfo, type);
- }
+ int type_idx = rc_deptype_parse(type);
+ if (type_idx == RC_DEPTYPE_INVALID)
+ continue;
+ deptype = &depinfo->depends[type_idx];
}
/* Now add each depend to our type.
@@ -902,26 +910,27 @@ rc_deptree_update(void)
/* Remove our dependency if instructed */
if (depend[0] == '!') {
- rc_stringlist_delete(deptype->services, depend + 1);
+ if ((di = get_depinfo(deptree, depend + 1)))
+ rc_deplist_delete(deptype, di);
continue;
}
- rc_stringlist_add(deptype->services, depend);
+ if (!(di = get_depinfo(deptree, depend)))
+ di = make_depinfo(deptree, depend);
+
+ dep = xmalloc(sizeof(*dep));
+ dep->service = di;
+ TAILQ_INSERT_TAIL(deptype, dep, entries);
/* We need to allow `after *; before local;` to work.
* Conversely, we need to allow 'before *; after modules' also */
/* If we're before something, remove us from the after list */
- if (strcmp(type, "ibefore") == 0) {
- if ((dt = get_deptype(depinfo, "iafter")))
- rc_stringlist_delete(dt->services, depend);
- }
+ if (strcmp(type, "ibefore") == 0)
+ rc_deplist_delete(&depinfo->depends[RC_DEPTYPE_IAFTER], di);
/* If we're after something, remove us from the before list */
- if (strcmp(type, "iafter") == 0 ||
- strcmp(type, "ineed") == 0 ||
- strcmp(type, "iwant") == 0 ||
- strcmp(type, "iuse") == 0) {
- if ((dt = get_deptype(depinfo, "ibefore")))
- rc_stringlist_delete(dt->services, depend);
+ if (strcmp(type, "iafter") == 0 || strcmp(type, "ineed") == 0
+ || strcmp(type, "iwant") == 0 || strcmp(type, "iuse") == 0) {
+ rc_deplist_delete(&depinfo->depends[RC_DEPTYPE_IBEFORE], di);
}
}
}
@@ -948,24 +957,20 @@ rc_deptree_update(void)
onosys[i + 2] = '\0';
TAILQ_FOREACH_SAFE(depinfo, deptree, entries, depinfo_np) {
- if (!(deptype = get_deptype(depinfo, "keyword")))
- continue;
- TAILQ_FOREACH(s, deptype->services, entries) {
- if (strcmp(s->value, nosys) != 0 && strcmp(s->value, onosys) != 0)
+ deptype = &depinfo->depends[RC_DEPTYPE_KEYWORD];
+ TAILQ_FOREACH(dep, deptype, entries) {
+ const char *svcname = dep->service->service;
+ if (strcmp(svcname, nosys) != 0 && strcmp(svcname, onosys) != 0)
continue;
- provide = get_deptype(depinfo, "iprovide");
+ provide = &depinfo->depends[RC_DEPTYPE_IPROVIDE];
TAILQ_REMOVE(deptree, depinfo, entries);
TAILQ_FOREACH(di, deptree, entries) {
- TAILQ_FOREACH_SAFE(dt, &di->depends, entries, dt_np) {
- rc_stringlist_delete(dt->services, depinfo->service);
- if (provide)
- TAILQ_FOREACH(s2, provide->services, entries)
- rc_stringlist_delete(dt->services, s2->value);
- if (!TAILQ_FIRST(dt->services)) {
- TAILQ_REMOVE(&di->depends, dt, entries);
- free(dt->type);
- free(dt->services);
- free(dt);
+ for (dt = di->depends; dt < di->depends + RC_DEPTYPE_MAX; dt++) {
+ rc_deplist_delete(dt, depinfo);
+ if (!TAILQ_EMPTY(provide)) {
+ struct rc_dep *provided;
+ TAILQ_FOREACH(provided, provide, entries)
+ rc_deplist_delete(dt, provided->service);
}
}
}
@@ -975,98 +980,57 @@ rc_deptree_update(void)
free(onosys);
}
- /* Phase 3 - add our providers to the tree */
- providers = xmalloc(sizeof(*providers));
- TAILQ_INIT(providers);
- TAILQ_FOREACH(depinfo, deptree, entries) {
- if (!(deptype = get_deptype(depinfo, "iprovide")))
- continue;
- TAILQ_FOREACH(s, deptype->services, entries) {
- di = get_depinfo(providers, s->value);
- if (!di)
- di = make_depinfo(providers, s->value);
- }
- }
- TAILQ_CONCAT(deptree, providers, entries);
- free(providers);
-
/* Phase 4 - backreference our depends */
TAILQ_FOREACH(depinfo, deptree, entries) {
- for (i = 0; deppairs[i].depend; i++) {
- deptype = get_deptype(depinfo, deppairs[i].depend);
- if (!deptype)
- continue;
- TAILQ_FOREACH(s, deptype->services, entries) {
- di = get_depinfo(deptree, s->value);
- if (!di) {
- if (strcmp(deptype->type, "ineed") == 0) {
+ for (i = 0; i < ARRAY_SIZE(deppairs); i++) {
+ deptype = &depinfo->depends[deppairs[i].depend];
+ TAILQ_FOREACH(dep, deptype, entries) {
+ struct rc_dep *newdep = xmalloc(sizeof(*newdep));
+ newdep->service = dep->service;
+ if (!dep->service->exists) {
+ if (deppairs[i].depend == RC_DEPTYPE_INEED) {
fprintf(stderr, "Service '%s' needs non existent service '%s'\n",
depinfo->service, s->value);
- dt = get_deptype(depinfo, "broken");
- if (!dt)
- dt = make_deptype(depinfo, "broken");
- rc_stringlist_addu(dt->services, s->value);
+ TAILQ_INSERT_TAIL(&depinfo->depends[RC_DEPTYPE_BROKEN], newdep, entries);
}
continue;
}
- dt = get_deptype(di, deppairs[i].addto);
- if (!dt)
- dt = make_deptype(di, deppairs[i].addto);
- rc_stringlist_addu(dt->services, depinfo->service);
+ TAILQ_INSERT_TAIL(&depinfo->depends[deppairs[i].addto], newdep, entries);
}
}
}
/* Phase 5 - Remove broken before directives */
- types = rc_stringlist_new();
- rc_stringlist_add(types, "ineed");
- rc_stringlist_add(types, "iwant");
- rc_stringlist_add(types, "iuse");
- rc_stringlist_add(types, "iafter");
+ types = RC_DEP(INEED) | RC_DEP(IWANT) | RC_DEP(IUSE) | RC_DEP(IAFTER);
TAILQ_FOREACH(depinfo, deptree, entries) {
- deptype = get_deptype(depinfo, "ibefore");
- if (!deptype)
- continue;
+ deptype = &depinfo->depends[RC_DEPTYPE_IBEFORE];
sorted = rc_stringlist_new();
- visited = rc_stringlist_new();
- visit_service(deptree, types, sorted, visited, depinfo,
- NULL, 0);
- rc_stringlist_free(visited);
- TAILQ_FOREACH_SAFE(s2, deptype->services, entries, s2_np) {
+ visit_service(deptree, types, sorted, depinfo, NULL, 0, 1);
+
+ TAILQ_FOREACH_SAFE(dep, deptype, entries, dep_np) {
TAILQ_FOREACH(s3, sorted, entries) {
- di = get_depinfo(deptree, s3->value);
- if (!di)
+ struct rc_dep *provided_dep = NULL;
+ if (!(di = get_depinfo(deptree, s3->value)))
continue;
- if (strcmp(s2->value, s3->value) == 0) {
- dt = get_deptype(di, "iafter");
- if (dt)
- rc_stringlist_delete(dt->services, depinfo->service);
+ if (strcmp(dep->service->service, s3->value) == 0) {
+ rc_deplist_delete(&di->depends[RC_DEPTYPE_IAFTER], depinfo);
break;
}
- dt = get_deptype(di, "iprovide");
- if (!dt)
- continue;
- TAILQ_FOREACH(s4, dt->services, entries) {
- if (strcmp(s4->value, s2->value) == 0)
+ TAILQ_FOREACH(provided_dep, &di->depends[RC_DEPTYPE_IPROVIDE], entries) {
+ if (provided_dep->service == dep->service)
break;
}
- if (s4) {
- di = get_depinfo(deptree, s4->value);
- if (di) {
- dt = get_deptype(di, "iafter");
- if (dt)
- rc_stringlist_delete(dt->services, depinfo->service);
- }
+ if (provided_dep) {
+ rc_deplist_delete(&provided_dep->service->depends[RC_DEPTYPE_IAFTER], depinfo);
break;
}
}
if (s3)
- rc_stringlist_delete(deptype->services, s2->value);
+ rc_deplist_delete(deptype, dep->service);
}
rc_stringlist_free(sorted);
}
- rc_stringlist_free(types);
/* Phase 6 - Print errors for duplicate services */
dupes = rc_stringlist_new();
@@ -1094,11 +1058,11 @@ rc_deptree_update(void)
i = 0;
TAILQ_FOREACH(depinfo, deptree, entries) {
fprintf(fp, "depinfo_%zu_service='%s'\n", i, depinfo->service);
- TAILQ_FOREACH(deptype, &depinfo->depends, entries) {
+ for (size_t d = 0; d < RC_DEPTYPE_MAX; d++) {
size_t k = 0;
- TAILQ_FOREACH(s, deptype->services, entries) {
+ TAILQ_FOREACH(dep, &depinfo->depends[d], entries) {
fprintf(fp, "depinfo_%zu_%s_%zu='%s'\n",
- i, deptype->type, k++, s->value);
+ i, deptype_map[d], k++, dep->service->service);
}
}
i++;
diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in
index 301e4134..e83d0490 100644
--- a/src/librc/rc.h.in
+++ b/src/librc/rc.h.in
@@ -375,29 +375,51 @@ const char *rc_sys(void);
* We analyse each init script and cache the resultant dependency tree.
* This tree can be accessed using the below functions. */
+#define RC_DEP(type) (1 << RC_DEPTYPE_ ## type)
+enum rc_deptype {
+ RC_DEPTYPE_INEED,
+ RC_DEPTYPE_NEEDSME,
+ RC_DEPTYPE_IUSE,
+ RC_DEPTYPE_USESME,
+ RC_DEPTYPE_IWANT,
+ RC_DEPTYPE_WANTSME,
+ RC_DEPTYPE_IAFTER,
+ RC_DEPTYPE_AFTERME,
+ RC_DEPTYPE_IBEFORE,
+ RC_DEPTYPE_BEFOREME,
+ RC_DEPTYPE_IPROVIDE,
+ RC_DEPTYPE_PROVIDEDBY,
+ RC_DEPTYPE_KEYWORD,
+ RC_DEPTYPE_BROKEN,
+ RC_DEPTYPE_MAX,
+
+ RC_DEPTYPE_INVALID = -1,
+};
+
+enum rc_deptype rc_deptype_parse(const char *type);
+
#ifdef _IN_LIBRC
/*! @name Dependency structures
* private to librc */
-/*! Singly linked list of dependency types that list the services the
- * type is for */
-typedef struct rc_deptype
-{
- /*! ineed, iuse, iafter, etc */
- char *type;
- /*! list of services */
- RC_STRINGLIST *services;
- /*! list of types */
- TAILQ_ENTRY(rc_deptype) entries;
-} RC_DEPTYPE;
+struct rc_dep {
+ struct rc_depinfo *service;
+ TAILQ_ENTRY(rc_dep) entries;
+};
/*! Singly linked list of services and their dependencies */
typedef struct rc_depinfo
{
/*! Name of service */
char *service;
+
+ /*! Used during dependency resolution */
+ bool exists;
+ int visited;
+
/*! Dependencies */
- TAILQ_HEAD(, rc_deptype) depends;
+ TAILQ_HEAD(rc_deplist, rc_dep) depends[RC_DEPTYPE_MAX];
+
/*! List of entries */
TAILQ_ENTRY(rc_depinfo) entries;
} RC_DEPINFO;
@@ -472,7 +494,7 @@ RC_DEPTREE *rc_deptree_load_file(const char *);
* @param type to use (keywords, etc)
* @param service to check
* @return NULL terminated list of services in order */
-RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *, const char *, const char *);
+RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *, const char *, enum rc_deptype);
/*! List all the services in order that the given services have
* for the given types and options.
@@ -481,8 +503,7 @@ RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *, const char *, const char *)
* @param services to check
* @param options to pass
* @return NULL terminated list of services in order */
-RC_STRINGLIST *rc_deptree_depends(const RC_DEPTREE *, const RC_STRINGLIST *,
- const RC_STRINGLIST *, const char *, int);
+RC_STRINGLIST *rc_deptree_depends(const RC_DEPTREE *, enum rc_deptype, const RC_STRINGLIST *, const char *, int);
/*! List all the services that should be stopped and then started, in order,
* for the given runlevel, including sysinit and boot services where
diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c
index 3aed8114..7e8aed41 100644
--- a/src/openrc-run/openrc-run.c
+++ b/src/openrc-run/openrc-run.c
@@ -96,13 +96,13 @@ static bool sighup, skip_mark, in_background, deps, dry_run;
static pid_t service_pid;
static int signal_pipe[2] = { -1, -1 };
-static RC_STRINGLIST *deptypes_b; /* broken deps */
-static RC_STRINGLIST *deptypes_n; /* needed deps */
-static RC_STRINGLIST *deptypes_nw; /* need+want deps */
-static RC_STRINGLIST *deptypes_nwu; /* need+want+use deps */
-static RC_STRINGLIST *deptypes_nwua; /* need+want+use+after deps */
-static RC_STRINGLIST *deptypes_m; /* needed deps for stopping */
-static RC_STRINGLIST *deptypes_mwua; /* need+want+use+after deps for stopping */
+//static RC_STRINGLIST *deptypes_b; /* broken deps */
+//static RC_STRINGLIST *deptypes_n; /* needed deps */
+//static RC_STRINGLIST *deptypes_nw; /* need+want deps */
+//static RC_STRINGLIST *deptypes_nwu; /* need+want+use deps */
+//static RC_STRINGLIST *deptypes_nwua; /* need+want+use+after deps */
+//static RC_STRINGLIST *deptypes_m; /* needed deps for stopping */
+//static RC_STRINGLIST *deptypes_mwua; /* need+want+use+after deps for stopping */
static void
handle_signal(int sig)
@@ -251,13 +251,6 @@ cleanup(void)
rc_plugin_unload();
- rc_stringlist_free(deptypes_b);
- rc_stringlist_free(deptypes_n);
- rc_stringlist_free(deptypes_nw);
- rc_stringlist_free(deptypes_nwu);
- rc_stringlist_free(deptypes_nwua);
- rc_stringlist_free(deptypes_m);
- rc_stringlist_free(deptypes_mwua);
rc_deptree_free(deptree);
rc_stringlist_free(restart_services);
rc_stringlist_free(need_services);
@@ -370,7 +363,7 @@ svc_exec(const char *arg1, const char *arg2)
RC_STRINGLIST *keywords;
bool forever;
- keywords = rc_deptree_depend(deptree, applet, "keyword");
+ keywords = rc_deptree_depend(deptree, applet, RC_DEPTYPE_KEYWORD);
if (rc_stringlist_find(keywords, "-timeout") ||
rc_stringlist_find(keywords, "notimeout"))
forever = true;
@@ -509,7 +502,7 @@ svc_wait(const char *svc)
struct timespec timeout, warn;
/* Some services don't have a timeout, like fsck */
- keywords = rc_deptree_depend(deptree, svc, "keyword");
+ keywords = rc_deptree_depend(deptree, svc, RC_DEPTYPE_KEYWORD);
if (rc_stringlist_find(keywords, "-timeout") ||
rc_stringlist_find(keywords, "notimeout"))
forever = true;
@@ -574,6 +567,7 @@ get_started_services(void)
free(tmp);
}
+/*
static void
setup_deptypes(void)
{
@@ -607,6 +601,7 @@ setup_deptypes(void)
rc_stringlist_add(deptypes_mwua, "usesme");
rc_stringlist_add(deptypes_mwua, "beforeme");
}
+*/
static void
svc_start_check(void)
@@ -657,6 +652,7 @@ svc_start_deps(void)
bool first;
RC_STRING *svc, *svc2;
RC_SERVICE state;
+ enum rc_deptype types = 0;
int depoptions = RC_DEP_TRACE;
size_t len;
char *p, *tmp;
@@ -668,11 +664,8 @@ svc_start_deps(void)
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
eerrorx("failed to load deptree");
- if (!deptypes_b)
- setup_deptypes();
- services = rc_deptree_depends(deptree, deptypes_b, applet_list,
- runlevel, 0);
+ services = rc_deptree_depends(deptree, RC_DEP(BROKEN), applet_list, runlevel, 0);
if (TAILQ_FIRST(services)) {
eerrorn("ERROR: %s needs service(s) ", applet);
first = true;
@@ -689,12 +682,9 @@ svc_start_deps(void)
rc_stringlist_free(services);
services = NULL;
- need_services = rc_deptree_depends(deptree, deptypes_n,
- applet_list, runlevel, depoptions);
- want_services = rc_deptree_depends(deptree, deptypes_nw,
- applet_list, runlevel, depoptions);
- use_services = rc_deptree_depends(deptree, deptypes_nwu,
- applet_list, runlevel, depoptions);
+ need_services = rc_deptree_depends(deptree, types |= RC_DEP(INEED), applet_list, runlevel, depoptions);
+ want_services = rc_deptree_depends(deptree, types |= RC_DEP(IWANT), applet_list, runlevel, depoptions);
+ use_services = rc_deptree_depends(deptree, types |= RC_DEP(IUSE), applet_list, runlevel, depoptions);
if (!rc_runlevel_starting()) {
TAILQ_FOREACH(svc, use_services, entries) {
@@ -721,8 +711,7 @@ svc_start_deps(void)
return;
/* Now wait for them to start */
- services = rc_deptree_depends(deptree, deptypes_nwua, applet_list,
- runlevel, depoptions);
+ services = rc_deptree_depends(deptree, types |= RC_DEP(IAFTER), applet_list, runlevel, depoptions);
/* We use tmplist to hold our scheduled by list */
tmplist = rc_stringlist_new();
TAILQ_FOREACH(svc, services, entries) {
@@ -769,8 +758,7 @@ svc_start_deps(void)
len = 0;
TAILQ_FOREACH(svc, tmplist, entries) {
rc_service_schedule_start(svc->value, applet);
- use_services = rc_deptree_depend(deptree,
- "iprovide", svc->value);
+ use_services = rc_deptree_depend(deptree, svc->value, RC_DEPTYPE_IPROVIDE);
TAILQ_FOREACH(svc2, use_services, entries)
rc_service_schedule_start(svc2->value, applet);
rc_stringlist_free(use_services);
@@ -833,7 +821,7 @@ static void svc_start_real(void)
/* Do the same for any services we provide */
if (deptree) {
- tmplist = rc_deptree_depend(deptree, "iprovide", applet);
+ tmplist = rc_deptree_depend(deptree, applet, RC_DEPTYPE_IPROVIDE);
TAILQ_FOREACH(svc, tmplist, entries) {
services = rc_services_scheduled(svc->value);
TAILQ_FOREACH(svc2, services, entries)
@@ -927,10 +915,7 @@ svc_stop_deps(RC_SERVICE state)
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
eerrorx("failed to load deptree");
- if (!deptypes_m)
- setup_deptypes();
-
- services = rc_deptree_depends(deptree, deptypes_m, applet_list,
+ services = rc_deptree_depends(deptree, RC_DEP(NEEDSME), applet_list,
runlevel, depoptions);
tmplist = rc_stringlist_new();
TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
@@ -990,8 +975,8 @@ svc_stop_deps(RC_SERVICE state)
/* We now wait for other services that may use us and are
* stopping. This is important when a runlevel stops */
- services = rc_deptree_depends(deptree, deptypes_mwua, applet_list,
- runlevel, depoptions);
+ services = rc_deptree_depends(deptree, RC_DEP(NEEDSME) | RC_DEP(WANTSME) | RC_DEP(USESME) | RC_DEP(BEFOREME),
+ applet_list, runlevel, depoptions);
TAILQ_FOREACH(svc, services, entries) {
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
continue;
@@ -1305,6 +1290,7 @@ int main(int argc, char **argv)
strcmp(optarg, "ibefore") == 0 ||
strcmp(optarg, "iprovide") == 0)
{
+ enum rc_deptype type;
errno = 0;
if (rc_conf_yesno("rc_depend_strict") ||
errno == ENOENT)
@@ -1314,12 +1300,9 @@ int main(int argc, char **argv)
((deptree = _rc_deptree_load(0, NULL)) == NULL))
eerrorx("failed to load deptree");
- tmplist = rc_stringlist_new();
- rc_stringlist_add(tmplist, optarg);
- services = rc_deptree_depends(deptree, tmplist,
- applet_list,
- runlevel, depoptions);
- rc_stringlist_free(tmplist);
+ if ((type = rc_deptype_parse(optarg)) == RC_DEPTYPE_INVALID)
+ eerrorx("Invalid deptype '%s'", optarg);
+ services = rc_deptree_depends(deptree, type, applet_list, runlevel, depoptions);
tmplist = NULL;
TAILQ_FOREACH(svc, services, entries)
printf("%s ", svc->value);
diff --git a/src/openrc/rc.c b/src/openrc/rc.c
index 9e9bea9c..8c8fccba 100644
--- a/src/openrc/rc.c
+++ b/src/openrc/rc.c
@@ -76,8 +76,6 @@ const char *applet = NULL;
static RC_STRINGLIST *main_hotplugged_services;
static RC_STRINGLIST *main_stop_services;
static RC_STRINGLIST *main_start_services;
-static RC_STRINGLIST *main_types_nw;
-static RC_STRINGLIST *main_types_nwua;
static RC_DEPTREE *main_deptree;
static char *runlevel;
static RC_HOOK hook_out;
@@ -161,8 +159,6 @@ cleanup(void)
rc_stringlist_free(main_hotplugged_services);
rc_stringlist_free(main_stop_services);
rc_stringlist_free(main_start_services);
- rc_stringlist_free(main_types_nw);
- rc_stringlist_free(main_types_nwua);
rc_deptree_free(main_deptree);
free(runlevel);
}
@@ -551,24 +547,16 @@ runlevel_config(const char *service, const char *level)
}
static void
-do_stop_services(RC_STRINGLIST *types_nw, RC_STRINGLIST *start_services,
- const RC_STRINGLIST *stop_services, const RC_DEPTREE *deptree,
- const char *newlevel, bool parallel, bool going_down)
+do_stop_services(RC_STRINGLIST *start_services, const RC_STRINGLIST *stop_services,
+ const RC_DEPTREE *deptree, const char *newlevel, bool parallel, bool going_down)
{
pid_t pid;
RC_STRING *service, *svc1, *svc2;
RC_STRINGLIST *deporder, *tmplist, *kwords;
- RC_STRINGLIST *types_nw_save = NULL;
RC_SERVICE state;
RC_STRINGLIST *nostop;
bool crashed, nstop;
- if (!types_nw) {
- types_nw = types_nw_save = rc_stringlist_new();
- rc_stringlist_add(types_nw, "needsme");
- rc_stringlist_add(types_nw, "wantsme");
- }
-
crashed = rc_conf_yesno("rc_crashed_stop");
nostop = rc_stringlist_split(rc_conf_value("rc_nostop"), " ");
@@ -583,7 +571,7 @@ do_stop_services(RC_STRINGLIST *types_nw, RC_STRINGLIST *start_services,
rc_service_mark(service->value, RC_SERVICE_FAILED);
continue;
}
- kwords = rc_deptree_depend(deptree, service->value, "keyword");
+ kwords = rc_deptree_depend(deptree, service->value, RC_DEPTYPE_KEYWORD);
if (rc_stringlist_find(kwords, "-stop") ||
rc_stringlist_find(kwords, "nostop") ||
(going_down &&
@@ -625,9 +613,8 @@ do_stop_services(RC_STRINGLIST *types_nw, RC_STRINGLIST *start_services,
if (!svc1) {
tmplist = rc_stringlist_new();
rc_stringlist_add(tmplist, service->value);
- deporder = rc_deptree_depends(deptree, types_nw,
- tmplist, newlevel ? newlevel : runlevel,
- RC_DEP_STRICT | RC_DEP_TRACE);
+ deporder = rc_deptree_depends(deptree, RC_DEP(NEEDSME) | RC_DEP(WANTSME), tmplist,
+ newlevel ? newlevel : runlevel, RC_DEP_STRICT | RC_DEP_TRACE);
rc_stringlist_free(tmplist);
svc2 = NULL;
TAILQ_FOREACH(svc1, deporder, entries) {
@@ -654,9 +641,6 @@ stop:
}
}
- if (types_nw_save)
- rc_stringlist_free(types_nw_save);
-
rc_stringlist_free(nostop);
}
@@ -1016,15 +1000,9 @@ int main(int argc, char **argv)
if (main_stop_services)
rc_stringlist_sort(&main_stop_services);
- main_types_nwua = rc_stringlist_new();
- rc_stringlist_add(main_types_nwua, "ineed");
- rc_stringlist_add(main_types_nwua, "iwant");
- rc_stringlist_add(main_types_nwua, "iuse");
- rc_stringlist_add(main_types_nwua, "iafter");
-
if (main_stop_services) {
- tmplist = rc_deptree_depends(main_deptree, main_types_nwua, main_stop_services,
- runlevel, depoptions | RC_DEP_STOP);
+ enum rc_deptype types = RC_DEP(INEED) | RC_DEP(IWANT) | RC_DEP(IUSE) | RC_DEP(IAFTER);
+ tmplist = rc_deptree_depends(main_deptree, types, main_stop_services, runlevel, depoptions | RC_DEP_STOP);
rc_stringlist_free(main_stop_services);
main_stop_services = tmplist;
}
@@ -1068,7 +1046,7 @@ int main(int argc, char **argv)
/* Now stop the services that shouldn't be running */
if (main_stop_services && !nostop)
- do_stop_services(main_types_nw, main_start_services, main_stop_services, main_deptree, newlevel, parallel, going_down);
+ do_stop_services(main_start_services, main_stop_services, main_deptree, newlevel, parallel, going_down);
/* Wait for our services to finish */
wait_for_services();
@@ -1131,10 +1109,11 @@ int main(int argc, char **argv)
{
/* Get a list of all the services in that runlevel */
RC_STRINGLIST *run_services = rc_services_in_runlevel(rlevel->value);
+ enum rc_deptype types = RC_DEP(INEED) | RC_DEP(IWANT) | RC_DEP(IUSE) | RC_DEP(IAFTER);
/* Start those services. */
rc_stringlist_sort(&run_services);
- deporder = rc_deptree_depends(main_deptree, main_types_nwua, run_services, rlevel->value, depoptions | RC_DEP_START);
+ deporder = rc_deptree_depends(main_deptree, types, run_services, rlevel->value, depoptions | RC_DEP_START);
rc_stringlist_free(run_services);
run_services = deporder;
do_start_services(run_services, parallel);
diff --git a/src/rc-depend/rc-depend.c b/src/rc-depend/rc-depend.c
index 791bddc8..2c8891ed 100644
--- a/src/rc-depend/rc-depend.c
+++ b/src/rc-depend/rc-depend.c
@@ -58,10 +58,11 @@ const char *usagestring = NULL;
int main(int argc, char **argv)
{
RC_STRINGLIST *list;
- RC_STRINGLIST *types;
+ enum rc_deptype types;
RC_STRINGLIST *services;
RC_STRINGLIST *depends;
RC_STRING *s;
+ bool default_types = true;
RC_DEPTREE *deptree = NULL;
int options = RC_DEP_TRACE, update = 0;
bool first = true;
@@ -71,7 +72,6 @@ int main(int argc, char **argv)
char *deptree_file = NULL;
applet = basename_c(argv[0]);
- types = rc_stringlist_new();
while ((opt = getopt_long(argc, argv, getoptstring,
longopts, (int *) 0)) != -1)
{
@@ -86,8 +86,13 @@ int main(int argc, char **argv)
options |= RC_DEP_STRICT;
break;
case 't':
- while ((token = strsep(&optarg, ",")))
- rc_stringlist_add(types, token);
+ default_types = false;
+ while ((token = strsep(&optarg, ","))) {
+ enum rc_deptype parsed = rc_deptype_parse(token);
+ if (parsed == RC_DEPTYPE_INVALID)
+ eerrorx("Invalid deptype '%s'", token);
+ types |= (1 << parsed);
+ }
break;
case 'u':
update = 1;
@@ -116,23 +121,24 @@ int main(int argc, char **argv)
services = rc_stringlist_new();
while (optind < argc) {
- list = rc_stringlist_new();
- rc_stringlist_add(list, argv[optind]);
- errno = 0;
- depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0);
+ //list = rc_stringlist_new();
+ //rc_stringlist_add(list, argv[optind]);
+ //errno = 0;
+ /*
+ depends = rc_deptree_depends(deptree, -1, list, runlevel, 0);
if (!depends && errno == ENOENT)
eerror("no dependency info for service `%s'",
argv[optind]);
else
- rc_stringlist_add(services, argv[optind]);
+ */
+ rc_stringlist_add(services, argv[optind]);
- rc_stringlist_free(depends);
- rc_stringlist_free(list);
+ //rc_stringlist_free(depends);
+ //rc_stringlist_free(list);
optind++;
}
if (!TAILQ_FIRST(services)) {
rc_stringlist_free(services);
- rc_stringlist_free(types);
rc_deptree_free(deptree);
free(runlevel);
if (update)
@@ -141,13 +147,10 @@ int main(int argc, char **argv)
}
/* If we don't have any types, then supply some defaults */
- if (!TAILQ_FIRST(types)) {
- rc_stringlist_add(types, "ineed");
- rc_stringlist_add(types, "iuse");
- }
+ if (default_types)
+ types = RC_DEP(INEED) | RC_DEP(IUSE);
- depends = rc_deptree_depends(deptree, types, services,
- runlevel, options);
+ depends = rc_deptree_depends(deptree, types, services, runlevel, options);
if (TAILQ_FIRST(depends)) {
TAILQ_FOREACH(s, depends, entries) {
@@ -161,7 +164,6 @@ int main(int argc, char **argv)
printf ("\n");
}
- rc_stringlist_free(types);
rc_stringlist_free(services);
rc_stringlist_free(depends);
rc_deptree_free(deptree);
diff --git a/src/rc-status/rc-status.c b/src/rc-status/rc-status.c
index e250fb68..ba20dc3c 100644
--- a/src/rc-status/rc-status.c
+++ b/src/rc-status/rc-status.c
@@ -70,10 +70,9 @@ const char *usagestring = ""
" or: rc-status [-C] [-c | -l | -r]";
static RC_DEPTREE *deptree;
-static RC_STRINGLIST *types;
static RC_STRINGLIST *levels, *services, *tmp, *alist;
-static RC_STRINGLIST *sservices, *nservices, *needsme;
+static RC_STRINGLIST *sservices, *nservices;
static void print_level(const char *prefix, const char *level,
enum format_t format)
@@ -220,16 +219,10 @@ static void print_services(const char *runlevel, RC_STRINGLIST *svcs,
print_service(s->value, format);
return;
}
- if (!types) {
- types = rc_stringlist_new();
- rc_stringlist_add(types, "ineed");
- rc_stringlist_add(types, "iuse");
- rc_stringlist_add(types, "iafter");
- }
if (!runlevel)
r = rc_runlevel_get();
- l = rc_deptree_depends(deptree, types, svcs, r ? r : runlevel,
- RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START);
+ l = rc_deptree_depends(deptree, RC_DEP(INEED) | RC_DEP(IUSE) | RC_DEP(IAFTER),
+ svcs, r ? r : runlevel, RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START);
free(r);
if (!l)
return;
@@ -434,9 +427,6 @@ int main(int argc, char **argv)
}
}
}
- needsme = rc_stringlist_new();
- rc_stringlist_add(needsme, "needsme");
- rc_stringlist_add(needsme, "wantsme");
nservices = rc_stringlist_new();
alist = rc_stringlist_new();
l = rc_stringlist_add(alist, "");
@@ -445,7 +435,7 @@ int main(int argc, char **argv)
TAILQ_FOREACH_SAFE(s, services, entries, t) {
l->value = s->value;
setenv("RC_SVCNAME", l->value, 1);
- tmp = rc_deptree_depends(deptree, needsme, alist, level->value, RC_DEP_TRACE);
+ tmp = rc_deptree_depends(deptree, RC_DEP(NEEDSME) | RC_DEP(WANTSME), alist, level->value, RC_DEP_TRACE);
if (TAILQ_FIRST(tmp)) {
TAILQ_REMOVE(services, s, entries);
TAILQ_INSERT_TAIL(nservices, s, entries);
@@ -469,11 +459,9 @@ int main(int argc, char **argv)
exit:
free(runlevel);
rc_stringlist_free(alist);
- rc_stringlist_free(needsme);
rc_stringlist_free(sservices);
rc_stringlist_free(nservices);
rc_stringlist_free(services);
- rc_stringlist_free(types);
rc_stringlist_free(levels);
rc_deptree_free(deptree);