[pve-devel] [PATCH v2 qemu-server] refuse to add non-replicatable disks to replicating VMs

Wolfgang Bumiller w.bumiller at proxmox.com
Tue Jun 27 09:42:55 CEST 2017


Unless replication is explicitly disabled for them.
---
Changes to v1:
  * Use new PVE::Storage::storage_can_replicate()
  * Do the check early (in $update_vm_api() instead of $create_disks())
  Note that this means it will not be done in the create_vm api call,
  which is fine since no replication job should exist at that point.

 PVE/API2/Qemu.pm | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 6b502df..da5f5b1 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -115,6 +115,7 @@ my $check_storage_access_clone = sub {
 
 # Note: $pool is only needed when creating a VM, because pool permissions
 # are automatically inherited if VM already exists inside a pool.
+my $NEW_DISK_RE = qr!^(([^/:\s]+):)?(\d+(\.\d+)?)$!;
 my $create_disks = sub {
     my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $settings, $default_storage) = @_;
 
@@ -130,7 +131,7 @@ my $create_disks = sub {
 	if (!$volid || $volid eq 'none' || $volid eq 'cdrom') {
 	    delete $disk->{size};
 	    $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
-	} elsif ($volid =~ m!^(([^/:\s]+):)?(\d+(\.\d+)?)$!) {
+	} elsif ($volid =~ $NEW_DISK_RE) {
 	    my ($storeid, $size) = ($2 || $default_storage, $3);
 	    die "no storage ID specified (and no default storage)\n" if !$storeid;
 	    my $defformat = PVE::Storage::storage_default_format($storecfg, $storeid);
@@ -954,12 +955,33 @@ my $update_vm_api  = sub {
 	push @delete, $opt;
     }
 
+    my $repl_conf = PVE::ReplicationConfig->new();
+    my $is_replicated = $repl_conf->check_for_existing_jobs($vmid, 1);
+    my $check_replication = sub {
+	my ($drive) = @_;
+	return if !$is_replicated;
+	my $volid = $drive->{file};
+	return if !$volid || !($drive->{replicate}//1);
+	return if PVE::QemuServer::drive_is_cdrom($drive);
+	my ($storeid, $format);
+	if ($volid =~ $NEW_DISK_RE) {
+	    $storeid = $2;
+	    $format = $drive->{format} || PVE::Storage::storage_default_format($storecfg, $storeid);
+	} else {
+	    ($storeid, undef) = PVE::Storage::parse_volume_id($volid, 1);
+	    $format = (PVE::Storage::parse_volname($storecfg, $volid))[6];
+	}
+	return if PVE::Storage::storage_can_replicate($storecfg, $storeid, $format);
+	die "cannot add non-replicatable volume to a replicated VM\n";
+    };
+
     foreach my $opt (keys %$param) {
 	if (PVE::QemuServer::is_valid_drivename($opt)) {
 	    # cleanup drive path
 	    my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
 	    raise_param_exc({ $opt => "unable to parse drive options" }) if !$drive;
 	    PVE::QemuServer::cleanup_drive_path($opt, $storecfg, $drive);
+	    $check_replication->($drive);
 	    $param->{$opt} = PVE::QemuServer::print_drive($vmid, $drive);
 	} elsif ($opt =~ m/^net(\d+)$/) {
 	    # add macaddr
-- 
2.11.0





More information about the pve-devel mailing list