forked from Proxmox-Port/Proxmox-Port
110 lines
3.2 KiB
Diff
110 lines
3.2 KiB
Diff
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
|
|
index 1664a35..73f60f0 100644
|
|
--- a/src/PVE/LXC/Config.pm
|
|
+++ b/src/PVE/LXC/Config.pm
|
|
@@ -473,7 +473,7 @@ my $confdesc = {
|
|
arch => {
|
|
optional => 1,
|
|
type => 'string',
|
|
- enum => ['amd64', 'i386', 'arm64', 'armhf', 'riscv32', 'riscv64'],
|
|
+ enum => ['amd64', 'i386', 'arm64', 'armhf', 'riscv32', 'riscv64', 'loongarch64'],
|
|
description => "OS architecture type.",
|
|
default => 'amd64',
|
|
},
|
|
diff --git a/src/PVE/LXC/Setup.pm b/src/PVE/LXC/Setup.pm
|
|
index 5c9114c..cae55b1 100644
|
|
--- a/src/PVE/LXC/Setup.pm
|
|
+++ b/src/PVE/LXC/Setup.pm
|
|
@@ -135,17 +135,6 @@ sub new {
|
|
if (!defined($conf->{arch})) {
|
|
my $arch = eval { $self->protected_call(sub { $plugin->detect_architecture() }) };
|
|
|
|
- if (my $err = $@) {
|
|
- warn "Architecture detection failed: $err" if $err;
|
|
- }
|
|
-
|
|
- if (!defined($arch)) {
|
|
- $arch = 'amd64';
|
|
- print "Falling back to $arch.\nUse `pct set VMID --arch ARCH` to change.\n";
|
|
- } else {
|
|
- print "Detected container architecture: $arch\n";
|
|
- }
|
|
-
|
|
$conf->{arch} = $arch;
|
|
}
|
|
|
|
diff --git a/src/PVE/LXC/Setup/Plugin.pm b/src/PVE/LXC/Setup/Plugin.pm
|
|
index b9d9c2d..533afe0 100644
|
|
--- a/src/PVE/LXC/Setup/Plugin.pm
|
|
+++ b/src/PVE/LXC/Setup/Plugin.pm
|
|
@@ -6,6 +6,7 @@ use strict;
|
|
use warnings;
|
|
|
|
use Carp;
|
|
+use PVE::Tools;
|
|
|
|
sub new {
|
|
my ($class, $conf, $rootdir, $os_release) = @_;
|
|
@@ -64,7 +65,48 @@ sub ssh_host_key_types_to_generate {
|
|
|
|
sub detect_architecture {
|
|
my ($self) = @_;
|
|
- croak "implement me in sub-class\n";
|
|
+ # see https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
|
+ my $supported_elf_machine = {
|
|
+ 0x03 => 'i386',
|
|
+ 0x3e => 'amd64',
|
|
+ 0x28 => 'armhf',
|
|
+ 0xb7 => 'arm64',
|
|
+ 0xf3 => 'riscv',
|
|
+ 0x2 => 'loongarch64',
|
|
+ };
|
|
+
|
|
+ my $elf_fn = '/bin/sh'; # '/bin/sh' is POSIX mandatory
|
|
+ my $detect_arch = sub {
|
|
+ # chroot avoids a problem where we check the binary of the host system
|
|
+ # if $elf_fn is an absolut symlink (e.g. $rootdir/bin/sh -> /bin/bash)
|
|
+ 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);
|
|
+
|
|
+ return $arch;
|
|
+ };
|
|
+
|
|
+ my $arch = eval { PVE::Tools::run_fork_with_timeout(5, $detect_arch) };
|
|
+ if (my $err = $@) {
|
|
+ $arch = 'arm64';
|
|
+ print "Architecture detection failed: $err\nFalling back to loongarch64.\n" .
|
|
+ "Use `pct set VMID --arch ARCH` to change.\n";
|
|
+ } else {
|
|
+ print "Detected container architecture: $arch\n";
|
|
+ }
|
|
+
|
|
+ return $arch;
|
|
}
|
|
|
|
# hooks
|
|
diff --git a/src/PVE/LXC/Tools.pm b/src/PVE/LXC/Tools.pm
|
|
index 7e3e530..838327f 100644
|
|
--- a/src/PVE/LXC/Tools.pm
|
|
+++ b/src/PVE/LXC/Tools.pm
|
|
@@ -179,6 +179,7 @@ sub detect_elf_architecture {
|
|
0x28 => 'armhf',
|
|
0xb7 => 'arm64',
|
|
0xf3 => 'riscv',
|
|
+ 0x2 => 'loongarch64',
|
|
};
|
|
|
|
my $detect_arch = sub {
|