[pve-devel] [PATCH container v3] Create: fix architecture detection in restore_archive
Dietmar Maurer
dietmar at proxmox.com
Tue Dec 20 11:48:35 CET 2016
> On December 20, 2016 at 6:48 AM Thomas Lamprecht <t.lamprecht at proxmox.com>
> wrote:
>
>
> For detecting a CT templates architecture we used the `file -b -L`
> output from the PVE host side.
> If the container has a link:
> /bin/sh -> /bin/bash
> (Alpine Linux does that) the '-L' flag from file resolves the
> $rootfs/bin/sh to /bin/bash and thus checks the architecture of
> bash on the PVE system, which is always 64 bit.
>
> Add a helper which chroots in the rootfs to avoid problems with
> absolute symlinks and use 'open' to avoid relative symlink problems
> read the first 5 bytes from /bin/sh, 4 bytes for the ELF magic number
> and the fifth for the ELF class, which tells us if we have a 32
> (class 1) or 64 (class 2) bit ELF binary.
>
> Return this information as an exit code to the parent.
>
> Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
> CC: Wolfgang Bumiller <w.bumiller at proxmox.com>
> ---
> src/PVE/LXC/Create.pm | 77
> +++++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 62 insertions(+), 15 deletions(-)
>
> diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm
> index 11bc00d..5af03d3 100644
> --- a/src/PVE/LXC/Create.pm
> +++ b/src/PVE/LXC/Create.pm
> @@ -11,6 +11,7 @@ use PVE::LXC;
> use PVE::LXC::Setup;
> use PVE::VZDump::ConvertOVZ;
> use PVE::Tools;
> +use POSIX;
>
> sub next_free_nbd_dev {
>
> @@ -23,6 +24,55 @@ sub next_free_nbd_dev {
> die "unable to find free nbd device\n";
> }
>
> +sub get_elf_class {
> + my ($rootfs, $binary_fn) = @_;
> +
> + my $child = fork();
> +
> + if (!defined($child)) {
> + die "get_elf_class - fork failed: $!\n";
> + } elsif ($child == 0) {
> + eval {
> + # chroot avoids a problem where we check the binary of the host system
> + # if $binary_fn is an absolut symlink (e.g. $rootfs/bin/sh -> /bin/bash)
> + chroot($rootfs) or die "chroot '$rootfs' failed: $!\n";
> +
> + my $fh;
> + open($fh, "<", $binary_fn) or die "open '$binary_fn' failed: $!\n";
> + binmode($fh);
> +
> + my $data;
> +
> + my $length = read($fh, $data, 5);
> + die "read failed: $!\n" if !defined($length);
> +
> + # 4 bytes ELF magic number and 1 byte ELF class
> + my ($magic, $class) = unpack("A4C", $data);
> +
> + die "'$binary_fn' does not resolve to an ELF!\n"
> + if (!defined($class) || !defined($magic) || $magic ne "\177ELF");
> +
> + die "'$binary_fn' has unknown ELF class '$class'!\n"
> + if ($class != 1 && $class != 2);
> +
> + POSIX::_exit($class) # tell parent the elf class via exit code
> + };
> + warn $@;
should be:
warn $@ if $@;
?
More information about the pve-devel
mailing list