[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: init/umount problem persists



I wrote:

> How about to add the new actiontype "last", to be executed at
> the final moment of the system shutdown.
> 
> Here is the diff (caution ! I have not test this) :

That can not be compiled. This could be. I checked this feature
with

tty1::last:/etc/init.d/shutdown
tty1::last:/sbin/swapoff -a
tty1::last:/bin/umount -a

in /etc/inittab, and

#! /bin/sh

echo "going shutdown..."
sleep 1

/sbin/swapoff -a
echo "swapoff finished"
sleep 2

/bin/umount -a
echo "umount -a finished"
sleep 2

in /etc/init.d/shutdown.

Interestingly, the execution of /etc/init.d/shutdown begins
after init went to the next stage. I suppose wait() does not
wait the child process, and init passes by.

Here is the patch to use the new "last" action:

--- init.c.orig	Tue Feb  8 18:57:38 2000
+++ init.c	Tue Feb  8 22:08:10 2000
@@ -78,7 +78,8 @@
     RESPAWN,
     ASKFIRST,
     WAIT,
-    ONCE
+    ONCE,
+    LAST
 } initActionEnum;
 
 /* And now a list of the actions we support in the version of init */
@@ -93,6 +94,7 @@
     {"askfirst",    ASKFIRST},
     {"wait",        WAIT},
     {"once",        ONCE},
+    {"last",        LAST},
     {0}
 };
 
@@ -106,6 +108,7 @@
     initActionEnum action;
 };
 initAction* initActionList = NULL;
+initAction* lastActionList = NULL;
 
 
 static char *secondConsole = VT_SECONDARY;
@@ -459,6 +462,15 @@
 	while (1) sleep(1);
 }
 
+static void run_lastAction(void)
+{
+    /* run anything to be run at final stage */
+    initAction *a;
+    for( a=lastActionList ; a; a=a->nextPtr) {
+	run(a->process, a->console, FALSE);
+    }
+}
+
 #ifndef DEBUG_INIT
 static void shutdown_system(void)
 {
@@ -480,10 +492,13 @@
     kill(-1, SIGKILL);
     sleep(5);
 
+    /* run anything to be run at final stage */
+    run_lastAction();
+
     message(CONSOLE, "Disabling swap.\r\n");
-	waitfor( "swapoff -a", console, FALSE);
+	waitfor( "/sbin/swapoff -a", console, FALSE);
     message(CONSOLE, "Unmounting filesystems.\r\n");
-	waitfor("umount -a -r", console, FALSE);
+	waitfor("/bin/umount -a -r", console, FALSE);
     sync();
     if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
 	/* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -625,14 +640,21 @@
 	message(LOG|CONSOLE,"Memory allocation failure\n");
 	while (1) sleep(1);
     }
-    newAction->nextPtr = initActionList;
-    initActionList = newAction;
-    strncpy( newAction->process, process, 255);
+
+    strncpy(newAction->process, process, 255);
     newAction->action = action;
     strncpy(newAction->console, cons, 255);
     newAction->pid = 0;
-//    message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
+
+    if (action != LAST) {
+        newAction->nextPtr = initActionList;
+        initActionList = newAction;
+//      message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
 //	    newAction->process, newAction->action, newAction->console);
+    } else {
+        newAction->nextPtr = lastActionList;
+        lastActionList = newAction;
+    }
 }
 
 void delete_initAction (initAction *action)



Please note: current init.c in cvs (which uses waitfor() with "umount -a")
does not solve the umount problem at all, because execve() must be given
the filename, and it does not search the command using the PATH env.
(see do_execve() at fs/exec.c in the kernel code.)
If you have to rery on the PATH, then use execvp() or execlp().

-- 
  Taketoshi Sano: <sano@debian.org>,<sano@debian.or.jp>,<kgh12351@nifty.ne.jp>



Reply to: