[pve-devel] [RFC pve-container 1/2] detect_architecture: use ELF mach9ine header to detect ISA

Dietmar Maurer dietmar at proxmox.com
Fri Sep 14 13:31:02 CEST 2018


We can now detect arm64 containers.

Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
 src/PVE/LXC/Config.pm |  2 +-
 src/PVE/LXC/Create.pm | 22 +++++++++++++---------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 3b1e2df..196cfac 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -295,7 +295,7 @@ my $confdesc = {
     arch => {
 	optional => 1,
 	type => 'string',
-	enum => ['amd64', 'i386'],
+	enum => ['amd64', 'i386', 'arm64'],
 	description => "OS architecture type.",
 	default => 'amd64',
     },
diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm
index cf73dba..1bb60bc 100644
--- a/src/PVE/LXC/Create.pm
+++ b/src/PVE/LXC/Create.pm
@@ -17,9 +17,12 @@ use POSIX;
 sub detect_architecture {
     my ($rootdir) = @_;
 
-    my $supported_elf_class = {
-	1 => 'i386',
-	2 => 'amd64',
+    # see https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
+
+    my $supported_elf_machine = {
+	0x03 => 'i386',
+	0x3e => 'amd64',
+	0xb7 => 'arm64',
     };
 
     my $elf_fn = '/bin/sh'; # '/bin/sh' is POSIX mandatory
@@ -32,18 +35,19 @@ sub detect_architecture {
 	open(my $fh, "<", $elf_fn) or die "open '$elf_fn' failed: $!\n";
 	binmode($fh);
 
-	my $length = read($fh, my $data, 5) or die "read failed: $!\n";
+	my $length = read($fh, my $data, 20) or die "read failed: $!\n";
 
-	# 4 bytes ELF magic number and 1 byte ELF class
-	my ($magic, $class) = unpack("A4C", $data);
+	# 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");
 
-	die "'$elf_fn' has unknown ELF class '$class'!\n"
-	    if !defined($supported_elf_class->{$class});
+	my $arch = $supported_elf_machine->{$machine};
+	die "'$elf_fn' has unknown ELF machine '$machine'!\n"
+	    if !defined($arch);
 
-	return $supported_elf_class->{$class};
+	return $arch;
     };
 
     my $arch = eval { PVE::Tools::run_fork_with_timeout(5, $detect_arch) };
-- 
2.11.0



More information about the pve-devel mailing list