From 21366f76b79dfb4e0c929ac8365eb47e3c47f215 Mon Sep 17 00:00:00 2001 From: Johannes Schauer Marin Rodrigues Date: Wed, 27 Sep 2023 14:02:00 +0200 Subject: [PATCH] Stop copying qemu-$arch-static binary into the chroot - since qemu-user binfmt has support for pre-opening the interpreter since stretch, there is no reason to copy it into the chroot anymore --- mmdebstrap | 125 ++++++++++++++++++----------------------------------- 1 file changed, 42 insertions(+), 83 deletions(-) diff --git a/mmdebstrap b/mmdebstrap index ba10e8a..ffff237 100755 --- a/mmdebstrap +++ b/mmdebstrap @@ -2772,90 +2772,49 @@ sub run_prepare { error "unknown mode: $options->{mode}"; } - # copy qemu-user-static binary into chroot - if (defined $options->{qemu}) { - if ($options->{mode} eq 'fakechroot') { - # Make sure that the fakeroot and fakechroot shared - # libraries exist for the right architecture - open my $fh, '-|', 'dpkg-architecture', '-a', - $options->{nativearch}, - '-qDEB_HOST_MULTIARCH' // error "failed to fork(): $!"; - chomp( - my $deb_host_multiarch = do { local $/; <$fh> } - ); - close $fh; - if (($? != 0) or (!$deb_host_multiarch)) { - error "dpkg-architecture failed: $?"; - } - my $fakechrootdir = "/usr/lib/$deb_host_multiarch/fakechroot"; - if (!-e "$fakechrootdir/libfakechroot.so") { - error "$fakechrootdir/libfakechroot.so doesn't exist." - . " Install libfakechroot:$options->{nativearch}" - . " outside the chroot"; - } - my $fakerootdir = "/usr/lib/$deb_host_multiarch/libfakeroot"; - if (!-e "$fakerootdir/libfakeroot-sysv.so") { - error "$fakerootdir/libfakeroot-sysv.so doesn't exist." - . " Install libfakeroot:$options->{nativearch}" - . " outside the chroot"; - } - # The rest of this block sets environment variables, so we - # have to add the "no critic" statement to stop perlcritic - # from complaining about setting global variables - ## no critic (Variables::RequireLocalizedPunctuationVars) - # fakechroot only fills LD_LIBRARY_PATH with the - # directories of the host's architecture. We append the - # directories of the chroot architecture. - $ENV{LD_LIBRARY_PATH} - = "$ENV{LD_LIBRARY_PATH}:$fakechrootdir:$fakerootdir"; - # The binfmt support on the outside is used, so qemu needs - # to know where it has to look for shared libraries - if (defined $ENV{QEMU_LD_PREFIX} - && $ENV{QEMU_LD_PREFIX} ne "") { - $ENV{QEMU_LD_PREFIX} = "$ENV{QEMU_LD_PREFIX}:$options->{root}"; - } else { - $ENV{QEMU_LD_PREFIX} = $options->{root}; - } - } elsif (any { $_ eq $options->{mode} } ('root', 'unshare')) { - my $require_qemu_static = 1; - # make $@ local, so we don't print an eventual error - # in other parts where we evaluate $@ - local $@ = ''; - eval { - # Check for the F flag which makes the kernel open the binfmt - # binary at configuration time instead of lazily at startup - # time. If the flag is set, then the qemu-static binary is not - # required inside the chroot. - if (-e "/proc/sys/fs/binfmt_misc/qemu-$options->{qemu}") { - open my $fh, '<', - "/proc/sys/fs/binfmt_misc/qemu-$options->{qemu}"; - while (my $line = <$fh>) { - chomp($line); - if ($line =~ /^flags: [A-Z]*F[A-Z]*$/) { - $require_qemu_static = 0; - last; - } - } - close $fh; - } - }; - if ($require_qemu_static) { - # other modes require a static qemu-user binary - my $qemubin = "/usr/bin/qemu-$options->{qemu}-static"; - if (!-e $qemubin) { - error "cannot find $qemubin"; - } - copy $qemubin, "$options->{root}/$qemubin" - or error "cannot copy $qemubin: $!"; - # File::Copy does not retain permissions but on some - # platforms (like Travis CI) the binfmt interpreter must - # have the executable bit set or otherwise execve will - # fail with EACCES - chmod 0755, "$options->{root}/$qemubin" - or error "cannot chmod $qemubin: $!"; - } + # foreign architecture setup for fakechroot mode + if (defined $options->{qemu} && $options->{mode} eq 'fakechroot') { + # Make sure that the fakeroot and fakechroot shared libraries exist for + # the right architecture + open my $fh, '-|', 'dpkg-architecture', '-a', + $options->{nativearch}, + '-qDEB_HOST_MULTIARCH' // error "failed to fork(): $!"; + chomp( + my $deb_host_multiarch = do { local $/; <$fh> } + ); + close $fh; + if (($? != 0) or (!$deb_host_multiarch)) { + error "dpkg-architecture failed: $?"; + } + my $fakechrootdir = "/usr/lib/$deb_host_multiarch/fakechroot"; + if (!-e "$fakechrootdir/libfakechroot.so") { + error "$fakechrootdir/libfakechroot.so doesn't exist." + . " Install libfakechroot:$options->{nativearch}" + . " outside the chroot"; + } + my $fakerootdir = "/usr/lib/$deb_host_multiarch/libfakeroot"; + if (!-e "$fakerootdir/libfakeroot-sysv.so") { + error "$fakerootdir/libfakeroot-sysv.so doesn't exist." + . " Install libfakeroot:$options->{nativearch}" + . " outside the chroot"; + } + + # The rest of this block sets environment variables, so we have to add + # the "no critic" statement to stop perlcritic from complaining about + # setting global variables + ## no critic (Variables::RequireLocalizedPunctuationVars) + # fakechroot only fills LD_LIBRARY_PATH with the directories of the + # host's architecture. We append the directories of the chroot + # architecture. + $ENV{LD_LIBRARY_PATH} + = "$ENV{LD_LIBRARY_PATH}:$fakechrootdir:$fakerootdir"; + # The binfmt support on the outside is used, so qemu needs to know + # where it has to look for shared libraries + if (defined $ENV{QEMU_LD_PREFIX} + && $ENV{QEMU_LD_PREFIX} ne "") { + $ENV{QEMU_LD_PREFIX} = "$ENV{QEMU_LD_PREFIX}:$options->{root}"; } else { - error "unknown mode: $options->{mode}"; + $ENV{QEMU_LD_PREFIX} = $options->{root}; } }