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;
if (strcmp(type, "ineed") == 0 ||
if (!runlevel ||
strcmp(type, "ineed") == 0 ||
strcmp(type, "needsme") == 0)
return true;
@ -251,7 +252,7 @@ get_provided1(const char *runlevel, RC_STRINGLIST *providers,
provided dependancy can change depending on runlevel state.
*/
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_STRINGLIST *providers = rc_stringlist_new();
@ -682,42 +683,30 @@ rc_deptree_update_needed(void)
}
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
and echos their dependency info to stdout
Phase 2 takes that and populates a depinfo object with that data
Phase 3 adds any provided services to the depinfo object
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
rc_deptree_update(void)
{
FILE *fp;
RC_DEPTREE *deptree;
RC_DEPTREE *providers;
RC_DEPINFO *depinfo = NULL;
RC_DEPINFO *depinfo_np;
RC_DEPINFO *di;
RC_DEPTYPE *deptype = NULL;
RC_DEPTYPE *dt;
RC_DEPTYPE *dt_np;
RC_STRINGLIST *config;
RC_STRING *s;
RC_STRING *s2;
RC_DEPTYPE *provide;
RC_DEPTREE *deptree, *providers;
RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
RC_DEPTYPE *deptype = NULL, *dt_np, *dt, *provide;
RC_STRINGLIST *config, *types, *sorted, *visited;
RC_STRING *s, *s2, *s2_np, *s3, *s4;
char *line = NULL;
size_t len = 0;
char *depend;
char *depends;
char *service;
char *type;
size_t i;
size_t k;
size_t l;
int retval = true;
char *depend, *depends, *service, *type, *nosys;
size_t i, k, l;
bool retval = true;
const char *sys = rc_sys();
char *nosys;
/* Some init scripts need RC_LIBDIR to source stuff
Ideally we should be setting our full env instead */
@ -876,7 +865,7 @@ rc_deptree_update(void)
TAILQ_FOREACH(s, deptype->services, entries) {
di = get_depinfo(deptree, s->value);
if (!di) {
if (strcmp (deptype->type, "ineed") == 0)
if (strcmp(deptype->type, "ineed") == 0)
fprintf (stderr,
"Service `%s' needs non"
" 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?
I think yes as then it stays human readable
This works and should be entirely shell parseable provided that depend
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;
STAILQ_FOREACH(depinfo, deptree, entries) {
fprintf(fp, "depinfo_%zu_service='%s'\n",
@ -935,11 +976,11 @@ rc_deptree_update(void)
RC_DEPCONFIG, strerror(errno));
retval = false;
}
rc_stringlist_free (config);
} else {
unlink(RC_DEPCONFIG);
}
rc_stringlist_free(config);
rc_deptree_free(deptree);
return retval;
}