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: