}
}
+sub volume_snapshot_rollback {
+ my ($cfg, $volid, $snap) = @_;
+
+ my ($storeid, $volname) = parse_volume_id($volid, 1);
+ if ($storeid) {
+ my $scfg = storage_config($cfg, $storeid);
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+ return $plugin->volume_snapshot_rollback($scfg, $storeid, $volname, $snap);
+ } elsif ($volid =~ m|^(/.+)$| && -e $volid) {
+ die "snapshot rollback device is not possible";
+ } else {
+ die "can't snapshot";
+ }
+}
+
+sub volume_snapshot_delete {
+ my ($cfg, $volid, $snap, $running) = @_;
+
+ my ($storeid, $volname) = parse_volume_id($volid, 1);
+ if ($storeid) {
+ my $scfg = storage_config($cfg, $storeid);
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+ return $plugin->volume_snapshot_delete($scfg, $storeid, $volname, $snap, $running);
+ } elsif ($volid =~ m|^(/.+)$| && -e $volid) {
+ die "snapshot delete device is not possible";
+ } else {
+ die "can't delete snapshot";
+ }
+}
+
+sub volume_has_feature {
+ my ($cfg, $feature, $volid, $snap, $running) = @_;
+
+ my ($storeid, $volname) = parse_volume_id($volid, 1);
+ if ($storeid) {
+ my $scfg = storage_config($cfg, $storeid);
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+ return $plugin->volume_has_feature($scfg, $feature, $storeid, $volname, $snap, $running);
+ } elsif ($volid =~ m|^(/.+)$| && -e $volid) {
+ return undef;
+ } else {
+ return undef;
+ }
+}
+
sub get_image_dir {
my ($cfg, $storeid, $vmid) = @_;
die "unable to parse volume ID '$volid'\n";
}
+sub volume_is_base {
+ my ($cfg, $volid) = @_;
+
+ my ($sid, $volname) = parse_volume_id($volid, 1);
+ return 0 if !$sid;
+
+ if (my $scfg = $cfg->{ids}->{$sid}) {
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+ my ($vtype, $name, $vmid, $basename, $basevmid, $isBase) =
+ $plugin->parse_volname($volname);
+ return $isBase ? 1 : 0;
+ } else {
+ # stale volid with undefined storage - so we can just guess
+ if ($volid =~ m/base-/) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
# try to map a filesystem path to a volume identifier
sub path_to_volume_id {
my ($cfg, $path) = @_;
my ($sid, $volname) = parse_volume_id($path, 1);
if ($sid) {
if (my $scfg = $ids->{$sid}) {
- if (my $path = $scfg->{path}) {
+ if ($scfg->{path}) {
my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
my ($vtype, $name, $vmid) = $plugin->parse_volname($volname);
return ($vtype, $path);
if ($path =~ m!^$imagedir/(\d+)/([^/\s]+)$!) {
my $vmid = $1;
my $name = $2;
- return ('images', "$sid:$vmid/$name");
+
+ my $vollist = $plugin->list_images($sid, $scfg, $vmid);
+ foreach my $info (@$vollist) {
+ my ($storeid, $volname) = parse_volume_id($info->{volid});
+ my $volpath = $plugin->path($scfg, $volname, $storeid);
+ if ($volpath eq $path) {
+ return ('images', $info->{volid});
+ }
+ }
} elsif ($path =~ m!^$isodir/([^/]+\.[Ii][Ss][Oo])$!) {
my $name = $1;
return ('iso', "$sid:iso/$name");
} elsif ($path =~ m!^$privatedir/(\d+)$!) {
my $vmid = $1;
return ('rootdir', "$sid:rootdir/$vmid");
- } elsif ($path =~ m!^$backupdir/([^/]+\.(tar|tar\.gz|tar\.lzo|tgz))$!) {
+ } elsif ($path =~ m!^$backupdir/([^/]+\.(tar|tar\.gz|tar\.lzo|tgz|vma|vma\.gz|vma\.lzo))$!) {
my $name = $1;
return ('iso', "$sid:backup/$name");
}
my $errstr = "unable to migrate '$volid' to '${target_volid}' on host '$target_host'";
- # blowfish is a fast block cipher, much faster then 3des
- my $sshoptions = "-c blowfish -o 'BatchMode=yes'";
+ my $sshoptions = "-o 'BatchMode=yes'";
my $ssh = "/usr/bin/ssh $sshoptions";
local $ENV{RSYNC_RSH} = $ssh;
}
}
+sub vdisk_clone {
+ my ($cfg, $volid, $vmid) = @_;
+
+ my ($storeid, $volname) = parse_volume_id($volid);
+
+ my $scfg = storage_config($cfg, $storeid);
+
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+
+ activate_storage($cfg, $storeid);
+
+ # lock shared storage
+ return $plugin->cluster_lock_storage($storeid, $scfg->{shared}, undef, sub {
+ my $volname = $plugin->clone_image($scfg, $storeid, $volname, $vmid);
+ return "$storeid:$volname";
+ });
+}
+
+sub vdisk_create_base {
+ my ($cfg, $volid) = @_;
+
+ my ($storeid, $volname) = parse_volume_id($volid);
+
+ my $scfg = storage_config($cfg, $storeid);
+
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+
+ activate_storage($cfg, $storeid);
+
+ # lock shared storage
+ return $plugin->cluster_lock_storage($storeid, $scfg->{shared}, undef, sub {
+ my $volname = $plugin->create_base($storeid, $scfg, $volname);
+ return "$storeid:$volname";
+ });
+}
+
sub vdisk_alloc {
my ($cfg, $storeid, $vmid, $fmt, $name, $size) = @_;
$info = { volid => "$sid:vztmpl/$1", format => 'tgz' };
} elsif ($tt eq 'backup') {
- next if $fn !~ m!/([^/]+\.(tar|tar\.gz|tar\.lzo|tgz))$!;
+ next if $fn !~ m!/([^/]+\.(tar|tar\.gz|tar\.lzo|tgz|vma|vma\.gz|vma\.lzo))$!;
$info = { volid => "$sid:backup/$1", format => $2 };
}