From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id A67E21FF138 for ; Wed, 22 Jul 2026 11:53:55 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 44F9F214E6; Wed, 22 Jul 2026 11:53:48 +0200 (CEST) From: Thomas Ellmenreich To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server v2 1/2] refactor checks for absolute path as drive Date: Wed, 22 Jul 2026 11:52:50 +0200 Message-ID: <20260722095251.89606-2-t.ellmenreich@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260722095251.89606-1-t.ellmenreich@proxmox.com> References: <20260722095251.89606-1-t.ellmenreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1784713966098 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.139 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 4N3XHIAKIZCOFJVEDZXVOQFSCPALP2ZV X-Message-ID-Hash: 4N3XHIAKIZCOFJVEDZXVOQFSCPALP2ZV X-MailFrom: t.ellmenreich@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Thomas Ellmenreich X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Previously there were a bunch of separate checks for whether a drive was an absolute path. These have been refactored to use two checks in QemuServer::Drive and QemuServer::Helpers. Signed-off-by: Thomas Ellmenreich --- src/PVE/QemuConfig.pm | 2 +- src/PVE/QemuMigrate.pm | 2 +- src/PVE/QemuServer.pm | 20 ++++++++------------ src/PVE/QemuServer/Blockdev.pm | 4 ++-- src/PVE/QemuServer/Drive.pm | 8 +++++++- src/PVE/QemuServer/Helpers.pm | 5 +++++ 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/PVE/QemuConfig.pm b/src/PVE/QemuConfig.pm index 26f0fda2..d8733d9d 100644 --- a/src/PVE/QemuConfig.pm +++ b/src/PVE/QemuConfig.pm @@ -145,7 +145,7 @@ sub get_replicatable_volumes { return if !$cleanup && !$attr->{replicate}; - if ($volid =~ m|^/|) { + if (PVE::QemuServer::Helpers::is_absolute_path($volid)) { return if !$attr->{replicate}; return if $cleanup || $noerr; die "unable to replicate local file/device '$volid'\n"; diff --git a/src/PVE/QemuMigrate.pm b/src/PVE/QemuMigrate.pm index 8da6f15d..dcf911a5 100644 --- a/src/PVE/QemuMigrate.pm +++ b/src/PVE/QemuMigrate.pm @@ -405,7 +405,7 @@ sub scan_local_volumes { my $test_volid = sub { my ($volid, $attr) = @_; - if ($volid =~ m|^/|) { + if (PVE::QemuServer::Helpers::is_absolute_path($volid)) { return if $attr->{shared}; $local_volumes->{$volid}->{ref} = 'config'; die "local file/device\n"; diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index 191ae549..ce832c8e 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -75,6 +75,7 @@ use PVE::QemuServer::Drive qw( checked_volume_format drive_is_cloudinit drive_is_cdrom + drive_is_absolute_path parse_drive print_drive storage_allows_io_uring_default @@ -913,7 +914,7 @@ PVE::JSONSchema::register_format( sub verify_volume_id_or_absolute_path { my ($volid, $noerr) = @_; - return $volid if $volid =~ m|^/|; + return $volid if PVE::QemuServer::Helpers::is_absolute_path($volid); $volid = eval { PVE::JSONSchema::check_format('pve-volume-id', $volid, '') }; if ($@) { @@ -1555,7 +1556,7 @@ sub print_vga_device { sub vm_is_volid_owner { my ($storecfg, $vmid, $volid) = @_; - if ($volid !~ m|^/|) { + if (!PVE::QemuServer::Helpers::is_absolute_path($volid)) { my ($path, $owner); eval { ($path, $owner) = PVE::Storage::path($storecfg, $volid); }; log_warn("ownership of volume '$volid' could not be determined: $@") if $@; @@ -1841,11 +1842,9 @@ sub destroy_vm { { include_unused => 1 }, sub { my ($ds, $drive) = @_; - return if drive_is_cdrom($drive); + return if drive_is_cdrom($drive) || drive_is_absolute_path($drive); my $volid = $drive->{file}; - return if !$volid || $volid =~ m|^/|; - my $result = eval { PVE::Storage::volume_is_base_and_used($storecfg, $volid) }; # early check, removal of volume will fail later anyway, so warning here is fine log_warn("failed to check if volume '$volid' is used by linked clones: $@") @@ -1859,10 +1858,9 @@ sub destroy_vm { my $volids = {}; my $remove_owned_drive = sub { my ($ds, $drive) = @_; - return if drive_is_cdrom($drive, 1); + return if drive_is_cdrom($drive, 1) || drive_is_absolute_path($drive); my $volid = $drive->{file}; - return if !$volid || $volid =~ m|^/|; return if $volids->{$volid}; my ($path, $owner) = eval { PVE::Storage::path($storecfg, $volid) }; @@ -6085,7 +6083,7 @@ sub get_vm_volumes { sub { my ($volid, $attr) = @_; - return if $volid =~ m|^/|; + return if PVE::QemuServer::Helpers::is_absolute_path($volid); my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1); return if !$sid; @@ -6485,7 +6483,7 @@ sub tar_restore_cleanup { if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) { my $volid = $2; eval { - if ($volid =~ m|^/|) { + if (PVE::QemuServer::Helpers::is_absolute_path($volid)) { unlink $volid || die 'unlink failed\n'; } else { PVE::Storage::vdisk_free($storecfg, $volid); @@ -6530,11 +6528,9 @@ my $restore_cleanup_oldconf = sub { sub { my ($ds, $drive) = @_; - return if drive_is_cdrom($drive, 1); + return if drive_is_cdrom($drive, 1) || drive_is_absolute_path($drive); my $volid = $drive->{file}; - return if !$volid || $volid =~ m|^/|; - my ($path, $owner) = PVE::Storage::path($storecfg, $volid); return if !$path || !$owner || ($owner != $vmid); diff --git a/src/PVE/QemuServer/Blockdev.pm b/src/PVE/QemuServer/Blockdev.pm index 101c747c..78a53ff5 100644 --- a/src/PVE/QemuServer/Blockdev.pm +++ b/src/PVE/QemuServer/Blockdev.pm @@ -11,7 +11,7 @@ use JSON; use PVE::JSONSchema qw(json_bool); use PVE::Storage; -use PVE::QemuServer::Drive qw(drive_is_cdrom); +use PVE::QemuServer::Drive qw(drive_is_cdrom drive_is_absolute_path); use PVE::QemuServer::Helpers; use PVE::QemuServer::Machine; use PVE::QemuServer::Monitor qw(mon_cmd qmp_cmd qsd_qmp_peer vm_qmp_peer); @@ -299,7 +299,7 @@ sub generate_file_blockdev { } elsif ($drive->{file} eq 'cdrom') { my $path = PVE::QemuServer::Drive::get_iso_path($storecfg, $drive->{file}); $blockdev = { driver => 'host_cdrom', filename => "$path" }; - } elsif ($drive->{file} =~ m|^/|) { + } elsif (drive_is_absolute_path($drive)) { my $path = $drive->{file}; # The 'file' driver only works for regular files. The check below is taken from # block/file-posix.c:hdev_probe_device() in QEMU. To detect CD-ROM host devices, QEMU issues diff --git a/src/PVE/QemuServer/Drive.pm b/src/PVE/QemuServer/Drive.pm index b80b7dbb..35256acf 100644 --- a/src/PVE/QemuServer/Drive.pm +++ b/src/PVE/QemuServer/Drive.pm @@ -23,6 +23,7 @@ our @EXPORT_OK = qw( checked_volume_format drive_is_cloudinit drive_is_cdrom + drive_is_absolute_path parse_drive print_drive storage_allows_io_uring_default @@ -766,6 +767,11 @@ sub drive_is_cdrom { return $drive && $drive->{media} && ($drive->{media} eq 'cdrom'); } +sub drive_is_absolute_path { + my ($drive) = @_; + return PVE::QemuServer::Helpers::is_absolute_path($drive->{file}); +} + sub parse_drive_interface { my ($key) = @_; @@ -1061,7 +1067,7 @@ sub get_scsi_device_type { if (drive_is_cdrom($drive) || drive_is_cloudinit($drive)) { $devicetype = 'cd'; } else { - if ($drive->{file} =~ m|^/|) { + if (drive_is_absolute_path($drive)) { $path = $drive->{file}; if (my $info = path_is_scsi($path)) { if ($info->{type} == 0 && $drive->{scsiblock}) { diff --git a/src/PVE/QemuServer/Helpers.pm b/src/PVE/QemuServer/Helpers.pm index dd17eef5..5cc3e8b5 100644 --- a/src/PVE/QemuServer/Helpers.pm +++ b/src/PVE/QemuServer/Helpers.pm @@ -389,4 +389,9 @@ sub get_host_phys_address_bits { return; # undef, cannot really do anything.. } +sub is_absolute_path { + my ($volid) = @_; + return $volid =~ m|^/|; +} + 1; -- 2.47.3