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