[pve-devel] [PATCH 1/2] Add the functionality of full clone

Wolfgang Link w.link at proxmox.com
Thu Apr 14 17:38:59 CEST 2016


---
 src/PVE/API2/LXC.pm | 21 ++++++++++-----------
 src/PVE/LXC.pm      | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 90cdba6..e64ee17 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -1073,6 +1073,7 @@ __PACKAGE__->register_method({
 
 	my $storage = extract_param($param, 'storage');
 
+	die "Full clone require a storage.\n"if $param->{full} && !$storage;
         my $localnode = PVE::INotify::nodename();
 
 	my $storecfg = PVE::Storage::config();
@@ -1126,10 +1127,6 @@ __PACKAGE__->register_method({
 		    if ($mp->{type} eq 'volume') {
 			my $volid = $mp->{volume};
 			if ($param->{full}) {
-			    die "fixme: full clone not implemented";
-
-			    die "Full clone feature for '$volid' is not available\n"
-				if !PVE::Storage::volume_has_feature($storecfg, 'copy', $volid, $snapname, $running);
 			    $fullclone->{$opt} = 1;
 			} else {
 			    # not full means clone instead of copy
@@ -1176,18 +1173,20 @@ __PACKAGE__->register_method({
 		    foreach my $opt (keys %$mountpoints) {
 			my $mp = $mountpoints->{$opt};
 			my $volid = $mp->{volume};
+			my $newvolid;
 
 			if ($fullclone->{$opt}) {
-			    die "fixme: full clone not implemented\n";
+			    print "create full clone of mountpoint $opt ($volid)\n";
+			    $newvolid = PVE::LXC::clone_volume($mp, $vmid, $newid, $storage, $storecfg, $conf);
 			} else {
 			    print "create linked clone of mountpoint $opt ($volid)\n";
-			    my $newvolid = PVE::Storage::vdisk_clone($storecfg, $volid, $newid, $snapname);
-			    push @$newvollist, $newvolid;
-			    $mp->{volume} = $newvolid;
-
-			    $newconf->{$opt} = PVE::LXC::Config->print_ct_mountpoint($mp, $opt eq 'rootfs');
-			    PVE::LXC::Config->write_config($newid, $newconf);
+			    $newvolid = PVE::Storage::vdisk_clone($storecfg, $volid, $newid, $snapname);
 			}
+			push @$newvollist, $newvolid;
+			$mp->{volume} = $newvolid;
+
+			$newconf->{$opt} = PVE::LXC::Config->print_ct_mountpoint($mp, $opt eq 'rootfs');
+			PVE::LXC::Config->write_config($newid, $newconf);
 		    }
 
 		    delete $newconf->{lock};
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index fe97d31..b51f5a0 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -1348,5 +1348,54 @@ sub userns_command {
     return [];
 }
 
+sub clone_volume {
+    my ($mp, $vmid, $newid, $storage, $storage_cfg, $conf, $sanpshot) = @_;
+    my $dir = "/tmp/$vmid";
+    my $dest = "$dir\/dest";
+    my $src =  "$dir\/src";
+
+    my $new_format = $storage_cfg->{ids}->{$storage}->{type} eq "zfspool" ? 'subvol' : 'raw';
+
+    my $new_volid = PVE::Storage::vdisk_alloc($storage_cfg, $storage, $newid, $new_format, undef, $mp->{size}/1024);
+
+    $mp->{mp} =~ s!.*$/!!;
+    my $new_mp = PVE::LXC::Config->parse_ct_rootfs($new_volid);
+    my (undef, $rootuid, $rootgid) = parse_id_maps($conf);
+
+    my $path = PVE::Storage::path($storage_cfg, $new_volid, undef);
+
+    eval {
+	mkfs($path, $rootuid, $rootgid) if $new_format ne "subvol";
+
+	mkdir $dir;
+	mkdir $dest;
+	mkdir $src;
+
+	mountpoint_mount($mp, $src, $storage_cfg);
+	mountpoint_mount($new_mp, $dest, $storage_cfg);
+
+	PVE::Tools::run_command(['/usr/bin/rsync', '--stats', '-X', '-A', '--numeric-ids',
+				 '--whole-file', '--inplace', '--one-file-system', '-aH',
+				 "$src$mp->{mp}\/.", $dest.$new_mp->{mp}]);
+
+    };
+    my $err = $@;
+    eval { PVE::Tools::run_command(['/bin/umount', '-f', $src.$mp->{mp}], errfunc => sub{})};
+    warn "Can't umount $src.$mp->{mp}\n" if $@;
+    eval { PVE::Tools::run_command(['/bin/umount', '-f', $dest.$new_mp->{mp}], errfunc => sub{})};
+    warn "Can't umount $src.$new_mp->{mp}\n" if $@;
+
+    rmdir $src.$mp->{mp};
+    rmdir $dest.$new_mp->{mp};
+    rmdir $dest;
+    rmdir $src;
+    rmdir $dir;
+
+    if ($err) {
+	PVE::Storage::vdisk_free($storage_cfg, $new_volid);
+	die $err;
+    }
+    return $new_volid;
+}
 
 1;
-- 
2.1.4




More information about the pve-devel mailing list