* [PATCH qemu-server 1/4] agent: add should_fs_freeze helper
2026-03-25 20:49 [PATCH qemu-server 0/4] rework fs-freeze agent property Thomas Lamprecht
@ 2026-03-25 20:49 ` Thomas Lamprecht
2026-03-25 20:49 ` [PATCH qemu-server 2/4] agent: treat freeze-fs-on-backup as alias for guest-fsfreeze Thomas Lamprecht
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Thomas Lamprecht @ 2026-03-25 20:49 UTC (permalink / raw)
To: pve-devel
Add a centralized helper that checks whether guest filesystem
freeze/thaw should be attempted, combining the agent-enabled and
guest-fsfreeze setting checks. This replaces duplicated inline logic
and the scattered '// 1' default fallback across call sites.
No behavioral change intended, the helper returns the same result as
the previous inline expressions.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
src/PVE/API2/Qemu.pm | 10 ++++------
src/PVE/QemuConfig.pm | 5 ++---
src/PVE/QemuServer/Agent.pm | 15 +++++++++++++++
3 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
index b409610c..020c68b2 100644
--- a/src/PVE/API2/Qemu.pm
+++ b/src/PVE/API2/Qemu.pm
@@ -374,8 +374,7 @@ my $import_from_volid = sub {
my ($src_storeid) = PVE::Storage::parse_volume_id($src_volid);
- my $qga = $src_conf->{agent}
- && (PVE::QemuServer::Agent::get_qga_key($src_conf, 'guest-fsfreeze') // 1);
+ my $fs_freeze = PVE::QemuServer::Agent::should_fs_freeze($src_conf);
return PVE::QemuServer::clone_disk(
$storecfg,
@@ -385,7 +384,7 @@ my $import_from_volid = sub {
$vollist,
undef,
undef,
- $qga,
+ $fs_freeze,
PVE::Storage::get_bandwidth_limit('clone', [$src_storeid, $dest_info->{storage}]),
);
};
@@ -4562,8 +4561,7 @@ __PACKAGE__->register_method({
$dest_info->{efisize} = PVE::QemuServer::get_efivars_size($oldconf)
if $opt eq 'efidisk0';
- my $qga = $oldconf->{agent}
- && (PVE::QemuServer::Agent::get_qga_key($oldconf, 'guest-fsfreeze') // 1);
+ my $fs_freeze = PVE::QemuServer::Agent::should_fs_freeze($oldconf);
my $newdrive = PVE::QemuServer::clone_disk(
$storecfg,
@@ -4573,7 +4571,7 @@ __PACKAGE__->register_method({
$newvollist,
$jobs,
$completion,
- $qga,
+ $fs_freeze,
$clonelimit,
);
diff --git a/src/PVE/QemuConfig.pm b/src/PVE/QemuConfig.pm
index 462d1d6d..839b6cd0 100644
--- a/src/PVE/QemuConfig.pm
+++ b/src/PVE/QemuConfig.pm
@@ -297,9 +297,8 @@ sub __snapshot_check_freeze_needed {
return (
$running,
$running
- && PVE::QemuServer::Agent::get_qga_key($config, 'enabled')
- && PVE::QemuServer::Agent::qga_check_running($vmid)
- && (PVE::QemuServer::Agent::get_qga_key($config, 'guest-fsfreeze') // 1),
+ && PVE::QemuServer::Agent::should_fs_freeze($config)
+ && PVE::QemuServer::Agent::qga_check_running($vmid),
);
} else {
return ($running, 0);
diff --git a/src/PVE/QemuServer/Agent.pm b/src/PVE/QemuServer/Agent.pm
index fb3e1835..4bc7cfa1 100644
--- a/src/PVE/QemuServer/Agent.pm
+++ b/src/PVE/QemuServer/Agent.pm
@@ -202,6 +202,21 @@ sub qemu_exec_status {
return $res;
}
+=head3 should_fs_freeze
+
+Returns whether guest filesystem freeze/thaw should be attempted based on the agent configuration.
+Does B<not> check whether the agent is actually running.
+
+=cut
+
+sub should_fs_freeze {
+ my ($conf) = @_;
+
+ my $agent = parse_guest_agent($conf);
+ return 0 if !$agent->{enabled};
+ return $agent->{'guest-fsfreeze'} // 1;
+}
+
=head3 guest_fsfreeze
guest_fsfreeze($vmid);
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH qemu-server 2/4] agent: treat freeze-fs-on-backup as alias for guest-fsfreeze
2026-03-25 20:49 [PATCH qemu-server 0/4] rework fs-freeze agent property Thomas Lamprecht
2026-03-25 20:49 ` [PATCH qemu-server 1/4] agent: add should_fs_freeze helper Thomas Lamprecht
@ 2026-03-25 20:49 ` Thomas Lamprecht
2026-03-25 20:49 ` [PATCH qemu-server 3/4] tests: cfg2cmd: add agent guest-fsfreeze config tests Thomas Lamprecht
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Thomas Lamprecht @ 2026-03-25 20:49 UTC (permalink / raw)
To: pve-devel
Alias the deprecated key to 'guest-fsfreeze' through the JSONSchema
alias key support so consumers see a single, consistent value.
Previously only the backup code path fell back to it, while snapshots,
replications, clones and imports silently ignored it.
Note that while alias support for top-level JSON schema has a bug [0],
the one for property strings - which this here is - works out fine.
[0]: https://lore.proxmox.com/all/20251205100317.1101549-1-d.csapak@proxmox.com/
The key stays in the schema indefinitely for old backup restore
compatibility rather than being removed in a future major release.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
src/PVE/QemuServer/Agent.pm | 15 ++++++---------
src/PVE/VZDump/QemuServer.pm | 7 +------
2 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/src/PVE/QemuServer/Agent.pm b/src/PVE/QemuServer/Agent.pm
index 4bc7cfa1..c0315a03 100644
--- a/src/PVE/QemuServer/Agent.pm
+++ b/src/PVE/QemuServer/Agent.pm
@@ -35,25 +35,21 @@ our $agent_fmt = {
optional => 1,
default => 0,
},
- # TODO Remove for Proxmox VE 10
'freeze-fs-on-backup' => {
- description => "Deprecated: Use 'guest-fsfreeze' instead.\n\n"
- . "Freeze/thaw guest filesystems on backup for consistency.",
type => 'boolean',
optional => 1,
- default => 1,
+ alias => 'guest-fsfreeze', # keep for old backup restore compatibility
},
'guest-fsfreeze' => {
- description =>
- "Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent"
- . " commands.",
+ description => "Freeze guest filesystems through QGA for consistent disk state on"
+ . " operations such as snapshots, backups, replications and clones.",
verbose_description =>
"Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent"
. " commands. Backups in snapshot mode, clones, snapshots without RAM, importing"
. " disks from a running guest, and replications normally issue a guest-fsfreeze-freeze"
. " and a respective thaw command when the QEMU Guest agent option is enabled in the"
- . " guest's configuration and the agent is running inside of the guest.\n\nWhen set, it"
- . " will take precedence over 'freeze-fs-on-backup'.",
+ . " guest's configuration and the agent is running inside of the guest.\n\nThe deprecated"
+ . " 'freeze-fs-on-backup' setting is treated as an alias for this setting.",
type => 'boolean',
optional => 1,
default => 1,
@@ -77,6 +73,7 @@ sub parse_guest_agent {
# if the agent is disabled ignore the other potentially set properties
return {} if !$res->{enabled};
+
return $res;
}
diff --git a/src/PVE/VZDump/QemuServer.pm b/src/PVE/VZDump/QemuServer.pm
index 55fb6dc4..925172f4 100644
--- a/src/PVE/VZDump/QemuServer.pm
+++ b/src/PVE/VZDump/QemuServer.pm
@@ -1102,12 +1102,7 @@ sub qga_fs_freeze {
return;
}
- my $freeze = PVE::QemuServer::Agent::get_qga_key($self->{vmlist}->{$vmid}, 'guest-fsfreeze');
- $freeze //=
- PVE::QemuServer::Agent::get_qga_key($self->{vmlist}->{$vmid}, 'freeze-fs-on-backup');
- $freeze //= 1;
-
- if (!$freeze) {
+ if (!PVE::QemuServer::Agent::should_fs_freeze($self->{vmlist}->{$vmid})) {
$self->loginfo("skipping guest-agent 'fs-freeze', disabled in VM options");
return;
}
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH qemu-server 3/4] tests: cfg2cmd: add agent guest-fsfreeze config tests
2026-03-25 20:49 [PATCH qemu-server 0/4] rework fs-freeze agent property Thomas Lamprecht
2026-03-25 20:49 ` [PATCH qemu-server 1/4] agent: add should_fs_freeze helper Thomas Lamprecht
2026-03-25 20:49 ` [PATCH qemu-server 2/4] agent: treat freeze-fs-on-backup as alias for guest-fsfreeze Thomas Lamprecht
@ 2026-03-25 20:49 ` Thomas Lamprecht
2026-03-25 20:49 ` [PATCH qemu-server 4/4] qga: rename guest-fsfreeze to freeze-fs Thomas Lamprecht
2026-03-25 21:35 ` superseded: [PATCH qemu-server 0/4] rework fs-freeze agent property Thomas Lamprecht
4 siblings, 0 replies; 6+ messages in thread
From: Thomas Lamprecht @ 2026-03-25 20:49 UTC (permalink / raw)
To: pve-devel
Ensure the different agent sub-property variants, including the
deprecated freeze-fs-on-backup key, are parsed without affecting
the QEMU command line.
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
.../cfg2cmd/qga-fs-freeze-backup-legacy.conf | 2 ++
.../qga-fs-freeze-backup-legacy.conf.cmd | 29 +++++++++++++++++++
src/test/cfg2cmd/qga-fs-freeze.conf | 2 ++
src/test/cfg2cmd/qga-fs-freeze.conf.cmd | 29 +++++++++++++++++++
src/test/cfg2cmd/qga-minimal.conf | 2 ++
src/test/cfg2cmd/qga-minimal.conf.cmd | 29 +++++++++++++++++++
6 files changed, 93 insertions(+)
create mode 100644 src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf
create mode 100644 src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf.cmd
create mode 100644 src/test/cfg2cmd/qga-fs-freeze.conf
create mode 100644 src/test/cfg2cmd/qga-fs-freeze.conf.cmd
create mode 100644 src/test/cfg2cmd/qga-minimal.conf
create mode 100644 src/test/cfg2cmd/qga-minimal.conf.cmd
diff --git a/src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf b/src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf
new file mode 100644
index 00000000..14ef474d
--- /dev/null
+++ b/src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf
@@ -0,0 +1,2 @@
+# TEST: Ensure the deprecated freeze-fs-on-backup agent key is still parsed.
+agent: enabled=1,freeze-fs-on-backup=0
diff --git a/src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf.cmd b/src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf.cmd
new file mode 100644
index 00000000..41b185e0
--- /dev/null
+++ b/src/test/cfg2cmd/qga-fs-freeze-backup-legacy.conf.cmd
@@ -0,0 +1,29 @@
+/usr/bin/kvm \
+ -id 8006 \
+ -name 'vm8006,debug-threads=on' \
+ -no-shutdown \
+ -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+ -mon 'chardev=qmp,mode=control' \
+ -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \
+ -mon 'chardev=qmp-event,mode=control' \
+ -pidfile /var/run/qemu-server/8006.pid \
+ -daemonize \
+ -smp '1,sockets=1,cores=1,maxcpus=1' \
+ -nodefaults \
+ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+ -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+ -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \
+ -m 512 \
+ -global 'PIIX4_PM.disable_s3=1' \
+ -global 'PIIX4_PM.disable_s4=1' \
+ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \
+ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \
+ -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \
+ -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \
+ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
+ -chardev 'socket,path=/var/run/qemu-server/8006.qga,server=on,wait=off,id=qga0' \
+ -device 'virtio-serial,id=qga0,bus=pci.0,addr=0x8' \
+ -device 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0' \
+ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
+ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+ -machine 'type=pc+pve0'
diff --git a/src/test/cfg2cmd/qga-fs-freeze.conf b/src/test/cfg2cmd/qga-fs-freeze.conf
new file mode 100644
index 00000000..c32e143e
--- /dev/null
+++ b/src/test/cfg2cmd/qga-fs-freeze.conf
@@ -0,0 +1,2 @@
+# TEST: Ensure agent sub-properties do not affect the QEMU command line.
+agent: 1,guest-fsfreeze=1
diff --git a/src/test/cfg2cmd/qga-fs-freeze.conf.cmd b/src/test/cfg2cmd/qga-fs-freeze.conf.cmd
new file mode 100644
index 00000000..41b185e0
--- /dev/null
+++ b/src/test/cfg2cmd/qga-fs-freeze.conf.cmd
@@ -0,0 +1,29 @@
+/usr/bin/kvm \
+ -id 8006 \
+ -name 'vm8006,debug-threads=on' \
+ -no-shutdown \
+ -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+ -mon 'chardev=qmp,mode=control' \
+ -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \
+ -mon 'chardev=qmp-event,mode=control' \
+ -pidfile /var/run/qemu-server/8006.pid \
+ -daemonize \
+ -smp '1,sockets=1,cores=1,maxcpus=1' \
+ -nodefaults \
+ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+ -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+ -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \
+ -m 512 \
+ -global 'PIIX4_PM.disable_s3=1' \
+ -global 'PIIX4_PM.disable_s4=1' \
+ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \
+ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \
+ -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \
+ -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \
+ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
+ -chardev 'socket,path=/var/run/qemu-server/8006.qga,server=on,wait=off,id=qga0' \
+ -device 'virtio-serial,id=qga0,bus=pci.0,addr=0x8' \
+ -device 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0' \
+ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
+ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+ -machine 'type=pc+pve0'
diff --git a/src/test/cfg2cmd/qga-minimal.conf b/src/test/cfg2cmd/qga-minimal.conf
new file mode 100644
index 00000000..86560065
--- /dev/null
+++ b/src/test/cfg2cmd/qga-minimal.conf
@@ -0,0 +1,2 @@
+# TEST: Ensure agent sub-properties do not affect the QEMU command line.
+agent: 1
diff --git a/src/test/cfg2cmd/qga-minimal.conf.cmd b/src/test/cfg2cmd/qga-minimal.conf.cmd
new file mode 100644
index 00000000..41b185e0
--- /dev/null
+++ b/src/test/cfg2cmd/qga-minimal.conf.cmd
@@ -0,0 +1,29 @@
+/usr/bin/kvm \
+ -id 8006 \
+ -name 'vm8006,debug-threads=on' \
+ -no-shutdown \
+ -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+ -mon 'chardev=qmp,mode=control' \
+ -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \
+ -mon 'chardev=qmp-event,mode=control' \
+ -pidfile /var/run/qemu-server/8006.pid \
+ -daemonize \
+ -smp '1,sockets=1,cores=1,maxcpus=1' \
+ -nodefaults \
+ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+ -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+ -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \
+ -m 512 \
+ -global 'PIIX4_PM.disable_s3=1' \
+ -global 'PIIX4_PM.disable_s4=1' \
+ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \
+ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \
+ -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \
+ -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \
+ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \
+ -chardev 'socket,path=/var/run/qemu-server/8006.qga,server=on,wait=off,id=qga0' \
+ -device 'virtio-serial,id=qga0,bus=pci.0,addr=0x8' \
+ -device 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0' \
+ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \
+ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+ -machine 'type=pc+pve0'
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread