]> git.proxmox.com Git - pve-container.git/commitdiff
Merge branch 'c.heiss/nixos/fix-arch-detection'
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 17 Nov 2023 15:44:45 +0000 (16:44 +0100)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 17 Nov 2023 15:46:16 +0000 (16:46 +0100)
resolved conflict with b58ba5d4494c ("drop old mount code")

1  2 
src/PVE/LXC/Tools.pm

index 62cdbc14b8159b722225a3508399dfcfa82de1ce,fdda4e3a7de36fd7b1656331315666ba6ea2713c..0ff56e8e0e1ce95161e8f8e72dd8ec6f8f9e7f38
@@@ -132,4 -134,70 +132,54 @@@ sub cgroup_do_write($$) 
      return 1;
  }
  
 -# Check whether the kernel supports the new mount api. This is used in the pre-start hook and in
 -# the hotplugging code.
 -my $cached_can_use_new_mount_api = undef;
 -sub can_use_new_mount_api() {
 -    if (!defined($cached_can_use_new_mount_api)) {
 -      if (PVE::Tools::move_mount(-1, 0, -1, 0, 0)) {
 -          # This should not be possible...
 -          die "kernel behaved unexpectedly: move_mount(-1, NULL, -1, NULL) did not fail!\n";
 -      }
 -      # On older kernels the syscall doesn't exist and we get ENOSYS. (For newer kernels this call
 -      # will fail with EFAULT instead, since we pass in a NULL pointer as file system name.)
 -      $cached_can_use_new_mount_api = ($! != ENOSYS);
 -    }
 -    return $cached_can_use_new_mount_api;
 -}
 -
+ # Tries to the architecture of an executable file based on its ELF header.
+ sub detect_elf_architecture {
+     my ($elf_fn) = @_;
+     # see https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
+     my $supported_elf_machine = {
+       0x03 => 'i386',
+       0x3e => 'amd64',
+       0x28 => 'armhf',
+       0xb7 => 'arm64',
+       0xf3 => 'riscv',
+     };
+     my $detect_arch = sub {
+       open(my $fh, "<", $elf_fn) or die "open '$elf_fn' failed: $!\n";
+       binmode($fh);
+       my $length = read($fh, my $data, 20) or die "read failed: $!\n";
+       # 4 bytes ELF magic number and 1 byte ELF class, padding, machine
+       my ($magic, $class, undef, $machine) = unpack("A4CA12n", $data);
+       die "'$elf_fn' does not resolve to an ELF!\n"
+           if (!defined($class) || !defined($magic) || $magic ne "\177ELF");
+       my $arch = $supported_elf_machine->{$machine};
+       die "'$elf_fn' has unknown ELF machine '$machine'!\n"
+           if !defined($arch);
+       if ($arch eq 'riscv') {
+           if ($class eq 1) {
+               $arch = 'riscv32';
+           } elsif ($class eq 2) {
+               $arch = 'riscv64';
+           } else {
+               die "'$elf_fn' has invalid class '$class'!\n";
+           }
+       }
+       return $arch;
+     };
+     my $arch = eval { PVE::Tools::run_fork_with_timeout(10, $detect_arch); };
+     my $err = $@ // "timeout\n";
+     die $err if !defined($arch);
+     return $arch;
+ }
  1;