From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id AD2D01FF1A6 for ; Mon, 29 Sep 2025 14:59:02 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 444CD11DC5; Mon, 29 Sep 2025 14:59:01 +0200 (CEST) From: Fiona Ebner To: pve-devel@lists.proxmox.com Date: Mon, 29 Sep 2025 14:56:48 +0200 Message-ID: <20250929125852.102343-4-f.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20250929125852.102343-1-f.ebner@proxmox.com> References: <20250929125852.102343-1-f.ebner@proxmox.com> MIME-Version: 1.0 X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1759150716711 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.022 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH qemu-server v2 3/6] introduce dedicated cfg2cmd module X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" Having a dedicated Cfg2Cmd class allows having a cleaner interface by only calling into pre-defined methods. Important, global information about the VM like machine type or OS version will be recorded by the object and can be queried via methods. For now, there is only windows_version(). There will be sub-classes, each concerning a dedicated part of the configuration. The first one is for the timer. Signed-off-by: Fiona Ebner --- Changes in v2: * Actually commit new Makefile in Cfg2Cmd directory. * Rename $self -> $cfg2cmd in Timer.pm submodule to avoid potential confusion. src/PVE/QemuServer.pm | 32 +++------- src/PVE/QemuServer/Cfg2Cmd.pm | 91 +++++++++++++++++++++++++++++ src/PVE/QemuServer/Cfg2Cmd/Makefile | 9 +++ src/PVE/QemuServer/Cfg2Cmd/Timer.pm | 37 ++++++++++++ src/PVE/QemuServer/Makefile | 2 + 5 files changed, 146 insertions(+), 25 deletions(-) create mode 100644 src/PVE/QemuServer/Cfg2Cmd.pm create mode 100644 src/PVE/QemuServer/Cfg2Cmd/Makefile create mode 100644 src/PVE/QemuServer/Cfg2Cmd/Timer.pm diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index 7d5ab718..cb7755b6 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -56,6 +56,7 @@ use PVE::QemuMigrate::Helpers; use PVE::QemuServer::Agent qw(qga_check_running); 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); use PVE::QemuServer::Cloudinit; @@ -3569,31 +3570,12 @@ sub config_to_command { push @$cmd, '-nographic'; } - # time drift fix - my $tdf = defined($conf->{tdf}) ? $conf->{tdf} : $defaults->{tdf}; - my $useLocaltime = $conf->{localtime}; - - if ($winversion >= 5) { # windows - $useLocaltime = 1 if !defined($conf->{localtime}); - - # use time drift fix when acpi is enabled - if (!(defined($conf->{acpi}) && $conf->{acpi} == 0)) { - $tdf = 1 if !defined($conf->{tdf}); - } - } - - if ($winversion >= 6) { - push $cmd->@*, '-global', 'kvm-pit.lost_tick_policy=discard'; - push @$machineFlags, 'hpet=off'; - } - - push @$rtcFlags, 'driftfix=slew' if $tdf; - - if ($conf->{startdate} && $conf->{startdate} ne 'now') { - push @$rtcFlags, "base=$conf->{startdate}"; - } elsif ($useLocaltime) { - push @$rtcFlags, 'base=localtime'; - } + # For now, handles only specific parts, but the final goal is to cover everything. + my $cfg2cmd = PVE::QemuServer::Cfg2Cmd->new($conf, $defaults); + my $generated = $cfg2cmd->generate(); + push $cmd->@*, '-global', $_ for ($generated->global_flags() // [])->@*; + push $machineFlags->@*, ($generated->machine_flags() // [])->@*; + push $rtcFlags->@*, ($generated->rtc_flags() // [])->@*; if ($forcecpu) { push @$cmd, '-cpu', $forcecpu; diff --git a/src/PVE/QemuServer/Cfg2Cmd.pm b/src/PVE/QemuServer/Cfg2Cmd.pm new file mode 100644 index 00000000..6b26ab23 --- /dev/null +++ b/src/PVE/QemuServer/Cfg2Cmd.pm @@ -0,0 +1,91 @@ +package PVE::QemuServer::Cfg2Cmd; + +use warnings; +use strict; + +use PVE::QemuServer::Cfg2Cmd::Timer; +use PVE::QemuServer::Helpers; + +sub new { + my ($class, $conf, $defaults) = @_; + + my $self = bless { + conf => $conf, + defaults => $defaults, + }, $class; + + my $ostype = $self->get_prop('ostype'); + $self->{'windows-version'} = PVE::QemuServer::Helpers::windows_version($ostype); + + return $self; +} + +=head3 get_prop + + my $value = $self->get_prop($prop); + +Return the configured value for the property C<$prop>. If no fallback to the default value should be +made, use C<$only_explicit>. Note that any such usage is likely an indication that the default value +is not actually a static default, but that the default depends on context. + +=cut + +sub get_prop { + my ($self, $prop, $only_explicit) = @_; + + my ($conf, $defaults) = $self->@{qw(conf defaults)}; + return $conf->{$prop} if $only_explicit; + return defined($conf->{$prop}) ? $conf->{$prop} : $defaults->{$prop}; +} + +sub add_global_flag { + my ($self, $flag) = @_; + + push $self->{'global-flags'}->@*, $flag; +} + +sub global_flags { + my ($self) = @_; + + return $self->{'global-flags'}; +} + +sub add_machine_flag { + my ($self, $flag) = @_; + + push $self->{'machine-flags'}->@*, $flag; +} + +sub machine_flags { + my ($self) = @_; + + return $self->{'machine-flags'}; +} + +sub add_rtc_flag { + my ($self, $flag) = @_; + + push $self->{'rtc-flags'}->@*, $flag; +} + +sub rtc_flags { + my ($self) = @_; + + return $self->{'rtc-flags'}; +} + +sub windows_version { + my ($self) = @_; + + return $self->{'windows-version'}; +} + +sub generate { + my ($self) = @_; + + PVE::QemuServer::Cfg2Cmd::Timer::generate($self); + + return $self; +} + +1; diff --git a/src/PVE/QemuServer/Cfg2Cmd/Makefile b/src/PVE/QemuServer/Cfg2Cmd/Makefile new file mode 100644 index 00000000..1c0ea0b2 --- /dev/null +++ b/src/PVE/QemuServer/Cfg2Cmd/Makefile @@ -0,0 +1,9 @@ +DESTDIR= +PREFIX=/usr +PERLDIR=$(PREFIX)/share/perl5 + +SOURCES=Timer.pm + +.PHONY: install +install: $(SOURCES) + for i in $(SOURCES); do install -D -m 0644 $$i $(DESTDIR)$(PERLDIR)/PVE/QemuServer/Cfg2Cmd/$$i; done diff --git a/src/PVE/QemuServer/Cfg2Cmd/Timer.pm b/src/PVE/QemuServer/Cfg2Cmd/Timer.pm new file mode 100644 index 00000000..d4b16af0 --- /dev/null +++ b/src/PVE/QemuServer/Cfg2Cmd/Timer.pm @@ -0,0 +1,37 @@ +package PVE::QemuServer::Cfg2Cmd::Timer; + +use warnings; +use strict; + +sub generate { + my ($cfg2cmd) = @_; + + my $time_drift_fix = $cfg2cmd->get_prop('tdf', 1); + my $acpi = $cfg2cmd->get_prop('acpi'); + my $localtime = $cfg2cmd->get_prop('localtime', 1); + my $startdate = $cfg2cmd->get_prop('startdate'); + + if ($cfg2cmd->windows_version() >= 5) { # windows + $localtime = 1 if !defined($localtime); + + # use time drift fix when acpi is enabled, but prefer explicitly set value + $time_drift_fix = 1 if $acpi && !defined($time_drift_fix); + } + + if ($cfg2cmd->windows_version() >= 6) { + $cfg2cmd->add_global_flag('kvm-pit.lost_tick_policy=discard'); + $cfg2cmd->add_machine_flag('hpet=off'); + } + + $cfg2cmd->add_rtc_flag('driftfix=slew') if $time_drift_fix; + + if ($startdate ne 'now') { + $cfg2cmd->add_rtc_flag("base=$startdate"); + } elsif ($localtime) { + $cfg2cmd->add_rtc_flag('base=localtime'); + } + + return; +} + +1; diff --git a/src/PVE/QemuServer/Makefile b/src/PVE/QemuServer/Makefile index 23c136bc..df56cffa 100644 --- a/src/PVE/QemuServer/Makefile +++ b/src/PVE/QemuServer/Makefile @@ -5,6 +5,7 @@ PERLDIR=$(PREFIX)/share/perl5 SOURCES=Agent.pm \ Blockdev.pm \ BlockJob.pm \ + Cfg2Cmd.pm \ CGroup.pm \ Cloudinit.pm \ CPUConfig.pm \ @@ -30,3 +31,4 @@ SOURCES=Agent.pm \ .PHONY: install install: $(SOURCES) for i in $(SOURCES); do install -D -m 0644 $$i $(DESTDIR)$(PERLDIR)/PVE/QemuServer/$$i; done + $(MAKE) -C Cfg2Cmd install -- 2.47.3 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel