[pve-devel] [PATCH 15/15] qm migrate : add storage migration for local node
Alexandre Derumier
aderumier at odiso.com
Thu Jan 17 18:51:34 CET 2013
currently only for local node, works online or offline
syntax:
qm migrate <vmid> <target> -storage -[virtiox|idex|scsix|satax] storeid:[fmt]
sample:
qm migrate <vmid> <target> -storage -virtio0 local:raw -scsi1 local:qcow2 -sata3 rbdstorage: --ide4 lvmstorage:
fixme: how to handle snapshots ? delete them ? or keep the old drive if snapshot exist ?
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
PVE/API2/Qemu.pm | 40 +++++++++++++++++++++++++++++++++-------
PVE/QemuServer.pm | 17 +++++++++++++++++
2 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 633245c..fa878cb 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -135,7 +135,7 @@ my $create_disks = sub {
};
my $clone_disks = sub {
- my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $settings, $snap, $mode, $clonefrom, $running) = @_;
+ my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $settings, $snap, $mode, $clonefrom, $running, $onlysettings) = @_;
my $vollist = [];
my $voliddst = undef;
@@ -143,6 +143,8 @@ my $clone_disks = sub {
my $res = {};
PVE::QemuServer::foreach_drive($conf, sub {
my ($ds, $disk) = @_;
+
+ return if ($onlysettings && !$settings->{$ds});
my $volid = $disk->{file};
if (PVE::QemuServer::drive_is_cdrom($disk)) {
@@ -1871,7 +1873,7 @@ __PACKAGE__->register_method({
},
parameters => {
additionalProperties => 0,
- properties => {
+ properties => PVE::QemuServer::json_disk_properties({
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
target => get_standard_option('pve-node', { description => "Target node." }),
@@ -1885,7 +1887,12 @@ __PACKAGE__->register_method({
description => "Allow to migrate VMs which use local devices. Only root may use this option.",
optional => 1,
},
- },
+ storage => {
+ type => 'boolean',
+ description => "Migrate storage.",
+ optional => 1,
+ },
+ }),
},
returns => {
type => 'string',
@@ -1900,8 +1907,10 @@ __PACKAGE__->register_method({
my $target = extract_param($param, 'target');
+ my $storage = extract_param($param, 'storage');
+
my $localnode = PVE::INotify::nodename();
- raise_param_exc({ target => "target is local node."}) if $target eq $localnode;
+ raise_param_exc({ target => "target is local node."}) if ($target eq $localnode && !$storage);
PVE::Cluster::check_cfs_quorum();
@@ -1920,8 +1929,8 @@ __PACKAGE__->register_method({
# try to detect errors early
PVE::QemuServer::check_lock($conf);
-
- if (PVE::QemuServer::check_running($vmid)) {
+ my $running = PVE::QemuServer::check_running($vmid);
+ if ($running) {
die "cant migrate running VM without --online\n"
if !$param->{online};
}
@@ -1951,8 +1960,25 @@ __PACKAGE__->register_method({
my $realcmd = sub {
my $upid = shift;
+ if ($target eq $localnode && $storage){
+ die "disk copy feature is not available" if !PVE::QemuServer::has_feature('copy', $conf, $storecfg);
+ my $oldconf = { %$conf };
+ &$clone_disks($rpcenv, $authuser, $conf, $storecfg, $vmid, undef, $param, undef, 'copy', $vmid, $running, 1);
+ PVE::QemuServer::update_config_nolock($vmid, $conf);
+ #delete old disks
+ #fix me : how to handle snapshots removal ?
+ PVE::QemuServer::foreach_drive($oldconf, sub {
+ my ($ds, $disk) = @_;
+ return if !$param->{$ds};
+ my $volid = $disk->{file};
+ print "free $volid\n";
+ eval { PVE::Storage::vdisk_free($storecfg, $volid); };
+ warn $@ if $@;
+ });
- PVE::QemuMigrate->migrate($target, $targetip, $vmid, $param);
+ }else{
+ PVE::QemuMigrate->migrate($target, $targetip, $vmid, $param);
+ }
};
return $rpcenv->fork_worker('qmigrate', $vmid, $authuser, $realcmd);
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 30a890a..f9fbead 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -150,6 +150,8 @@ mkdir $lock_dir;
my $pcisysfs = "/sys/bus/pci";
+my $diskdesc = {};
+
my $confdesc = {
onboot => {
optional => 1,
@@ -603,21 +605,25 @@ for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
$drivename_hash->{"ide$i"} = 1;
$confdesc->{"ide$i"} = $idedesc;
+ $diskdesc->{"ide$i"} = $idedesc;
}
for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
$drivename_hash->{"sata$i"} = 1;
$confdesc->{"sata$i"} = $satadesc;
+ $diskdesc->{"sata$i"} = $satadesc;
}
for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
$drivename_hash->{"scsi$i"} = 1;
$confdesc->{"scsi$i"} = $scsidesc ;
+ $diskdesc->{"scsi$i"} = $scsidesc ;
}
for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
$drivename_hash->{"virtio$i"} = 1;
$confdesc->{"virtio$i"} = $virtiodesc;
+ $diskdesc->{"virtio$i"} = $virtiodesc;
}
for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
@@ -1425,6 +1431,17 @@ sub json_config_properties {
return $prop;
}
+# add JSON properties for create and set function
+sub json_disk_properties {
+ my $prop = shift;
+
+ foreach my $opt (keys %$diskdesc) {
+ $prop->{$opt} = $confdesc->{$opt};
+ }
+
+ return $prop;
+}
+
sub check_type {
my ($key, $value) = @_;
--
1.7.10.4
More information about the pve-devel
mailing list