[pve-devel] [PATCH pve-container 9/9] implement move disk

Wolfgang Link w.link at proxmox.com
Wed Nov 18 09:30:06 CET 2015


---
 src/PVE/API2/LXC.pm | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 87 insertions(+), 3 deletions(-)

diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index dbf4057..c742058 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -1168,12 +1168,96 @@ __PACKAGE__->register_method({
 
 	my $storecfg = PVE::Storage::config();
 
-	die "Storage do not support container\n" if !$storeid; 
-	
+	die "Storage do not support container\n" if !$storeid;
+
 	my $updatefn =  sub {
 
-	    print "Not implemented now!!";
+	    my $conf = PVE::LXC::load_config($vmid);
+
+	    die "checksum missmatch (file change by other user?)\n"
+		if $digest && $digest ne $conf->{digest};
+
+	    die "Disk: '$disk' does not exist\n" if !$conf->{$disk};
+
+	    my $mp = PVE::LXC::parse_ct_mountpoint($conf->{$disk});
+	    my $old_volid = $mp->{volume};
+
+	    my $oldfmt = (PVE::Storage::parse_volname($storecfg, $old_volid))[6];
+
+	    my $drive = {};
+	    $drive->{file} = $old_volid;
+	    $drive->{size} = (PVE::Storage::volume_size_info($storecfg, $old_volid));
+
+	    my ($oldstoreid, $oldvolname) = PVE::Storage::parse_volume_id($old_volid);
+
+	    die "Storage: $storeid don't exists!\n" if !$storecfg->{ids}->{$storeid};
+	    die "Container images are not allowed on $storeid!\n" if !$storecfg->{ids}->{$storeid}->{content}->{rootdir};
+
+	    my $newfmt = 'raw';
+	    $newfmt = 'subvol' if  $storecfg->{ids}->{$storeid}->{type} eq 'zfspool';
+
+	    $newfmt = $format if $format;
+
+	    die "you can't move on the same storage with same format\n"
+		if $oldstoreid eq $storeid && $oldfmt eq $newfmt;
+
+	    PVE::Cluster::log_msg('info', $authuser, "move disk VM $vmid:".
+				  " move --disk $disk --storage $storeid");
+
+	    my $run = PVE::LXC::check_running($vmid);
+
+	    die "Can't move CT: $vmid if it's running!\n" if $run;
+
+	    PVE::Storage::activate_volumes($storecfg, [ $drive->{file} ]);
+
+	    my $realcmd = sub {
+
+		my $dst_volid;
+
+		eval {
+		    local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} =
+			$SIG{HUP} = sub { die "interrupted by signal\n"; };
+
+		    $dst_volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $newfmt, undef, $drive->{size}/1024);
+		    if ('raw' eq (PVE::Storage::parse_volname($storecfg, $dst_volid))[6]) {
+
+			PVE::Storage::activate_volumes($storecfg, [$dst_volid]);
+
+			my ($id_map, $rootuid, $rootgid) = PVE::LXC::parse_id_maps($conf);
+			my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
+			PVE::LXC::mkfs($dst_path, $rootuid, $rootgid);
+			
+			PVE::Storage::deactivate_volumes($storecfg, [$dst_volid]);
+		    }
+
+		    PVE::LXC::copy_lxc_disk($drive->{file}, $dst_volid, $storecfg);
+
+		    $mp->{volume} = $dst_volid;
+		    $mp->{size} = $drive->{size};
+		    $conf->{$disk} = PVE::LXC::print_ct_mountpoint($mp, $disk eq 'rootfs');
+
+
+		    PVE::LXC::write_config($vmid, $conf);
+
+		    eval {
+			# try to deactivate volumes - avoid lvm LVs to be active on several nodes
+			PVE::Storage::deactivate_volumes($storecfg, [ $dst_volid ])
+			    if !$run;
+		    };
+		    warn $@ if $@;
+		};
+		if (my $err = $@) {
+		    PVE::Storage::vdisk_free($storecfg, $dst_volid) if $dst_volid;
+		    die "storage migration failed: $err\n";
+		}
+
+		if ($param->{delete}) {
+		    eval { PVE::Storage::vdisk_free($storecfg, $old_volid); };
+		    warn $@ if $@;
+		}
+	    };
 
+	return $rpcenv->fork_worker('lxcmove_disk', $vmid, $authuser, $realcmd);
 	};
 
 	return PVE::LXC::lock_container($vmid, undef, $updatefn);
-- 
2.1.4




More information about the pve-devel mailing list