test snapshot capability, fix unused drive handling

This commit is contained in:
Dietmar Maurer 2012-09-10 11:49:32 +02:00
parent b7ba6b7933
commit ee2f90b14e

View File

@ -1649,27 +1649,36 @@ sub write_vm_config {
delete $conf->{smp}; delete $conf->{smp};
} }
# fixme: unused drives and snapshots??!! my $used_volids = {};
my $new_volids = {}; my $cleanup_config = sub {
foreach my $key (keys %$conf) { my ($cref) = @_;
next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
my $value = $conf->{$key}; foreach my $key (keys %$cref) {
next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
$key eq 'snapstate';
my $value = $cref->{$key};
eval { $value = check_type($key, $value); }; eval { $value = check_type($key, $value); };
die "unable to parse value of '$key' - $@" if $@; die "unable to parse value of '$key' - $@" if $@;
$conf->{$key} = $value; $cref->{$key} = $value;
if (valid_drivename($key)) { if (valid_drivename($key)) {
my $drive = PVE::QemuServer::parse_drive($key, $value); my $drive = PVE::QemuServer::parse_drive($key, $value);
$new_volids->{$drive->{file}} = 1 if $drive && $drive->{file}; $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
} }
} }
};
&$cleanup_config($conf);
foreach my $snapname (keys %{$conf->{snapshots}}) {
&$cleanup_config($conf->{snapshots}->{$snapname});
}
# remove 'unusedX' settings if we re-add a volume # remove 'unusedX' settings if we re-add a volume
foreach my $key (keys %$conf) { foreach my $key (keys %$conf) {
my $value = $conf->{$key}; my $value = $conf->{$key};
if ($key =~ m/^unused/ && $new_volids->{$value}) { if ($key =~ m/^unused/ && $used_volids->{$value}) {
delete $conf->{$key}; delete $conf->{$key};
} }
} }
@ -3608,8 +3617,27 @@ my $snapshot_prepare = sub {
die "snapshot name '$snapname' already used\n" die "snapshot name '$snapname' already used\n"
if defined($conf->{snapshots}->{$snapname}); if defined($conf->{snapshots}->{$snapname});
# fixme: need to implement a check to see if all storages my $storecfg = PVE::Storage::config();
# support snapshots
PVE::QemuServer::foreach_drive($conf, sub {
my ($ds, $drive) = @_;
return if drive_is_cdrom($drive);
my $volid = $drive->{file};
my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
if ($storeid) {
my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
die "can't snapshot volume '$volid'\n"
if !(($scfg->{path} && $volname =~ m/\.qcow2$/) ||
($scfg->{type} eq 'rbd') ||
($scfg->{type} eq 'sheepdog'));
} elsif ($volid =~ m|^(/.+)$| && -e $volid) {
die "snapshot device '$volid' is not possible\n";
} else {
die "can't snapshot volume '$volid'\n";
}
});
$snap = $conf->{snapshots}->{$snapname} = { $snap = $conf->{snapshots}->{$snapname} = {
snapstate => "prepare", snapstate => "prepare",
@ -3643,6 +3671,7 @@ my $snapshot_commit = sub {
if !($snap->{snapstate} && $snap->{snapstate} eq "prepare"); if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
delete $snap->{snapstate}; delete $snap->{snapstate};
delete $conf->{lock};
my $newconf = &$snapshot_apply_config($conf, $snap); my $newconf = &$snapshot_apply_config($conf, $snap);
@ -3745,7 +3774,7 @@ sub snapshot_create {
if ($err) { if ($err) {
warn "snapshot create failed: starting cleanup\n"; warn "snapshot create failed: starting cleanup\n";
eval { snapshot_delete($vmid, $snapname); }; eval { snapshot_delete($vmid, $snapname, 1); };
warn $@ if $@; warn $@ if $@;
die $err; die $err;
} }
@ -3759,6 +3788,7 @@ sub snapshot_delete {
my $prepare = 1; my $prepare = 1;
my $snap; my $snap;
my $unused = [];
my $updatefn = sub { my $updatefn = sub {
@ -3786,7 +3816,11 @@ sub snapshot_delete {
if ($prepare) { if ($prepare) {
$snap->{snapstate} = 'delete'; $snap->{snapstate} = 'delete';
} else { } else {
delete $conf->{parent} if $conf->{parent} && $conf->{parent} eq $snapname;
delete $conf->{snapshots}->{$snapname}; delete $conf->{snapshots}->{$snapname};
foreach my $volid (@$unused) {
add_unused_volume($conf, $volid);
}
} }
update_config_nolock($vmid, $conf, 1); update_config_nolock($vmid, $conf, 1);
@ -3806,6 +3840,7 @@ sub snapshot_delete {
my $device = "drive-$ds"; my $device = "drive-$ds";
qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname); qemu_volume_snapshot_delete($vmid, $device, $storecfg, $volid, $snapname);
push @$unused, $volid;
}); });
# now cleanup config # now cleanup config