[pve-devel] [PATCH storage 2/5] move check for existing clones into own method

Fabian Grünbichler f.gruenbichler at proxmox.com
Wed Sep 14 16:08:49 CEST 2016


---
we need this in other parts as well, at least in qemu-server
and later pve-container to fix #1094

 PVE/Storage.pm | 54 +++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 19 deletions(-)

diff --git a/PVE/Storage.pm b/PVE/Storage.pm
index 273d17d..c1de558 100755
--- a/PVE/Storage.pm
+++ b/PVE/Storage.pm
@@ -341,6 +341,36 @@ sub parse_volume_id {
     return PVE::Storage::Plugin::parse_volume_id($volid, $noerr);
 }
 
+sub volume_is_referenced_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});
+
+    my ($vtype, $name, $vmid, undef, undef, $isBase, undef) =
+	$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) {
+		return $tmpvolname;
+	    }
+	}
+    }
+    return undef;
+}
+
 # try to map a filesystem path to a volume identifier
 sub path_to_volume_id {
     my ($cfg, $path) = @_;
@@ -673,26 +703,12 @@ sub vdisk_free {
     # lock shared storage
     $plugin->cluster_lock_storage($storeid, $scfg->{shared}, undef, sub {
 
-	my ($vtype, $name, $vmid, undef, undef, $isBase, $format) =
+	my $clonevolname = volume_is_referenced_base($cfg, $volid);
+	die "base volume '$volname' is still in use (by '$clonevolname')\n"
+	    if $clonevolname;
+
+	my (undef, undef, undef, undef, undef, $isBase, $format) =
 	    $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 " .
-			"(used by '$tmpvolname')\n";
-		}
-	    }
-	}
 	$cleanup_worker = $plugin->free_image($storeid, $scfg, $volname, $isBase, $format);
     });
 
-- 
2.1.4





More information about the pve-devel mailing list