On Mon, Aug 17, 2009 at 05:47:58PM +0200, Werner Fink wrote:
> On Mon, Aug 17, 2009 at 05:41:23PM +0200, Petter Reinholdtsen wrote:
> > [Michael Meskes]
> > > Just imagine a logger that is supposed to log all actions done while
> > > shutting down the system or, as in my case, a daemon whose job it is
> > > to monitor other daemons and, if they do not run anymore, either
> > > restart that daemon or the whole system. It's fairly easy to make
> > > the start action run late enough because there's a hierarchy already
> > > there. But it is almost impossible to stop this daemon first without
> > > listing all ~1000 facilities as to be stopped later.
> > 
> > Werner, what is your opinion on allowing $all to work also for stop
> > dependencies, to be able to stop scripts very early during shutdown?
> > Michael Meskes ran into the need with the watchdog package, where he
> > want to stop the service monitoring before any services are stopped.
> 
> Hmmm ... this is already on my todo but requires to move already sorted
> scripts in the hierarchy.  Or I increase the order nummer before
> sorting.

Let's see ... how does this patch works for you?


       Werner

-- 
  "Having a smoking section in a restaurant is like having
          a peeing section in a swimming pool." -- Edward Burr
--- insserv.c
+++ insserv.c	2009-08-18 13:26:15.805902273 +0200
@@ -300,7 +300,10 @@ static void rememberreq(service_t * rest
 	    if (strcasecmp(token, "$null") == 0)
 		break;
 	    if (strcasecmp(token, "$all") == 0) {
-		serv->attr.flags |= SERV_ALL;
+		if (bit & REQ_KILL)
+		    serv->attr.flags |= SERV_FIRST;
+		else
+		    serv->attr.flags |= SERV_ALL;
 		break;
 	    }
 	    /* Expand the `$' token recursively down */
@@ -622,8 +625,7 @@ static inline void active_script(void)
 }
 
 /*
- * Last but not least the `$all' scripts will be set to the
- * end of the current start order.
+ * The `$all' scripts will be set to the end of the current start order.
  */
 static inline void all_script(void) attribute((always_inline));
 static inline void all_script(void)
@@ -680,6 +682,50 @@ static inline void all_script(void)
 }
 
 /*
+ * Last but not least the `$all' scripts will be set to the
+ * beginning of the current stop order.
+ */
+static inline void first_script(void) attribute((always_inline));
+static inline void first_script(void)
+{
+    list_t * pos;
+
+    list_for_each(pos, s_start) {
+	service_t * serv = getservice(pos);
+	list_t * tmp;
+
+	if (serv->attr.flags & SERV_DUPLET)
+	    continue;			/* Duplet */
+
+	if (!(serv->attr.flags & SERV_FIRST))
+	    continue;
+
+	if (serv->attr.script == (char*)0)
+	    continue;
+
+	list_for_each(tmp, s_start) {
+	    service_t * cur = getservice(tmp);
+
+	    if (cur->attr.flags & SERV_DUPLET)
+		continue;		/* Duplet */
+
+	    if ((serv->start->lvl & cur->start->lvl) == 0)
+		continue;
+
+	    if (cur == serv)
+		continue;
+
+	    if (cur->attr.flags & SERV_FIRST)
+		continue;
+
+	    rememberreq(serv, REQ_SHLD|REQ_KILL, cur->name);
+	}
+
+	setorder(serv->attr.script, 'K', 1, false);
+    }
+}
+
+/*
  * Make the dependency files
  */
 static inline void makedep(void) attribute((always_inline));
@@ -3194,6 +3240,11 @@ int main (int argc, char *argv[])
     nonlsb_script();
 
     /*
+     * Move the `$all' stop scripts to the very beginning
+     */
+    first_script();
+
+    /*
      * Now generate for all scripts the dependencies
      */
     follow_all();
--- listing.c
+++ listing.c	2009-08-18 13:53:47.693917907 +0200
@@ -317,6 +317,7 @@ static void __follow (dir_t *restrict di
     }
 
     for (tmp = dir; tmp; tmp = getnextlink(l_list)) {
+	const typeof(attof(tmp)->flags) sflags = attof(tmp)->flags;
 	register boolean recursion = true;
 	handle_t * ptmp = (mode == 'K') ? &tmp->stopp : &tmp->start;
 	uchar  * order = &ptmp->deep;
@@ -382,6 +383,7 @@ static void __follow (dir_t *restrict di
 	np_list_for_each(dent, l_list) {
 	    dir_t * target = getlink(dent)->target;
 	    handle_t * ptrg = (mode == 'K') ? &target->stopp : &target->start;
+	    const typeof(attof(target)->flags) kflags = attof(target)->flags;
 
 	    if ((peg->run.lvl & ptrg->run.lvl) == 0)
 		continue;			/* Not same boot level */
@@ -399,10 +401,18 @@ static void __follow (dir_t *restrict di
 		break;				/* Loop detected, stop recursion */
 	    }
 
-	    if ((mode == 'S') && (attof(tmp)->flags & SERV_ALL)) {
-		warn("%s depends on %s and therefore on system facility `$all' which can not be true!\n",
-		     target->script ? target->script : target->name, tmp->script ? tmp->script : tmp->name);
-		continue;
+	    if (mode == 'K') {
+		if (kflags & SERV_FIRST) {
+		    warn("Stopping %s depends on %s and therefore on system facility `$all' which can not be true!\n",
+			 tmp->script ? tmp->script : tmp->name, target->script ? target->script : target->name);
+		    continue;
+		}
+	    } else {
+		if (sflags & SERV_ALL) {
+		    warn("Starting %s depends on %s and therefore on system facility `$all' which can not be true!\n",
+			 target->script ? target->script : target->name, tmp->script ? tmp->script : tmp->name);
+		    continue;
+		}
 	    }
 
 	    if (ptrg->deep >= deep)		/* Nothing new */
@@ -848,7 +858,7 @@ void follow_all(void)
     list_for_each(tmp, d_start) {
 	maxorder = &maxstart;
 	guess_order(getdir(tmp), 'S');
-	maxorder = &maxstart;
+	maxorder = &maxstop;
 	guess_order(getdir(tmp), 'K');
     }
 }
--- listing.h
+++ listing.h	2009-08-18 12:54:12.185901887 +0200
@@ -368,6 +368,7 @@ static inline char * xstrdup(const char
 #define SERV_SCRIPT	0x0080
 #define SERV_NOSTOP	0x0100
 #define SERV_CMDLINE	0x0200
+#define SERV_FIRST	0x0400
 
 /*
  * Bits of the runlevels

Reply via email to