[pve-devel] [PATCH v2 3/12] fix #4225: qemuserver: add function to eject isofiles
Daniel Herzig
d.herzig at proxmox.com
Mon Jan 13 09:55:59 CET 2025
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 d07c170e..f72878d3 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -4041,6 +4041,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};
@@ -8999,6 +9001,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