[pve-devel] [PATCH qemu-server 3/12] fix #4225: qemuserver: add function to eject isofiles

Daniel Herzig d.herzig at proxmox.com
Fri Oct 25 17:02:34 CEST 2024


Current behaviour prevents a VM from starting, if an ISO file defined
in the configuration becomes unavailable.

The function eject_nonrequired_isos checks on whether a cdrom drive is
marked as 'required' or not. If the parameter 'required' is not
defined, it will assume 'required' to be true and keep the current
behaviour.

If 'required' is set to 0, the function 'ejects' the ISO file by
setting the drive's file value to 'none', if the underlying storage is
unavailable or if the defined file is unavailable for another reason.

The function is called while config_to_command iterates over all
volumes to allow for early storage activation and early exit in the
case of missing required files.

Signed-off-by: Daniel Herzig <d.herzig at proxmox.com>
---
 PVE/QemuServer.pm | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index a45bdab9..8fddff92 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -3994,6 +3994,8 @@ sub config_to_command {
     PVE::QemuConfig->foreach_volume($conf, sub {
 	my ($ds, $drive) = @_;
 
+	eject_nonrequired_isos($ds, $drive, $vmid, $storecfg, $conf);
+
 	if (PVE::Storage::parse_volume_id($drive->{file}, 1)) {
 	    check_volume_storage_type($storecfg, $drive->{file});
 	    push @$vollist, $drive->{file};
@@ -8942,6 +8944,43 @@ sub delete_ifaces_ipams_ips {
     }
 }
 
+sub eject_nonrequired_isos {
+    my ($ds, $drive, $vmid, $storecfg, $conf) = @_;
+    # set 1 to exclude cloudinit. cloudinit isos are always required.
+    if (drive_is_cdrom($drive, 1)
+	&& $drive->{file} ne 'none'
+	&& $drive->{file} ne 'cdrom') {
+	$drive->{required} = 1 if !defined($drive->{required});
+	my $iso_volid = $drive->{file};
+	my $iso_path = get_iso_path($storecfg, $vmid, $drive->{file});
+	my $store_err;
+	if ($iso_volid !~ m|^/|) {
+	    my $iso_storage  = PVE::Storage::parse_volume_id($iso_volid, 1);
+	    eval { PVE::Storage::activate_storage($storecfg, $iso_storage); };
+	    $store_err = $@;
+	}
+	if ($store_err) {
+	    if ($drive->{required}) {
+		die "cannot access required file: '${ds}: ${iso_volid}': ${store_err}\n";
+	    } else {
+		log_warn("eject '${ds}: ${iso_volid}': ${store_err}");
+		$drive->{file} = 'none';
+		$conf->{$ds} = print_drive($drive);
+	    }
+	} else {
+	    if (!file_exists($iso_path)) {
+		if ($drive->{required}) {
+		    die "required file does not exist: '${ds}: ${iso_volid}'\n";
+		} else {
+		    log_warn("eject '${ds}: ${iso_volid}': file does not exist");
+		    $drive->{file} = 'none';
+		    $conf->{$ds} = print_drive($drive);
+		}
+	    }
+	}
+    }
+}
+
 sub file_exists {
     my $file_path = shift;
     return -e $file_path
-- 
2.39.5





More information about the pve-devel mailing list