optional => 1,
});
-
-sub map_storage {
- my ($map, $source) = @_;
-
- return $source if !defined($map);
-
- return $map->{entries}->{$source}
- if $map->{entries} && defined($map->{entries}->{$source});
-
- return $map->{default} if $map->{default};
-
- # identity (fallback)
- return $source;
-}
-
PVE::JSONSchema::register_standard_option('pve-targetstorage', {
description => "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.",
type => 'string',
default_key => 1,
},
(map { $_ => { keyAlias => 'model', alias => 'macaddr' }} @$nic_model_list),
- bridge => {
- type => 'string',
+ bridge => get_standard_option('pve-bridge-id', {
description => $net_fmt_bridge_descr,
- format_description => 'bridge',
- pattern => '[-_.\w\d]+',
optional => 1,
- },
+ }),
queues => {
type => 'integer',
minimum => 0, maximum => 16,
}
sub parse_vm_config {
- my ($filename, $raw) = @_;
+ my ($filename, $raw, $strict) = @_;
return if !defined($raw);
pending => {},
};
+ my $handle_error = sub {
+ my ($msg) = @_;
+
+ if ($strict) {
+ die $msg;
+ } else {
+ warn $msg;
+ }
+ };
+
$filename =~ m|/qemu-server/(\d+)\.conf$|
|| die "got strange filename '$filename'";
if ($section eq 'pending') {
$conf->{delete} = $value; # we parse this later
} else {
- warn "vm $vmid - propertry 'delete' is only allowed in [PENDING]\n";
+ $handle_error->("vm $vmid - property 'delete' is only allowed in [PENDING]\n");
}
} elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(.+?)\s*$/) {
my $key = $1;
my $value = $2;
eval { $value = check_type($key, $value); };
if ($@) {
- warn "vm $vmid - unable to parse value of '$key' - $@";
+ $handle_error->("vm $vmid - unable to parse value of '$key' - $@");
} else {
$key = 'ide2' if $key eq 'cdrom';
my $fmt = $confdesc->{$key}->{format};
$v->{file} = $volid;
$value = print_drive($v);
} else {
- warn "vm $vmid - unable to parse value of '$key'\n";
+ $handle_error->("vm $vmid - unable to parse value of '$key'\n");
next;
}
}
$conf->{$key} = $value;
}
} else {
- warn "vm $vmid - unable to parse config: $line\n";
+ $handle_error->("vm $vmid - unable to parse config: $line\n");
}
}
sub vmconfig_apply_pending {
my ($vmid, $conf, $storecfg, $errors) = @_;
+ return if !scalar(keys %{$conf->{pending}});
+
my $add_apply_error = sub {
my ($opt, $msg) = @_;
my $err_msg = "unable to apply pending change $opt : $msg";
my ($ds, $drive) = @_;
return if drive_is_cdrom($drive);
+ return if $ds eq 'tpmstate0';
my $volid = $drive->{file};
# volume is not available there, fall back to the default format.
# Otherwise use the same format as the original.
if (!$storagemap->{identity}) {
- $storeid = map_storage($storagemap, $storeid);
+ $storeid = PVE::JSONSchema::map_id($storagemap, $storeid);
my ($defFormat, $validFormats) = PVE::Storage::storage_default_format($storecfg, $storeid);
my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
my $fileFormat = qemu_img_format($scfg, $volname);
# network => CIDR of migration network
# type => secure/insecure - tunnel over encrypted connection or plain-text
# nbd_proto_version => int, 0 for TCP, 1 for UNIX
-# replicated_volumes = which volids should be re-used with bitmaps for nbd migration
+# replicated_volumes => which volids should be re-used with bitmaps for nbd migration
+# tpmstate_vol => new volid of tpmstate0, not yet contained in config
sub vm_start_nolock {
my ($storecfg, $vmid, $conf, $params, $migrate_opts) = @_;
# this way we can reuse the old ISO with the correct config
PVE::QemuServer::Cloudinit::generate_cloudinitconfig($conf, $vmid) if !$migratedfrom;
+ # override TPM state vol if migrated, conf is out of date still
+ if (my $tpmvol = $migrate_opts->{tpmstate_vol}) {
+ my $parsed = parse_drive("tpmstate0", $conf->{tpmstate0});
+ $parsed->{file} = $tpmvol;
+ $conf->{tpmstate0} = print_drive($parsed);
+ }
+
my $defaults = load_defaults();
# set environment variable useful inside network script
if ($agent_running) {
print "freeze filesystem\n";
eval { mon_cmd($vmid, "guest-fsfreeze-freeze"); };
+ warn $@ if $@;
} else {
print "suspend vm\n";
eval { PVE::QemuServer::vm_suspend($vmid, 1); };
+ warn $@ if $@;
}
# if we clone a disk for a new target vm, we don't switch the disk
if ($agent_running) {
print "unfreeze filesystem\n";
eval { mon_cmd($vmid, "guest-fsfreeze-thaw"); };
+ warn $@ if $@;
} else {
print "resume vm\n";
- eval { PVE::QemuServer::vm_resume($vmid, 1, 1); };
+ eval { PVE::QemuServer::vm_resume($vmid, 1, 1); };
+ warn $@ if $@;
}
last;
no_data_clone:
my ($size) = eval { PVE::Storage::volume_size_info($storecfg, $newvolid, 10) };
- my $disk = $drive;
- $disk->{format} = undef;
+ my $disk = dclone($drive);
+ delete $disk->{format};
$disk->{file} = $newvolid;
$disk->{size} = $size if defined($size);