Am 04.02.26 um 11:04 schrieb Dominik Csapak:
> instead of simply saving 'host_arch' in the global package namespace,
> use the PVE::Tools::get_host_arch helper, which caches the result
> anyway.
>
> For easier testing:
> * introduce our own helper for getting the host arch, which uses
> the PVE::Tools one. So we only have to mock the Tools one to get
> correct behavior in the tests. Use this everywhere here where we need
> it.
> * move the cpu_models_by_arch initialization into a sub that can be
> called by the tests to re-initialize.
>
> Signed-off-by: Dominik Csapak <[email protected]>
> ---
> changes from v1:
> * add helpers to be more easily used and mocked by the tests instead
> of modifying the module level variable
>
> src/PVE/QemuServer.pm | 5 +-
> src/PVE/QemuServer/CPUConfig.pm | 258 ++++++++++++++-------------
> src/PVE/QemuServer/Helpers.pm | 8 +-
> src/test/run_config2command_tests.pl | 8 +-
> 4 files changed, 146 insertions(+), 133 deletions(-)
>
> diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
> index 5d2dbe03..8bf23945 100644
> --- a/src/PVE/QemuServer.pm
> +++ b/src/PVE/QemuServer.pm
> @@ -46,8 +46,7 @@ use PVE::SafeSyslog;
> use PVE::Storage;
> use PVE::SysFSTools;
> use PVE::Systemd;
> -use PVE::Tools
> - qw(run_command file_read_firstline file_get_contents dir_glob_foreach
> get_host_arch $IPV6RE);
> +use PVE::Tools qw(run_command file_read_firstline file_get_contents
> dir_glob_foreach $IPV6RE);
>
> use PVE::QMPClient;
> use PVE::QemuConfig;
> @@ -58,7 +57,7 @@ use PVE::QemuServer::Blockdev;
> use PVE::QemuServer::BlockJob;
> use PVE::QemuServer::Cfg2Cmd;
> use PVE::QemuServer::Helpers
> - qw(config_aware_timeout get_iscsi_initiator_name min_version
> kvm_user_version windows_version);
> + qw(config_aware_timeout get_iscsi_initiator_name get_host_arch
> min_version kvm_user_version windows_version);
> use PVE::QemuServer::Cloudinit;
> use PVE::QemuServer::CGroup;
> use PVE::QemuServer::CPUConfig qw(
> diff --git a/src/PVE/QemuServer/CPUConfig.pm b/src/PVE/QemuServer/CPUConfig.pm
> index 32ec4954..7d5559b0 100644
> --- a/src/PVE/QemuServer/CPUConfig.pm
> +++ b/src/PVE/QemuServer/CPUConfig.pm
> @@ -11,7 +11,7 @@ use PVE::ProcFSTools;
> use PVE::RESTEnvironment qw(log_warn);
> use PVE::Tools qw(run_command);
>
> -use PVE::QemuServer::Helpers qw(min_version);
> +use PVE::QemuServer::Helpers qw(min_version get_host_arch);
>
> use base qw(PVE::SectionConfig Exporter);
>
> @@ -25,8 +25,6 @@ our @EXPORT_OK = qw(
> get_cvm_type
> );
>
> -my $host_arch = PVE::Tools::get_host_arch();
> -
> my $arch_desc = {
> description => "Virtual processor architecture. Defaults to the host
> architecture.",
> type => 'string',
> @@ -100,130 +98,138 @@ my $cputypes_32bit = {
> 'qemu32' => 1,
> };
>
> -my $cpu_models_by_arch = {
> - x86_64 => {
> - # Intel CPUs
> - 486 => 'GenuineIntel',
> - pentium => 'GenuineIntel',
> - pentium2 => 'GenuineIntel',
> - pentium3 => 'GenuineIntel',
> - coreduo => 'GenuineIntel',
> - core2duo => 'GenuineIntel',
> - Conroe => 'GenuineIntel',
> - Penryn => 'GenuineIntel',
> - Nehalem => 'GenuineIntel',
> - 'Nehalem-IBRS' => 'GenuineIntel',
> - Westmere => 'GenuineIntel',
> - 'Westmere-IBRS' => 'GenuineIntel',
> - SandyBridge => 'GenuineIntel',
> - 'SandyBridge-IBRS' => 'GenuineIntel',
> - IvyBridge => 'GenuineIntel',
> - 'IvyBridge-IBRS' => 'GenuineIntel',
> - Haswell => 'GenuineIntel',
> - 'Haswell-IBRS' => 'GenuineIntel',
> - 'Haswell-noTSX' => 'GenuineIntel',
> - 'Haswell-noTSX-IBRS' => 'GenuineIntel',
> - Broadwell => 'GenuineIntel',
> - 'Broadwell-IBRS' => 'GenuineIntel',
> - 'Broadwell-noTSX' => 'GenuineIntel',
> - 'Broadwell-noTSX-IBRS' => 'GenuineIntel',
> - 'Skylake-Client' => 'GenuineIntel',
> - 'Skylake-Client-IBRS' => 'GenuineIntel',
> - 'Skylake-Client-noTSX-IBRS' => 'GenuineIntel',
> - 'Skylake-Client-v4' => 'GenuineIntel',
> - 'Skylake-Server' => 'GenuineIntel',
> - 'Skylake-Server-IBRS' => 'GenuineIntel',
> - 'Skylake-Server-noTSX-IBRS' => 'GenuineIntel',
> - 'Skylake-Server-v4' => 'GenuineIntel',
> - 'Skylake-Server-v5' => 'GenuineIntel',
> - 'Cascadelake-Server' => 'GenuineIntel',
> - 'Cascadelake-Server-v2' => 'GenuineIntel',
> - 'Cascadelake-Server-noTSX' => 'GenuineIntel',
> - 'Cascadelake-Server-v4' => 'GenuineIntel',
> - 'Cascadelake-Server-v5' => 'GenuineIntel',
> - 'Cooperlake' => 'GenuineIntel',
> - 'Cooperlake-v2' => 'GenuineIntel',
> - KnightsMill => 'GenuineIntel',
> - 'Icelake-Client' => 'GenuineIntel', # depreacated, removed with QEMU
> 7.1
> - 'Icelake-Client-noTSX' => 'GenuineIntel', # depreacated, removed
> with QEMU 7.1
> - 'Icelake-Server' => 'GenuineIntel',
> - 'Icelake-Server-noTSX' => 'GenuineIntel',
> - 'Icelake-Server-v3' => 'GenuineIntel',
> - 'Icelake-Server-v4' => 'GenuineIntel',
> - 'Icelake-Server-v5' => 'GenuineIntel',
> - 'Icelake-Server-v6' => 'GenuineIntel',
> - 'Icelake-Server-v7' => 'GenuineIntel',
> - 'SapphireRapids' => 'GenuineIntel',
> - 'SapphireRapids-v2' => 'GenuineIntel',
> - 'SapphireRapids-v3' => 'GenuineIntel',
> - 'SapphireRapids-v4' => 'GenuineIntel',
> - 'GraniteRapids' => 'GenuineIntel',
> - 'GraniteRapids-v2' => 'GenuineIntel',
> - 'GraniteRapids-v3' => 'GenuineIntel',
> - 'SierraForest' => 'GenuineIntel',
> - 'SierraForest-v2' => 'GenuineIntel',
> - 'SierraForest-v3' => 'GenuineIntel',
> - 'ClearwaterForest' => 'GenuineIntel',
> -
> - # AMD CPUs
> - athlon => 'AuthenticAMD',
> - phenom => 'AuthenticAMD',
> - Opteron_G1 => 'AuthenticAMD',
> - Opteron_G2 => 'AuthenticAMD',
> - Opteron_G3 => 'AuthenticAMD',
> - Opteron_G4 => 'AuthenticAMD',
> - Opteron_G5 => 'AuthenticAMD',
> - EPYC => 'AuthenticAMD',
> - 'EPYC-IBPB' => 'AuthenticAMD',
> - 'EPYC-v3' => 'AuthenticAMD',
> - 'EPYC-v4' => 'AuthenticAMD',
> - 'EPYC-v5' => 'AuthenticAMD',
> - 'EPYC-Rome' => 'AuthenticAMD',
> - 'EPYC-Rome-v2' => 'AuthenticAMD',
> - 'EPYC-Rome-v3' => 'AuthenticAMD',
> - 'EPYC-Rome-v4' => 'AuthenticAMD',
> - 'EPYC-Rome-v5' => 'AuthenticAMD',
> - 'EPYC-Milan' => 'AuthenticAMD',
> - 'EPYC-Milan-v2' => 'AuthenticAMD',
> - 'EPYC-Milan-v3' => 'AuthenticAMD',
> - 'EPYC-Genoa' => 'AuthenticAMD',
> - 'EPYC-Genoa-v2' => 'AuthenticAMD',
> - 'EPYC-Turin' => 'AuthenticAMD',
> -
> - # generic types, use vendor from host node
> - kvm32 => 'default',
> - kvm64 => 'default',
> - qemu32 => 'default',
> - qemu64 => 'default',
> - max => 'default',
> - },
> - aarch64 => {
> - 'a64fx' => 'ARM',
> - 'cortex-a35' => 'ARM',
> - 'cortex-a53' => 'ARM',
> - 'cortex-a55' => 'ARM',
> - 'cortex-a57' => 'ARM',
> - 'cortex-a710' => 'ARM',
> - 'cortex-a72' => 'ARM',
> - 'cortex-a76' => 'ARM',
> - 'neoverse-n1' => 'ARM',
> - 'neoverse-n2' => 'ARM',
> - 'neoverse-v1' => 'ARM',
> - # 32 bit and deprecated models were not added
> - max => 'default',
> - },
> -};
> +my $cpu_models_by_arch;
> +my $all_cpu_models;
>
> -# The host CPU model only exists if the arch matches
> -$cpu_models_by_arch->{$host_arch}->{host} = 'default';
> +# helper to make it easier for testing
> +sub initialize_cpu_models {
> + $cpu_models_by_arch = {
> + x86_64 => {
> + # Intel CPUs
> + 486 => 'GenuineIntel',
> + pentium => 'GenuineIntel',
> + pentium2 => 'GenuineIntel',
> + pentium3 => 'GenuineIntel',
> + coreduo => 'GenuineIntel',
> + core2duo => 'GenuineIntel',
> + Conroe => 'GenuineIntel',
> + Penryn => 'GenuineIntel',
> + Nehalem => 'GenuineIntel',
> + 'Nehalem-IBRS' => 'GenuineIntel',
> + Westmere => 'GenuineIntel',
> + 'Westmere-IBRS' => 'GenuineIntel',
> + SandyBridge => 'GenuineIntel',
> + 'SandyBridge-IBRS' => 'GenuineIntel',
> + IvyBridge => 'GenuineIntel',
> + 'IvyBridge-IBRS' => 'GenuineIntel',
> + Haswell => 'GenuineIntel',
> + 'Haswell-IBRS' => 'GenuineIntel',
> + 'Haswell-noTSX' => 'GenuineIntel',
> + 'Haswell-noTSX-IBRS' => 'GenuineIntel',
> + Broadwell => 'GenuineIntel',
> + 'Broadwell-IBRS' => 'GenuineIntel',
> + 'Broadwell-noTSX' => 'GenuineIntel',
> + 'Broadwell-noTSX-IBRS' => 'GenuineIntel',
> + 'Skylake-Client' => 'GenuineIntel',
> + 'Skylake-Client-IBRS' => 'GenuineIntel',
> + 'Skylake-Client-noTSX-IBRS' => 'GenuineIntel',
> + 'Skylake-Client-v4' => 'GenuineIntel',
> + 'Skylake-Server' => 'GenuineIntel',
> + 'Skylake-Server-IBRS' => 'GenuineIntel',
> + 'Skylake-Server-noTSX-IBRS' => 'GenuineIntel',
> + 'Skylake-Server-v4' => 'GenuineIntel',
> + 'Skylake-Server-v5' => 'GenuineIntel',
> + 'Cascadelake-Server' => 'GenuineIntel',
> + 'Cascadelake-Server-v2' => 'GenuineIntel',
> + 'Cascadelake-Server-noTSX' => 'GenuineIntel',
> + 'Cascadelake-Server-v4' => 'GenuineIntel',
> + 'Cascadelake-Server-v5' => 'GenuineIntel',
> + 'Cooperlake' => 'GenuineIntel',
> + 'Cooperlake-v2' => 'GenuineIntel',
> + KnightsMill => 'GenuineIntel',
> + 'Icelake-Client' => 'GenuineIntel', # depreacated, removed with
> QEMU 7.1
> + 'Icelake-Client-noTSX' => 'GenuineIntel', # depreacated, removed
> with QEMU 7.1
> + 'Icelake-Server' => 'GenuineIntel',
> + 'Icelake-Server-noTSX' => 'GenuineIntel',
> + 'Icelake-Server-v3' => 'GenuineIntel',
> + 'Icelake-Server-v4' => 'GenuineIntel',
> + 'Icelake-Server-v5' => 'GenuineIntel',
> + 'Icelake-Server-v6' => 'GenuineIntel',
> + 'Icelake-Server-v7' => 'GenuineIntel',
> + 'SapphireRapids' => 'GenuineIntel',
> + 'SapphireRapids-v2' => 'GenuineIntel',
> + 'SapphireRapids-v3' => 'GenuineIntel',
> + 'SapphireRapids-v4' => 'GenuineIntel',
> + 'GraniteRapids' => 'GenuineIntel',
> + 'GraniteRapids-v2' => 'GenuineIntel',
> + 'GraniteRapids-v3' => 'GenuineIntel',
> + 'SierraForest' => 'GenuineIntel',
> + 'SierraForest-v2' => 'GenuineIntel',
> + 'SierraForest-v3' => 'GenuineIntel',
> + 'ClearwaterForest' => 'GenuineIntel',
> +
> + # AMD CPUs
> + athlon => 'AuthenticAMD',
> + phenom => 'AuthenticAMD',
> + Opteron_G1 => 'AuthenticAMD',
> + Opteron_G2 => 'AuthenticAMD',
> + Opteron_G3 => 'AuthenticAMD',
> + Opteron_G4 => 'AuthenticAMD',
> + Opteron_G5 => 'AuthenticAMD',
> + EPYC => 'AuthenticAMD',
> + 'EPYC-IBPB' => 'AuthenticAMD',
> + 'EPYC-v3' => 'AuthenticAMD',
> + 'EPYC-v4' => 'AuthenticAMD',
> + 'EPYC-v5' => 'AuthenticAMD',
> + 'EPYC-Rome' => 'AuthenticAMD',
> + 'EPYC-Rome-v2' => 'AuthenticAMD',
> + 'EPYC-Rome-v3' => 'AuthenticAMD',
> + 'EPYC-Rome-v4' => 'AuthenticAMD',
> + 'EPYC-Rome-v5' => 'AuthenticAMD',
> + 'EPYC-Milan' => 'AuthenticAMD',
> + 'EPYC-Milan-v2' => 'AuthenticAMD',
> + 'EPYC-Milan-v3' => 'AuthenticAMD',
> + 'EPYC-Genoa' => 'AuthenticAMD',
> + 'EPYC-Genoa-v2' => 'AuthenticAMD',
> + 'EPYC-Turin' => 'AuthenticAMD',
> +
> + # generic types, use vendor from host node
> + kvm32 => 'default',
> + kvm64 => 'default',
> + qemu32 => 'default',
> + qemu64 => 'default',
> + max => 'default',
> + },
> + aarch64 => {
> + 'a64fx' => 'ARM',
> + 'cortex-a35' => 'ARM',
> + 'cortex-a53' => 'ARM',
> + 'cortex-a55' => 'ARM',
> + 'cortex-a57' => 'ARM',
> + 'cortex-a710' => 'ARM',
> + 'cortex-a72' => 'ARM',
> + 'cortex-a76' => 'ARM',
> + 'neoverse-n1' => 'ARM',
> + 'neoverse-n2' => 'ARM',
> + 'neoverse-v1' => 'ARM',
> + # 32 bit and deprecated models were not added
> + max => 'default',
> + },
> + };
>
> -my $all_cpu_models;
> -for my $arch (keys $cpu_models_by_arch->%*) {
> - for my $model (keys $cpu_models_by_arch->{$arch}->%*) {
> - $all_cpu_models->{$model} = $cpu_models_by_arch->{$arch}->{$model};
> + my $host_arch = get_host_arch();
> + # The host CPU model only exists if the arch matches
> + $cpu_models_by_arch->{$host_arch}->{host} = 'default';
> +
> + for my $arch (keys $cpu_models_by_arch->%*) {
> + for my $model (keys $cpu_models_by_arch->{$arch}->%*) {
> + $all_cpu_models->{$model} =
> $cpu_models_by_arch->{$arch}->{$model};
> + }
> }
> }
>
> +initialize_cpu_models();
this now still always does this on module load, would be nicer to actually
only pay for that if needed by adding getter methods for each variable, like
sub get_all_cpu_models {
initialize_cpu_models() if !defined($all_cpu_models);
return $all_cpu_models;
}
Same with a get_cpu_models_by_arch getter.
And I'd split this and the host_arch change into separate patches, they are
rather
unrelated to each other.