Remove broken before dependencies, Gentoo #224171.

This commit is contained in:
Roy Marples 2008-06-05 10:14:11 +00:00
parent 3525e602d6
commit dc891b0647

View File

@ -182,7 +182,8 @@ valid_service(const char *runlevel, const char *service, const char *type)
{ {
RC_SERVICE state; RC_SERVICE state;
if (strcmp(type, "ineed") == 0 || if (!runlevel ||
strcmp(type, "ineed") == 0 ||
strcmp(type, "needsme") == 0) strcmp(type, "needsme") == 0)
return true; return true;
@ -251,7 +252,7 @@ get_provided1(const char *runlevel, RC_STRINGLIST *providers,
provided dependancy can change depending on runlevel state. provided dependancy can change depending on runlevel state.
*/ */
static RC_STRINGLIST * static RC_STRINGLIST *
get_provided (const RC_DEPINFO *depinfo, const char *runlevel, int options) get_provided(const RC_DEPINFO *depinfo, const char *runlevel, int options)
{ {
RC_DEPTYPE *dt; RC_DEPTYPE *dt;
RC_STRINGLIST *providers = rc_stringlist_new(); RC_STRINGLIST *providers = rc_stringlist_new();
@ -682,42 +683,30 @@ rc_deptree_update_needed(void)
} }
librc_hidden_def(rc_deptree_update_needed) librc_hidden_def(rc_deptree_update_needed)
/* This is a 5 phase operation /* This is a 6 phase operation
Phase 1 is a shell script which loads each init script and config in turn Phase 1 is a shell script which loads each init script and config in turn
and echos their dependency info to stdout and echos their dependency info to stdout
Phase 2 takes that and populates a depinfo object with that data Phase 2 takes that and populates a depinfo object with that data
Phase 3 adds any provided services to the depinfo object Phase 3 adds any provided services to the depinfo object
Phase 4 scans that depinfo object and puts in backlinks Phase 4 scans that depinfo object and puts in backlinks
Phase 5 saves the depinfo object to disk Phase 5 removes broken before dependencies
Phase 6 saves the depinfo object to disk
*/ */
bool bool
rc_deptree_update(void) rc_deptree_update(void)
{ {
FILE *fp; FILE *fp;
RC_DEPTREE *deptree; RC_DEPTREE *deptree, *providers;
RC_DEPTREE *providers; RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
RC_DEPINFO *depinfo = NULL; RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
RC_DEPINFO *depinfo_np; RC_STRINGLIST *config, *types, *sorted, *visited;
RC_DEPINFO *di; RC_STRING *s, *s2, *s2_np, *s3, *s4;
RC_DEPTYPE *deptype = NULL;
RC_DEPTYPE *dt;
RC_DEPTYPE *dt_np;
RC_STRINGLIST *config;
RC_STRING *s;
RC_STRING *s2;
RC_DEPTYPE *provide;
char *line = NULL; char *line = NULL;
size_t len = 0; size_t len = 0;
char *depend; char *depend, *depends, *service, *type, *nosys;
char *depends; size_t i, k, l;
char *service; bool retval = true;
char *type;
size_t i;
size_t k;
size_t l;
int retval = true;
const char *sys = rc_sys(); const char *sys = rc_sys();
char *nosys;
/* Some init scripts need RC_LIBDIR to source stuff /* Some init scripts need RC_LIBDIR to source stuff
Ideally we should be setting our full env instead */ Ideally we should be setting our full env instead */
@ -876,7 +865,7 @@ rc_deptree_update(void)
TAILQ_FOREACH(s, deptype->services, entries) { TAILQ_FOREACH(s, deptype->services, entries) {
di = get_depinfo(deptree, s->value); di = get_depinfo(deptree, s->value);
if (!di) { if (!di) {
if (strcmp (deptype->type, "ineed") == 0) if (strcmp(deptype->type, "ineed") == 0)
fprintf (stderr, fprintf (stderr,
"Service `%s' needs non" "Service `%s' needs non"
" existant service `%s'\n", " existant service `%s'\n",
@ -895,13 +884,65 @@ rc_deptree_update(void)
} }
} }
/* Phase 5 - save to disk
/* Phase 5 - Remove broken before directives */
types = rc_stringlist_new();
rc_stringlist_add(types, "ineed");
rc_stringlist_add(types, "iuse");
rc_stringlist_add(types, "iafter");
STAILQ_FOREACH(depinfo, deptree, entries) {
deptype = get_deptype(depinfo, "ibefore");
if (!deptype)
continue;
sorted = NULL;
visited = rc_stringlist_new();
visit_service(deptree, types, &sorted, visited, depinfo,
NULL, 0);
rc_stringlist_free(visited);
if (!sorted)
continue;
TAILQ_FOREACH_SAFE(s2, deptype->services, entries, s2_np) {
TAILQ_FOREACH(s3, sorted, entries) {
di = get_depinfo(deptree, s3->value);
if (!di)
continue;
if (strcmp(s2->value, s3->value) == 0) {
dt = get_deptype(di, "iafter");
if (dt)
rc_stringlist_delete(dt->services, depinfo->service);
break;
}
dt = get_deptype(di, "iprovide");
if (!dt)
continue;
TAILQ_FOREACH(s4, dt->services, entries) {
if (strcmp(s4->value, s2->value) == 0)
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);
}
break;
}
}
if (s3)
rc_stringlist_delete(deptype->services, s2->value);
}
rc_stringlist_free(sorted);
}
rc_stringlist_free(types);
/* Phase 6 - save to disk
Now that we're purely in C, do we need to keep a shell parseable file? Now that we're purely in C, do we need to keep a shell parseable file?
I think yes as then it stays human readable I think yes as then it stays human readable
This works and should be entirely shell parseable provided that depend This works and should be entirely shell parseable provided that depend
names don't have any non shell variable characters in names don't have any non shell variable characters in
*/ */
if ((fp = fopen (RC_DEPTREE_CACHE, "w"))) { if ((fp = fopen(RC_DEPTREE_CACHE, "w"))) {
i = 0; i = 0;
STAILQ_FOREACH(depinfo, deptree, entries) { STAILQ_FOREACH(depinfo, deptree, entries) {
fprintf(fp, "depinfo_%zu_service='%s'\n", fprintf(fp, "depinfo_%zu_service='%s'\n",
@ -935,11 +976,11 @@ rc_deptree_update(void)
RC_DEPCONFIG, strerror(errno)); RC_DEPCONFIG, strerror(errno));
retval = false; retval = false;
} }
rc_stringlist_free (config);
} else { } else {
unlink(RC_DEPCONFIG); unlink(RC_DEPCONFIG);
} }
rc_stringlist_free(config);
rc_deptree_free(deptree); rc_deptree_free(deptree);
return retval; return retval;
} }