On Monday 09 November 2009 02:55, Magnus Damm wrote:
> On Sat, Nov 7, 2009 at 12:37 PM, Denys Vlasenko
> <[email protected]> wrote:
> > On Friday 06 November 2009 07:19, Magnus Damm wrote:
> >> From: Magnus Damm <[email protected]>
> >>
> >> Modify the init applet to take note of SIGHUP received during
> >> early boot at SYSINIT or from hotplugging mdev scripts. Without
> >> this patch SIGHUP is ignored and the inittab is never reloaded.
> >>
> >> Useful for systems that add inittab entries from the mdev script
> >> and reload the initttab to spawn off gettys on hotplugged devices
> >> such as USB serial adapters.
> >
> > Code was:
> >
> >        /* Now run everything that needs to be run */
> >        /* First run the sysinit command */
> >        run_actions(SYSINIT);
> >        check_delayed_sigs();
> >        /* Next run anything that wants to block */
> >        run_actions(WAIT);
> >        check_delayed_sigs();
> >        /* Next run anything to be run only once */
> >        run_actions(ONCE);
> >
> >        /* Set up "reread /etc/inittab" handler.
> >         * Handler is set up without SA_RESTART, it will interrupt syscalls.
> >         */
> >        if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB)
> >                bb_signals_recursive_norestart((1 << SIGHUP), record_signo);
> >
> > You move code which installs SIGHUP handler up, to the top
> > of this fragment.
> 
> Exactly.
> 
> > With new code:
> >
> > If SIGHUP is caught, check_delayed_sigs() will detect it
> > ad call reload_inittab(). It removes all old entries,
> > and also all ONCE, SYSINIT and WAIT entries
> > (even if they come from the new iniitab), and (optionally)
> > kills any running processes resulted from old entries.
> >
> > In other words:
> > if inittab is reloaded by any SYSINIT, WAIT, or ONCE process,
> > all remaining SYSINIT, WAIT, or ONCE entries are ignored,
> > both from old and a new inittab.
> >
> > This was confusing users in the past.
> 
> That's very understandable. =)
> 
> > Where do you run "mdev -s" so that it wants to reload inittab?
> > As part of SYSINIT? When iniitab is reloaded, what
> > stage do you expect init to enter? Back to SYSINIT?
> > Continue with WAIT? or what?
> 
> I let the kernel hotplug handler point to mdev, and I have a line in
> /etc/mdev.conf that executes a shell script which modifies the inittab
> and asks init to reload using "kill -HUP 1".
> 
> In more detail, the shell script simply extends the inittab with a
> respawn getty login line for the recently added serial device. The
> hotplug event can happen at any time basically, but on my system it
> usually happens sometime during the SYSINIT phase. Today the inittab
> is never reloaded and that's the issue that the patch was trying to
> resolve.
> 
> Ideally I'd like the rest of the system to stay the same during the
> hotplugging, ie no processes killed.

Please test attached patch.
--
vda
diff -d -urpN busybox.8/init/init.c busybox.9/init/init.c
--- busybox.8/init/init.c	2009-11-13 08:56:20.000000000 +0100
+++ busybox.9/init/init.c	2009-11-15 03:04:38.000000000 +0100
@@ -40,9 +40,9 @@
 #define ONCE        0x04
 /*
  * NB: while SYSINIT/WAIT/ONCE are being processed,
- * SIGHUP ("reread /etc/inittab") will be ignored.
- * Rationale: it would be ambiguous whether SYSINIT/WAIT/ONCE
- * need to be rerun or not.
+ * SIGHUP ("reread /etc/inittab") will be processed only after
+ * each group of actions. If new inittab adds, say, a SYSINIT action,
+ * it will not be run, since init is already "past SYSINIT stage".
  */
 /* Start these after ONCE are started, restart on exit */
 #define RESPAWN     0x08
@@ -754,12 +754,12 @@ static void reload_inittab(void)
 
 	/* Disable old entries */
 	for (a = init_action_list; a; a = a->next)
-		a->action_type = ONCE;
+		a->action_type = 0;
 
 	/* Append new entries, or modify existing entries
-	 * (set a->action_type) if cmd and device name
+	 * (incl. setting a->action_type) if cmd and device name
 	 * match new ones. End result: only entries with
-	 * a->action_type == ONCE are stale.
+	 * a->action_type == 0 are stale.
 	 */
 	parse_inittab();
 
@@ -767,24 +767,26 @@ static void reload_inittab(void)
 	/* Kill stale entries */
 	/* Be nice and send SIGTERM first */
 	for (a = init_action_list; a; a = a->next)
-		if (a->action_type == ONCE && a->pid != 0)
+		if (a->action_type == 0 && a->pid != 0)
 			kill(a->pid, SIGTERM);
 	if (CONFIG_FEATURE_KILL_DELAY) {
 		/* NB: parent will wait in NOMMU case */
 		if ((BB_MMU ? fork() : vfork()) == 0) { /* child */
 			sleep(CONFIG_FEATURE_KILL_DELAY);
 			for (a = init_action_list; a; a = a->next)
-				if (a->action_type == ONCE && a->pid != 0)
+				if (a->action_type == 0 && a->pid != 0)
 					kill(a->pid, SIGKILL);
 			_exit(EXIT_SUCCESS);
 		}
 	}
 #endif
 
-	/* Remove stale (ONCE) and not useful (SYSINIT,WAIT) entries */
+	/* Remove stale entries and SYSINIT entries.
+	 * We never rerun SYSINIT entries anyway,
+	 * removing them too saves a few bytes */
 	nextp = &init_action_list;
 	while ((a = *nextp) != NULL) {
-		if (a->action_type & (ONCE | SYSINIT | WAIT)) {
+		if ((a->action_type & ~SYSINIT) == 0) {
 			*nextp = a->next;
 			free(a);
 		} else {
@@ -943,6 +945,12 @@ int init_main(int argc UNUSED_PARAM, cha
 		bb_signals_recursive_norestart((1 << SIGINT), record_signo);
 	}
 
+	/* Set up "reread /etc/inittab" handler.
+	 * Handler is set up without SA_RESTART, it will interrupt syscalls.
+	 */
+	if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB)
+		bb_signals_recursive_norestart((1 << SIGHUP), record_signo);
+
 	/* Now run everything that needs to be run */
 	/* First run the sysinit command */
 	run_actions(SYSINIT);
@@ -953,12 +961,6 @@ int init_main(int argc UNUSED_PARAM, cha
 	/* Next run anything to be run only once */
 	run_actions(ONCE);
 
-	/* Set up "reread /etc/inittab" handler.
-	 * Handler is set up without SA_RESTART, it will interrupt syscalls.
-	 */
-	if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB)
-		bb_signals_recursive_norestart((1 << SIGHUP), record_signo);
-
 	/* Now run the looping stuff for the rest of forever.
 	 */
 	while (1) {
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to