my $check_storage_access = sub {
my ($rpcenv, $authuser, $storecfg, $vmid, $settings, $default_storage) = @_;
- PVE::QemuServer::foreach_drive($settings, sub {
+ PVE::QemuConfig->foreach_volume($settings, sub {
my ($ds, $drive) = @_;
my $isCDROM = PVE::QemuServer::drive_is_cdrom($drive);
my $sharedvm = 1;
- PVE::QemuServer::foreach_drive($conf, sub {
+ PVE::QemuConfig->foreach_volume($conf, sub {
my ($ds, $drive) = @_;
my $isCDROM = PVE::QemuServer::drive_is_cdrom($drive);
}
};
- eval { PVE::QemuServer::foreach_drive($settings, $code); };
+ eval { PVE::QemuConfig->foreach_volume($settings, $code); };
# free allocated images on error
if (my $err = $@) {
push @delete, 'lock'; # this is the real deal to write it out
}
push @delete, 'runningmachine' if $conf->{runningmachine};
+ push @delete, 'runningcpu' if $conf->{runningcpu};
}
PVE::QemuConfig->check_lock($conf) if !$skiplock;
raise_param_exc({ skiplock => "Only root may use this option." })
if $skiplock && $authuser ne 'root@pam';
- # test if VM exists
- my $conf = PVE::QemuConfig->load_config($vmid);
- my $storecfg = PVE::Storage::config();
- PVE::QemuConfig->check_protection($conf, "can't remove VM $vmid");
+ my $early_checks = sub {
+ # test if VM exists
+ my $conf = PVE::QemuConfig->load_config($vmid);
+ PVE::QemuConfig->check_protection($conf, "can't remove VM $vmid");
- my $ha_managed = PVE::HA::Config::service_is_configured("vm:$vmid");
+ my $ha_managed = PVE::HA::Config::service_is_configured("vm:$vmid");
- if (!$param->{purge}) {
- die "unable to remove VM $vmid - used in HA resources and purge parameter not set.\n"
- if $ha_managed;
- # don't allow destroy if with replication jobs but no purge param
- my $repl_conf = PVE::ReplicationConfig->new();
- $repl_conf->check_for_existing_jobs($vmid);
- }
+ if (!$param->{purge}) {
+ die "unable to remove VM $vmid - used in HA resources and purge parameter not set.\n"
+ if $ha_managed;
+ # don't allow destroy if with replication jobs but no purge param
+ my $repl_conf = PVE::ReplicationConfig->new();
+ $repl_conf->check_for_existing_jobs($vmid);
+ }
- # early tests (repeat after locking)
- die "VM $vmid is running - destroy failed\n"
- if PVE::QemuServer::check_running($vmid);
+ die "VM $vmid is running - destroy failed\n"
+ if PVE::QemuServer::check_running($vmid);
+
+ return $ha_managed;
+ };
+
+ $early_checks->();
my $realcmd = sub {
my $upid = shift;
+ my $storecfg = PVE::Storage::config();
+
syslog('info', "destroy VM $vmid: $upid\n");
PVE::QemuConfig->lock_config($vmid, sub {
- die "VM $vmid is running - destroy failed\n"
- if (PVE::QemuServer::check_running($vmid));
+ # repeat, config might have changed
+ my $ha_managed = $early_checks->();
PVE::QemuServer::destroy_vm($storecfg, $vmid, $skiplock, { lock => 'destroyed' });
optional => 1,
},
machine => get_standard_option('pve-qemu-machine'),
+ 'force-cpu' => {
+ description => "Override QEMU's -cpu argument with the given string.",
+ type => 'string',
+ optional => 1,
+ },
targetstorage => get_standard_option('pve-targetstorage'),
timeout => {
description => "Wait maximal timeout seconds.",
my $timeout = extract_param($param, 'timeout');
my $machine = extract_param($param, 'machine');
+ my $force_cpu = extract_param($param, 'force-cpu');
my $get_root_param = sub {
my $value = extract_param($param, $_[0]);
raise_param_exc({ targetstorage => "targetstorage can only by used with migratedfrom." })
if !$migratedfrom;
$storagemap = eval { PVE::JSONSchema::parse_idmap($targetstorage, 'pve-storage-id') };
- raise_param_exc({ targetstorage => "failed to parse targetstorage map: $@" })
+ raise_param_exc({ targetstorage => "failed to parse storage map: $@" })
if $@;
}
skiplock => $skiplock,
forcemachine => $machine,
timeout => $timeout,
+ forcecpu => $force_cpu,
};
PVE::QemuServer::vm_start($storecfg, $vmid, $params, $migrate_opts);
if $skiplock && $authuser ne 'root@pam';
my $nocheck = extract_param($param, 'nocheck');
+ raise_param_exc({ nocheck => "Only root may use this option." })
+ if $nocheck && $authuser ne 'root@pam';
my $to_disk_suspended;
eval {
my $running = PVE::QemuServer::check_running($vmid) || 0;
- # exclusive lock if VM is running - else shared lock is enough;
- my $shared_lock = $running ? 0 : 1;
-
my $clonefn = sub {
# do all tests after lock but before forking worker - if possible
return $rpcenv->fork_worker('qmclone', $vmid, $authuser, $realcmd);
};
- return PVE::QemuConfig->lock_config_mode($vmid, 1, $shared_lock, sub {
- # Aquire exclusive lock lock for $newid
+ # Aquire exclusive lock lock for $newid
+ my $lock_target_vm = sub {
return PVE::QemuConfig->lock_config_full($newid, 1, $clonefn);
- });
+ };
+ # exclusive lock if VM is running - else shared lock is enough;
+ if ($running) {
+ return PVE::QemuConfig->lock_config_full($vmid, 1, $lock_target_vm);
+ } else {
+ return PVE::QemuConfig->lock_config_shared($vmid, 1, $lock_target_vm);
+ }
}});
__PACKAGE__->register_method({
$param->{online} = 0;
}
- raise_param_exc({ targetstorage => "Live storage migration can only be done online." })
- if !$param->{online} && $param->{targetstorage};
-
my $storecfg = PVE::Storage::config();
if (my $targetstorage = $param->{targetstorage}) {
};
my $storagemap = eval { PVE::JSONSchema::parse_idmap($targetstorage, 'pve-storage-id') };
- raise_param_exc({ targetstorage => "failed to parse targetstorage map: $@" })
+ raise_param_exc({ targetstorage => "failed to parse storage map: $@" })
if $@;
$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk'])
PVE::QemuServer::qemu_block_resize($vmid, "drive-$disk", $storecfg, $volid, $newsize);
- my $effective_size = eval { PVE::Storage::volume_size_info($storecfg, $volid, 3); };
- $drive->{size} = $effective_size // $newsize;
+ $drive->{size} = $newsize;
$conf->{$disk} = PVE::QemuServer::print_drive($drive);
PVE::QemuConfig->write_config($vmid, $conf);