[pve-devel] [PATCH container v3] Create: fix architecture detection in restore_archive

Thomas Lamprecht t.lamprecht at proxmox.com
Tue Dec 20 11:59:13 CET 2016



On 12/20/2016 11:48 AM, Dietmar Maurer wrote:
>
>> 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 $@;
>
> ?

I "optimized" the "if $@" away as this only gets reached when we die in 
the eval,
and so $@ is always set here.
If we do not die the POSIX::_exit($class) ensures that we do not reach 
this point.

Or should I let the if stay nonetheless, just to be sure?




More information about the pve-devel mailing list