]> git.proxmox.com Git - pve-storage.git/commitdiff
Fix #2050: only provide 'conv=sparse' for LvmThin
authorStoiko Ivanov <s.ivanov@proxmox.com>
Thu, 17 Jan 2019 15:31:51 +0000 (16:31 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 18 Jan 2019 09:46:33 +0000 (10:46 +0100)
LVMPlugin->volume_import (used by storage_migrate on either offline
migration with local disks, or online migration with storage-only
referenced disks) passed 'conv=sparse' to `dd`. This can lead to
data-corruption, if the target volume is not zero-initialized.

dropping the sparse argument completely would fix the problem, but
breaks keeping data sparse for LvmThinPlugin.

This patch moves the dd out into (LVM*) plugin specific sub so that
each can control the parameters.

Steps for reproducing the issue:
* create a cluster with (at least) 2 nodes A and B, with a free
  disk-device (/dev/sdx)
* write a recognizable pattern to /dev/sdx on B:
  `dd if=/dev/zero bs=10M | tr '\000' '\255' | dd of=/dev/sdb bs=10M`
  (would be grateful for alternatives to the dd| tr| dd)
* on both A and B create a lvm-vg (pvcreate, vgcreate)
* add it as _not_ shared storage, which is available on nodes A and B
* create a small guest on A
* fill a file in the guest with zeros
  `dd if=/dev/zero of=/zerofil bs=10M`
* stop the guest, migrate it to B
* start the guest - check that the file `/zerofil` contains `ad`
  instead of `00`

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
PVE/Storage/LVMPlugin.pm
PVE/Storage/LvmThinPlugin.pm

index 72d74646349a3b1808fd4966e609081fd191bdd8..9ad79795d6cf9d941636cb36656fbe8e8fc4368f 100644 (file)
@@ -620,8 +620,8 @@ sub volume_import {
        }
        my $file = $class->path($scfg, $volname, $storeid)
            or die "internal error: failed to get path to newly allocated volume $volname\n";
-       run_command(['dd', "of=$file", 'conv=sparse', 'bs=64k'],
-                   input => '<&'.fileno($fh));
+
+       $class->volume_import_write($fh, $file);
     };
     if (my $err = $@) {
        eval { $class->free_image($storeid, $scfg, $volname, 0) };
@@ -630,4 +630,10 @@ sub volume_import {
     }
 }
 
+sub volume_import_write {
+    my ($class, $input_fh, $output_file) = @_;
+    run_command(['dd', "of=$output_file", 'bs=64k'],
+       input => '<&'.fileno($input_fh));
+}
+
 1;
index 122fb37f0c9b280cf32c5a610523aa53ea907837..aafc202c043615852e1dbd9b7c2ebd0681914a12 100644 (file)
@@ -374,4 +374,11 @@ sub volume_has_feature {
     return undef;
 }
 
+# used in LVMPlugin->volume_import
+sub volume_import_write {
+    my ($class, $input_fh, $output_file) = @_;
+    run_command(['dd', "of=$output_file", 'conv=sparse', 'bs=64k'],
+       input => '<&'.fileno($input_fh));
+}
+
 1;