[pve-devel] [PATCH v2 pve-container] update inittab instead of replacing it

Wolfgang Bumiller w.bumiller at proxmox.com
Thu Oct 15 09:13:05 CEST 2015


---
 Changes:
  - always update the inittab file, never replace it
    (this required tests to be updated)

 src/PVE/LXC/Setup/Debian.pm              | 102 ++++++++++++++-----------------
 src/test/test-debian-005/etc/inittab.exp |  32 ++++++++--
 src/test/test-debian-006/etc/inittab.exp |  30 ++++++++-
 src/test/test-debian-010/etc/inittab.exp |  26 +++++++-
 4 files changed, 126 insertions(+), 64 deletions(-)

diff --git a/src/PVE/LXC/Setup/Debian.pm b/src/PVE/LXC/Setup/Debian.pm
index 1b2a277..a36a62c 100644
--- a/src/PVE/LXC/Setup/Debian.pm
+++ b/src/PVE/LXC/Setup/Debian.pm
@@ -33,70 +33,58 @@ sub new {
     return bless $self, $class;
 }
 
-my $default_inittab = <<__EOD__;
-
-# The default runlevel.
-id:2:initdefault:
-
-# Boot-time system configuration/initialization script.
-# This is run first except when booting in emergency (-b) mode.
-si::sysinit:/etc/init.d/rcS
-
-# /etc/init.d executes the S and K scripts upon change
-# of runlevel.
-#
-# Runlevel 0 is halt.
-# Runlevel 1 is single-user.
-# Runlevels 2-5 are multi-user.
-# Runlevel 6 is reboot.
-
-l0:0:wait:/etc/init.d/rc 0
-l1:1:wait:/etc/init.d/rc 1
-l2:2:wait:/etc/init.d/rc 2
-l3:3:wait:/etc/init.d/rc 3
-l4:4:wait:/etc/init.d/rc 4
-l5:5:wait:/etc/init.d/rc 5
-l6:6:wait:/etc/init.d/rc 6
-# Normally not reached, but fallthrough in case of emergency.
-z6:6:respawn:/sbin/sulogin
-
-# What to do when CTRL-ALT-DEL is pressed.
-ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
-
-# What to do when the power fails/returns.
-p0::powerfail:/sbin/init 0
-
-# /sbin/getty invocations for the runlevels.
-#
-# The "id" field MUST be the same as the last
-# characters of the device (after "tty").
-#
-# Format:
-#  <id>:<runlevels>:<action>:<process>
-#
-__EOD__
-
 sub setup_init {
     my ($self, $conf) = @_;
 
     my $filename = "/etc/inittab";
+    return if !$self->ct_file_exists($filename);
 
-    if ($self->ct_file_exists($filename)) {
-	my $inittab = $default_inittab;
-
-	my $ttycount =  PVE::LXC::get_tty_count($conf);
-	for (my $i = 1; $i <= $ttycount; $i++) {
-	    next if $i == 7; # reserved for X11
-	    my $levels = ($i == 1) ? '2345' : '23';
-	    if ($self->{version} < 7) {
-		$inittab .= "$i:$levels:respawn:/sbin/getty -L 38400 tty$i\n";
-	    } else {
-		$inittab .= "$i:$levels:respawn:/sbin/getty --noclear 38400 tty$i\n";
-	    }
+    my $ttycount =  PVE::LXC::get_tty_count($conf);
+    my $inittab = $self->ct_file_get_contents($filename);
+
+    my %tty_done;
+    my $linecount = 0;
+    my $last_tty_line;
+
+    # For every getty line enable/disable it via a comment tag ('#') depending
+    # on whether its id is within the ttycount range.
+    # Afterwards, for every new tty for which no tty entry line was found
+    # generate a new one.
+    my $process_line = sub {
+	my ($line) = @_;
+	++$linecount;
+
+	# Check for a getty line:
+	return $line if $line !~ /^\s*#?\s*(\d+):(\d+):([^:]*):(.*getty.*)$/;
+	my ($id, $runlevels, $action, $process) = ($1, $2, $3, $4);
+
+	# Remember the linenumber so we can insert new getty entries grouped
+	# together with the entries already in the file.
+	$last_tty_line = $linecount;
+	return $line if $id <= 0; # sanity check
+
+	$tty_done{$id} = 1; # remember it's already available
+
+	my $disabled = $id > $ttycount ? '#' : '';
+	return "${disabled}$id:$runlevels:$action:$process";
+    };
+    my @lines = map { &$process_line($_) } split(/\n/, $inittab);
+    $last_tty_line ||= scalar(@lines);
+
+    my $version = $self->{version};
+    for my $id (1..$ttycount) {
+	next if $tty_done{$id};
+	my $levels = ($id == 1) ? '2345' : '23';
+	if ($version < 7) {
+	    splice @lines, $last_tty_line++, 0, "$id:$levels:respawn:/sbin/getty -L 38400 tty$id";
+	} else {
+	    splice @lines, $last_tty_line++, 0, "$id:$levels:respawn:/sbin/getty --noclear 38400 tty$id";
 	}
-	
-	$self->ct_file_set_contents($filename, $inittab);
     }
+
+    $inittab = join("\n", @lines) . "\n";
+
+    $self->ct_file_set_contents($filename, $inittab);
 }
 
 sub setup_network {
diff --git a/src/test/test-debian-005/etc/inittab.exp b/src/test/test-debian-005/etc/inittab.exp
index 0cbb029..183edfa 100644
--- a/src/test/test-debian-005/etc/inittab.exp
+++ b/src/test/test-debian-005/etc/inittab.exp
@@ -1,3 +1,5 @@
+# /etc/inittab: init(8) configuration.
+# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
 
 # The default runlevel.
 id:2:initdefault:
@@ -6,6 +8,9 @@ id:2:initdefault:
 # This is run first except when booting in emergency (-b) mode.
 si::sysinit:/etc/init.d/rcS
 
+# What to do in single-user mode.
+~~:S:wait:/sbin/sulogin
+
 # /etc/init.d executes the S and K scripts upon change
 # of runlevel.
 #
@@ -27,8 +32,13 @@ z6:6:respawn:/sbin/sulogin
 # What to do when CTRL-ALT-DEL is pressed.
 ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
 
+# Action on special keypress (ALT-UpArrow).
+#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."
+
 # What to do when the power fails/returns.
-p0::powerfail:/sbin/init 0
+pf::powerwait:/etc/init.d/powerfail start
+pn::powerfailnow:/etc/init.d/powerfail now
+po::powerokwait:/etc/init.d/powerfail stop
 
 # /sbin/getty invocations for the runlevels.
 #
@@ -38,7 +48,21 @@ p0::powerfail:/sbin/init 0
 # Format:
 #  <id>:<runlevels>:<action>:<process>
 #
+# Note that on most Debian systems tty7 is used by the X Window System,
+# so if you want to add more getty's go ahead but skip tty7 if you run X.
+#
 1:2345:respawn:/sbin/getty --noclear 38400 tty1
-2:23:respawn:/sbin/getty --noclear 38400 tty2
-3:23:respawn:/sbin/getty --noclear 38400 tty3
-4:23:respawn:/sbin/getty --noclear 38400 tty4
+2:23:respawn:/sbin/getty 38400 tty2
+3:23:respawn:/sbin/getty 38400 tty3
+4:23:respawn:/sbin/getty 38400 tty4
+#5:23:respawn:/sbin/getty 38400 tty5
+#6:23:respawn:/sbin/getty 38400 tty6
+
+# Example how to put a getty on a serial line (for a terminal)
+#
+#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
+#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
+
+# Example how to put a getty on a modem line.
+#
+#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
diff --git a/src/test/test-debian-006/etc/inittab.exp b/src/test/test-debian-006/etc/inittab.exp
index 9190693..164b481 100644
--- a/src/test/test-debian-006/etc/inittab.exp
+++ b/src/test/test-debian-006/etc/inittab.exp
@@ -1,3 +1,5 @@
+# /etc/inittab: init(8) configuration.
+# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
 
 # The default runlevel.
 id:2:initdefault:
@@ -6,6 +8,9 @@ id:2:initdefault:
 # This is run first except when booting in emergency (-b) mode.
 si::sysinit:/etc/init.d/rcS
 
+# What to do in single-user mode.
+~~:S:wait:/sbin/sulogin
+
 # /etc/init.d executes the S and K scripts upon change
 # of runlevel.
 #
@@ -27,8 +32,13 @@ z6:6:respawn:/sbin/sulogin
 # What to do when CTRL-ALT-DEL is pressed.
 ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
 
+# Action on special keypress (ALT-UpArrow).
+#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."
+
 # What to do when the power fails/returns.
-p0::powerfail:/sbin/init 0
+pf::powerwait:/etc/init.d/powerfail start
+pn::powerfailnow:/etc/init.d/powerfail now
+po::powerokwait:/etc/init.d/powerfail stop
 
 # /sbin/getty invocations for the runlevels.
 #
@@ -38,3 +48,21 @@ p0::powerfail:/sbin/init 0
 # Format:
 #  <id>:<runlevels>:<action>:<process>
 #
+# Note that on most Debian systems tty7 is used by the X Window System,
+# so if you want to add more getty's go ahead but skip tty7 if you run X.
+#
+#1:2345:respawn:/sbin/getty --noclear 38400 tty1
+#2:23:respawn:/sbin/getty 38400 tty2
+#3:23:respawn:/sbin/getty 38400 tty3
+#4:23:respawn:/sbin/getty 38400 tty4
+#5:23:respawn:/sbin/getty 38400 tty5
+#6:23:respawn:/sbin/getty 38400 tty6
+
+# Example how to put a getty on a serial line (for a terminal)
+#
+#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
+#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
+
+# Example how to put a getty on a modem line.
+#
+#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
diff --git a/src/test/test-debian-010/etc/inittab.exp b/src/test/test-debian-010/etc/inittab.exp
index a8b8918..6a07412 100644
--- a/src/test/test-debian-010/etc/inittab.exp
+++ b/src/test/test-debian-010/etc/inittab.exp
@@ -1,3 +1,5 @@
+# /etc/inittab: init(8) configuration.
+# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
 
 # The default runlevel.
 id:2:initdefault:
@@ -6,6 +8,9 @@ id:2:initdefault:
 # This is run first except when booting in emergency (-b) mode.
 si::sysinit:/etc/init.d/rcS
 
+# What to do in single-user mode.
+~~:S:wait:/sbin/sulogin
+
 # /etc/init.d executes the S and K scripts upon change
 # of runlevel.
 #
@@ -27,8 +32,13 @@ z6:6:respawn:/sbin/sulogin
 # What to do when CTRL-ALT-DEL is pressed.
 ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
 
+# Action on special keypress (ALT-UpArrow).
+#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."
+
 # What to do when the power fails/returns.
-p0::powerfail:/sbin/init 0
+pf::powerwait:/etc/init.d/powerfail start
+pn::powerfailnow:/etc/init.d/powerfail now
+po::powerokwait:/etc/init.d/powerfail stop
 
 # /sbin/getty invocations for the runlevels.
 #
@@ -38,7 +48,19 @@ p0::powerfail:/sbin/init 0
 # Format:
 #  <id>:<runlevels>:<action>:<process>
 #
-1:2345:respawn:/sbin/getty -L 38400 tty1
+# Note that on most Debian systems tty7 is used by the X Window System,
+# so if you want to add more getty's go ahead but skip tty7 if you run X.
+#
+1:2345:respawn:/sbin/getty 38400 tty1
 2:23:respawn:/sbin/getty -L 38400 tty2
 3:23:respawn:/sbin/getty -L 38400 tty3
 4:23:respawn:/sbin/getty -L 38400 tty4
+
+# Example how to put a getty on a serial line (for a terminal)
+#
+#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
+#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
+
+# Example how to put a getty on a modem line.
+#
+#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
-- 
2.1.4





More information about the pve-devel mailing list