]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage/LvmThinPlugin.pm
bump version to 5.0-24
[pve-storage.git] / PVE / Storage / LvmThinPlugin.pm
index 5e404df55e1117f70ef21f2e44bd61187e75926a..cb2c1a270562012feba463ebcf09ab037bb24fa2 100644 (file)
@@ -15,6 +15,12 @@ use PVE::JSONSchema qw(get_standard_option);
 # lvcreate -n pvepool -L 20G pve
 # lvconvert --type thin-pool pve/pvepool
 
+# NOTE: volumes which were created as linked clones of another base volume
+# are currently not tracking this relationship in their volume IDs. this is
+# generally not a problem, as LVM thin allows deletion of such base volumes
+# without affecting the linked clones. this leads to increased disk usage
+# when migrating LVM-thin volumes, which is normally prevented for linked clones.
+
 use base qw(PVE::Storage::LVMPlugin);
 
 sub type {
@@ -43,9 +49,13 @@ sub options {
         nodes => { optional => 1 },
        disable => { optional => 1 },
        content => { optional => 1 },
+       bwlimit => { optional => 1 },
     };
 }
 
+# NOTE: the fourth and fifth element of the returned array are always
+# undef, even if the volume is a linked clone of another volume. see note
+# at beginning of file.
 sub parse_volname {
     my ($class, $volname) = @_;
 
@@ -163,6 +173,20 @@ sub list_images {
     return $res;
 }
 
+sub list_thinpools {
+    my ($vg) = @_;
+
+    my $lvs = PVE::Storage::LVMPlugin::lvm_list_volumes($vg);
+    my $thinpools = [];
+
+    foreach my $lvname (keys %{$lvs->{$vg}}) {
+       next if $lvs->{$vg}->{$lvname}->{lv_type} ne 't';
+       push @$thinpools, { lv => $lvname };
+    }
+
+    return $thinpools;
+}
+
 sub status {
     my ($class, $storeid, $scfg, $cache) = @_;
 
@@ -195,6 +219,9 @@ sub activate_volume {
        my $snapvol = "snap_${volname}_$snapname";
        my $cmd = ['/sbin/lvchange', '-ay', '-K', "$vg/$snapvol"];
        run_command($cmd, errmsg => "activate_volume '$vg/$snapvol' error");
+    } elsif ($volname =~ /^base-/) {
+       my $cmd = ['/sbin/lvchange', '-ay', '-K', "$vg/$volname"];
+       run_command($cmd, errmsg => "activate_volume '$vg/$volname' error");
     } else {
        # other volumes are active by default
     }
@@ -210,6 +237,9 @@ sub deactivate_volume {
        my $snapvol = "snap_${volname}_$snapname";
        my $cmd = ['/sbin/lvchange', '-an', "$vg/$snapvol"];
        run_command($cmd, errmsg => "deactivate_volume '$vg/$snapvol' error");
+    } elsif ($volname =~ /^base-/) {
+       my $cmd = ['/sbin/lvchange', '-an', "$vg/$volname"];
+       run_command($cmd, errmsg => "deactivate_volume '$vg/$volname' error");
     } else {
        # other volumes are kept active
     }
@@ -218,20 +248,27 @@ sub deactivate_volume {
 sub clone_image {
     my ($class, $scfg, $storeid, $volname, $vmid, $snap) = @_;
 
-    die "clone_image from snapshots not implemented" if $snap;
+    my $vg = $scfg->{vgname};
 
-    my ($vtype, undef, undef, undef, undef, $isBase, $format) =
-        $class->parse_volname($volname);
+    my $lv;
 
-    die "clone_image only works on base images\n" if !$isBase;
+    if ($snap) {
+       $lv = "$vg/snap_${volname}_$snap";
+    } else {
+       my ($vtype, undef, undef, undef, undef, $isBase, $format) =
+           $class->parse_volname($volname);
+
+       die "clone_image only works on base images\n" if !$isBase;
+
+       $lv = "$vg/$volname";
+    }
 
-    my $vg = $scfg->{vgname};
     my $lvs = PVE::Storage::LVMPlugin::lvm_list_volumes($vg);
 
     my $name =  PVE::Storage::LVMPlugin::lvm_find_free_diskname($lvs, $vg, $storeid, $vmid);
 
-    my $cmd = ['/sbin/lvcreate', '-n', $name, '-prw', '-kn', '-s', "$vg/$volname"];
-    run_command($cmd, errmsg => "clone image '$vg/$volname' error");
+    my $cmd = ['/sbin/lvcreate', '-n', $name, '-prw', '-kn', '-s', $lv];
+    run_command($cmd, errmsg => "clone image '$lv' error");
 
     return $name;
 }
@@ -312,9 +349,10 @@ sub volume_has_feature {
 
     my $features = {
        snapshot => { current => 1 },
-       clone => { base => 1},
+       clone => { base => 1, snap => 1},
        template => { current => 1},
        copy => { base => 1, current => 1, snap => 1},
+       sparseinit => { base => 1, current => 1},
     };
 
     my ($vtype, $name, $vmid, $basename, $basevmid, $isBase) =