summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDan Nicholson <dbn.lists@gmail.com>2008-04-29 08:39:15 -0700
committerDan Nicholson <dbn.lists@gmail.com>2008-04-29 08:39:15 -0700
commitd9c0825f0136116259b2bc23fd91ef8d0ad89200 (patch)
tree744259b48ee3bf136e3ea73608ccca20784c22fb /lib
parent2e0735ae16af6bcab2ba407e3d5c5c75fb344d6f (diff)
rdep: Verify the scripts for start/stop at each level
Added new function initd_list_verify_deps, which takes an ordered list of deps and verifies that they are valid for starting or stopping at each level. Currently, this is just called from initd_recurse_deps. The test program trdeps has been adjusted to set valid start and stop levels to exercise this functionality.
Diffstat (limited to 'lib')
-rw-r--r--lib/rdep.c130
-rw-r--r--lib/rdep.h1
2 files changed, 131 insertions, 0 deletions
diff --git a/lib/rdep.c b/lib/rdep.c
index fb3d260..c0907e0 100644
--- a/lib/rdep.c
+++ b/lib/rdep.c
@@ -17,6 +17,9 @@ static bool _recurse_deps(initd_list_t *pool, initd_sk_t sk,
initd_list_t *chain_deps, bool optional,
const char *parent);
static void msg_fill(FILE *fd, int num, const char *format, ...);
+static bool initd_list_verify_level(const initd_list_t *ord,
+ initd_rc_t rc, initd_sk_t sk,
+ bool required);
initd_list_t *initd_recurse_deps(initd_list_t *pool, initd_sk_t sk,
const dep_t *needed)
@@ -42,6 +45,15 @@ initd_list_t *initd_recurse_deps(initd_list_t *pool, initd_sk_t sk,
initd_list_free(chain);
dep_free(all_needed);
+
+ if (!success)
+ goto out;
+
+ success = initd_list_verify_deps(all, sk);
+ if (!success)
+ fprintf(stderr, "Failed to verify %s scripts\n",
+ (sk == RC_START) ? "start" : "stop");
+
out:
if (success) {
return all;
@@ -56,6 +68,38 @@ void initd_recurse_set_verbose(bool verbose)
rdep_verbose = verbose;
}
+/* Given an ordered initd list (such as determined in initd_recurse_deps)
+ * determine if the start and stop order is valid in each run level. */
+bool initd_list_verify_deps(const initd_list_t *ord, initd_sk_t sk)
+{
+ initd_rc_t rc;
+ bool ret = true;
+
+ if (!ord)
+ return false;
+
+ for (rc = RC_S; rc <= RC_6; rc = rc << 1) {
+ if (!initd_list_verify_level(ord, rc, sk, true)) {
+ fprintf(stderr, "Failed to verify the required "
+ "%s scripts for level %c\n",
+ (sk == RC_START) ? "start" : "stop",
+ initd_rc_level_char(rc));
+ ret = false;
+ break;
+ }
+ if (!initd_list_verify_level(ord, rc, sk, false)) {
+ fprintf(stderr, "Failed to verify the optional "
+ "%s scripts for level %c\n",
+ (sk == RC_START) ? "start" : "stop",
+ initd_rc_level_char(rc));
+ ret = false;
+ break;
+ }
+ }
+
+ return ret;
+}
+
static dep_t *add_all_active(const initd_list_t *pool,
const dep_t *init, initd_sk_t sk)
{
@@ -238,3 +282,89 @@ static void msg_fill(FILE *fd, int num, const char *format, ...)
vfprintf(fd, format, args);
va_end(args);
}
+
+static bool initd_list_verify_level(const initd_list_t *ord,
+ initd_rc_t rc, initd_sk_t sk,
+ bool required)
+{
+ initd_t *ip, *dep;
+ initd_rc_t iprc;
+ dep_t *iprcdep;
+ char *dstr;
+ int n;
+ bool match;
+
+ if (!ord)
+ return false;
+
+ /* Check the deps are valid in this level */
+ for (ip = ord->first; ip; ip = ip->next) {
+ if (sk == RC_START) {
+ iprc = ip->dstart;
+ if (required)
+ iprcdep = ip->rstart;
+ else
+ iprcdep = ip->sstart;
+ } else {
+ iprc = ip->dstop;
+ if (required)
+ iprcdep = ip->rstop;
+ else
+ iprcdep = ip->sstop;
+ }
+
+ /* Skip if the script isn't active at this level */
+ if (!(iprc & rc))
+ continue;
+
+ /* Check the deps */
+ for (n = 0; n < dep_get_num(iprcdep); n++) {
+ dstr = dep_get_dep(iprcdep, n);
+ dep = initd_list_find_provides(ord, dstr);
+ if (!dep) {
+ if (required) {
+ fprintf(stderr,
+ "No init script "
+ "provides %s\n",
+ dstr);
+ return false;
+ } else {
+ continue;
+ }
+ }
+
+ /* Check if the dep is started in this level
+ * or if it's in a special level */
+ if (sk == RC_START) {
+ match = dep->dstart & rc;
+ if (!match)
+ match = dep->dstart & RC_S;
+ } else {
+ match = dep->dstop & rc;
+ if (!match) {
+ match = (dep->dstop & RC_0) &&
+ (dep->dstop & RC_6);
+ }
+ }
+
+ if (!match && sk == RC_START) {
+ fprintf(stderr,
+ "%s dependency %s does not "
+ "start in level %c or sysinit\n",
+ ip->name, dstr,
+ initd_rc_level_char(rc));
+ return false;
+ } else if (!match) {
+ fprintf(stderr,
+ "%s dependency %s does not stop "
+ "in level %c or halt and reboot\n",
+ ip->name, dstr,
+ initd_rc_level_char(rc));
+ return false;
+ }
+ }
+ }
+
+ /* If we get here, then we were successful */
+ return true;
+}
diff --git a/lib/rdep.h b/lib/rdep.h
index 517fe23..ae97fb2 100644
--- a/lib/rdep.h
+++ b/lib/rdep.h
@@ -8,5 +8,6 @@
extern initd_list_t *initd_recurse_deps(initd_list_t *pool, initd_sk_t sk,
const dep_t *needed);
extern void initd_recurse_set_verbose(bool verbose);
+extern bool initd_list_verify_deps(const initd_list_t *ord, initd_sk_t sk);
#endif /* _dep_h_ */