[pve-devel] [PATCH aab 4/5] refactor initial device creation for pacman

Stoiko Ivanov s.ivanov at proxmox.com
Thu Apr 25 19:53:57 CEST 2019


`aab` installs `archlinux-keyring`, which in turn invokes `dirmngr` during
installation. `dirmngr` needs access (at least) to '/dev/null' (see [0]), which
`aab` only created afterwards (before populating the keyring). This lead to
`dirmngr` spinning (and filling the filesystem with a regular file
'${rootfs}/dev/null' containing error messages.

This patch changes the behavior of aab: it now creates the devices before
installing 'archlinux-keyring' and removes them after the keyring is populated.

In order to save one further `mkdir` call for the 'dev' directory, this was
appended to the `mkpath` invocation in ve_init.

[0] https://bbs.archlinux.org/viewtopic.php?id=222002

Signed-off-by: Stoiko Ivanov <s.ivanov at proxmox.com>
---
 PVE/AAB.pm | 51 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/PVE/AAB.pm b/PVE/AAB.pm
index fa65a1e..072a495 100644
--- a/PVE/AAB.pm
+++ b/PVE/AAB.pm
@@ -320,7 +320,7 @@ sub ve_init {
     }
 
     rmtree $self->{rootfs};
-    mkpath $self->{rootfs};
+    mkpath "$self->{rootfs}/dev";
 }
 
 sub ve_command {
@@ -516,6 +516,9 @@ sub bootstrap {
     $self->cache_packages($packages);
     #$self->copy_packages();
 
+    print "Creating device nodes for package manager...\n";
+    $self->create_dev();
+
     print "Installing package manager and essentials...\n";
     # inetutils for 'hostname' for our init
     $self->run_command([@pacman, '-S', 'pacman', 'inetutils', 'archlinux-keyring']);
@@ -531,6 +534,9 @@ sub bootstrap {
     print "Populating keyring...\n";
     $self->populate_keyring();
 
+    print "Removing device nodes...\n";
+    $self->cleanup_dev();
+
     print "Starting container...\n";
     $self->start_container();
 
@@ -538,32 +544,40 @@ sub bootstrap {
     $self->ve_command(['pacman', '-S', '--needed', '--noconfirm', '--', @$packages]);
 }
 
-sub populate_keyring {
+# devices needed for gnupg to function:
+my $devs = {
+    '/dev/null'    => ['c', '1', '3'],
+    '/dev/random'  => ['c', '1', '9'], # fake /dev/random (really urandom)
+    '/dev/urandom' => ['c', '1', '9'],
+    '/dev/tty'     => ['c', '5', '0'],
+};
+
+sub cleanup_dev {
     my ($self) = @_;
     my $root = $self->{rootfs};
 
-    # devices needed for gnupg to function:
-    my $devs = {
-	'/dev/null'    => ['c', '1', '3'],
-	'/dev/random'  => ['c', '1', '9'], # fake /dev/random (really urandom)
-	'/dev/urandom' => ['c', '1', '9'],
-	'/dev/tty'     => ['c', '5', '0'],
-    };
+    # remove temporary device files
+    unlink "${root}$_" foreach keys %$devs;
+}
 
-    my $cleanup_dev = sub {
-	# remove temporary device files
-	unlink "${root}$_" foreach keys %$devs;
-    };
-    local $SIG{INT} = $SIG{TERM} = $cleanup_dev;
+sub create_dev {
+    my ($self) = @_;
+    my $root = $self->{rootfs};
+
+    local $SIG{INT} = $SIG{TERM} = sub { $self->cleanup_dev; };
 
-    # at least /dev/null exists as regular file after installing the filesystem package,
-    # and we want to replace /dev/random, so delete devices first
-    &$cleanup_dev();
+    # we want to replace /dev/random, so delete devices first
+    $self->cleanup_dev();
 
     foreach my $dev (keys %$devs) {
 	my ($type, $major, $minor) = @{$devs->{$dev}};
 	system('mknod', "${root}${dev}", $type, $major, $minor);
     }
+}
+
+sub populate_keyring {
+    my ($self) = @_;
+    my $root = $self->{rootfs};
 
     # generate weak master key and populate the keyring
     system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--init') == 0
@@ -571,9 +585,6 @@ sub populate_keyring {
     system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--populate') == 0
 	or die "failed to populate keyring: $?";
 
-    &$cleanup_dev();
-    # reset to original state
-    system('touch', "$root/dev/null");
 }
 
 sub install {
-- 
2.11.0





More information about the pve-devel mailing list