]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage.pm
sheepdog : has_feature : clone base
[pve-storage.git] / PVE / Storage.pm
index 78a14f90b98f8f5bebf4428f3e48dd26dafb8825..36d4cb3ef0636debea3fa5c402e32cbe094d0f7e 100755 (executable)
@@ -257,15 +257,31 @@ sub parse_vmid {
     return int($vmid);
 }
 
-PVE::JSONSchema::register_format('pve-volume-id', \&parse_volume_id);
 sub parse_volume_id {
     my ($volid, $noerr) = @_;
 
-    if ($volid =~ m/^([a-z][a-z0-9\-\_\.]*[a-z0-9]):(.+)$/i) {
-       return wantarray ? ($1, $2) : $1;
+    return PVE::Storage::Plugin::parse_volume_id($volid, $noerr);
+}
+
+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 undef if $noerr;
-    die "unable to parse volume ID '$volid'\n";
+
+    return 0;
 }
 
 # try to map a filesystem path to a volume identifier
@@ -277,7 +293,7 @@ sub path_to_volume_id {
     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);
@@ -504,7 +520,28 @@ sub vdisk_free {
 
     # lock shared storage
     $plugin->cluster_lock_storage($storeid, $scfg->{shared}, undef, sub {
-       my $cleanup_worker = $plugin->free_image($storeid, $scfg, $volname);
+
+       my ($vtype, $name, $vmid, undef, undef, $isBase) = 
+           $plugin->parse_volname($volname);
+       if ($isBase) {
+           my $vollist = $plugin->list_images($storeid, $scfg);
+           foreach my $info (@$vollist) {
+               my (undef, $tmpvolname) = parse_volume_id($info->{volid});
+               my $basename = undef;
+               my $basevmid = undef;
+
+               eval{
+                   (undef, undef, undef, $basename, $basevmid) = 
+                       $plugin->parse_volname($tmpvolname);
+               };
+
+               if ($basename && defined($basevmid) && $basevmid == $vmid && $basename eq $name) {
+                   die "base volume '$volname' is still in use " .
+                       "(use by '$tmpvolname')\n";
+               }
+           }
+       }
+       my $cleanup_worker = $plugin->free_image($storeid, $scfg, $volname, $isBase);
     });
 
     return if !$cleanup_worker;