]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage.pm
fix error message
[pve-storage.git] / PVE / Storage.pm
index 907e3b39903dd9d9b0c7650fa7cb1eba0c39abdf..4fcda5a6b468eae48e1ae505ab8d059c0c9cb219 100755 (executable)
@@ -12,7 +12,7 @@ use File::Path;
 use Cwd 'abs_path';
 use Socket;
 
-use PVE::Tools qw(run_command file_read_firstline $IPV6RE);
+use PVE::Tools qw(run_command file_read_firstline dir_glob_foreach $IPV6RE);
 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::Exception qw(raise_param_exc);
 use PVE::JSONSchema;
@@ -33,7 +33,10 @@ use PVE::Storage::ZFSPoolPlugin;
 use PVE::Storage::ZFSPlugin;
 use PVE::Storage::DRBDPlugin;
 
-# load and initialize all plugins
+# Storage API version. Icrement it on changes in storage API interface.
+use constant APIVER => 1;
+
+# load standard plugins
 PVE::Storage::DirPlugin->register();
 PVE::Storage::LVMPlugin->register();
 PVE::Storage::LvmThinPlugin->register();
@@ -46,6 +49,34 @@ PVE::Storage::GlusterfsPlugin->register();
 PVE::Storage::ZFSPoolPlugin->register();
 PVE::Storage::ZFSPlugin->register();
 PVE::Storage::DRBDPlugin->register();
+
+# load third-party plugins
+if ( -d '/usr/share/perl5/PVE/Storage/Custom' ) {
+    dir_glob_foreach('/usr/share/perl5/PVE/Storage/Custom', '.*\.pm$', sub {
+       my ($file) = @_;
+       my $modname = 'PVE::Storage::Custom::' . $file;
+       $modname =~ s!\.pm$!!;
+       $file = 'PVE/Storage/Custom/' . $file;
+
+       eval {
+           require $file;
+       };
+       if ($@) {
+           warn $@;
+       # Check storage API version and that file is really storage plugin.
+       } elsif ($modname->isa('PVE::Storage::Plugin') && $modname->can('api') && $modname->api() == APIVER) {
+            eval {
+               import $file;
+               $modname->register();
+            };
+            warn $@ if $@;
+       } else {
+           warn "Error loading storage plugin \"$modname\" because of API version mismatch. Please, update it.\n"
+       }
+    });
+}
+
+# initialize all plugins
 PVE::Storage::Plugin->init();
 
 my $UDEVADM = '/sbin/udevadm';
@@ -75,7 +106,7 @@ sub lock_storage_config {
 sub storage_config {
     my ($cfg, $storeid, $noerr) = @_;
 
-    die "no storage id specified\n" if !$storeid;
+    die "no storage ID specified\n" if !$storeid;
 
     my $scfg = $cfg->{ids}->{$storeid};
 
@@ -515,7 +546,7 @@ sub storage_migrate {
 
        if ($tcfg->{type} eq 'zfspool') {
 
-           die "$errstr - pool on target has not same name as source!"
+           die "$errstr - pool on target does not have the same name as on source!"
                if $tcfg->{pool} ne $scfg->{pool};
 
            my (undef, $volname) = parse_volname($cfg, $volid);
@@ -545,35 +576,34 @@ sub storage_migrate {
 
     } elsif ($scfg->{type} eq 'lvmthin' || $scfg->{type} eq 'lvm') {
 
-       if ($tcfg->{type} eq 'lvmthin' || $tcfg->{type} eq 'lvm') {
-
-           die "$errstr - pool on target has not same name as source!"
-               if $tcfg->{type} ne $scfg->{type};
+       if (($scfg->{type} eq $tcfg->{type}) &&
+           ($tcfg->{type} eq 'lvmthin' || $tcfg->{type} eq 'lvm')) {
 
-           my (undef, $volname) = parse_volname($cfg, $volid);
+           my (undef, $volname, $vmid) = parse_volname($cfg, $volid);
            my $size = volume_size_info($cfg, $volid, 5);
-           my $path = path($cfg, $volid);
-
-           $volname =~ m/^vm-(\d+)-/;
-           my $vmid = $1;
+           my $src = path($cfg, $volid);
+           my $dst = path($cfg, $target_volid);
 
            run_command(['/usr/bin/ssh', "root\@${target_host}",
                         'pvesm', 'alloc', $target_storeid, $vmid,
-                        $volname, $size/1024]);
+                         $target_volname, int($size/1024)]);
 
            eval {
-               run_command([["dd", "if=$path"],
-                            ["/usr/bin/ssh", "root\@${target_host}", "-C",
-                             "dd", 'conv=sparse', "of=$path"]]);
+               if ($tcfg->{type} eq 'lvmthin') {
+                   run_command([["dd", "if=$src"],["/usr/bin/ssh", "root\@${target_host}",
+                             "dd", 'conv=sparse', "of=$dst"]]);
+               } else {
+                   run_command([["dd", "if=$src"],["/usr/bin/ssh", "root\@${target_host}",
+                             "dd", "of=$dst"]]);
+               }
            };
            if (my $err = $@) {
                run_command(['/usr/bin/ssh', "root\@${target_host}",
-                        'pvesm', 'free', $volid]);
-           } else {
-               vdisk_free($cfg, $volid);
+                        'pvesm', 'free', $target_volid]);
+               die $err;
            }
        } else {
-           die "$errstr - target type $tcfg->{type} is not valid\n";
+           die "$errstr - migrate from source type '$scfg->{type}' to '$tcfg->{type}' not implemented\n";
        }
     } else {
        die "$errstr - source type '$scfg->{type}' not implemented\n";
@@ -619,7 +649,7 @@ sub vdisk_create_base {
 sub vdisk_alloc {
     my ($cfg, $storeid, $vmid, $fmt, $name, $size) = @_;
 
-    die "no storage id specified\n" if !$storeid;
+    die "no storage ID specified\n" if !$storeid;
 
     PVE::JSONSchema::parse_storage_id($storeid);
 
@@ -680,7 +710,7 @@ sub vdisk_free {
 
                if ($basename && defined($basevmid) && $basevmid == $vmid && $basename eq $name) {
                    die "base volume '$volname' is still in use " .
-                       "(use by '$tmpvolname')\n";
+                       "(used by '$tmpvolname')\n";
                }
            }
        }
@@ -962,7 +992,7 @@ sub deactivate_volumes {
        }
     }
 
-    die "volume deativation failed: " . join(' ', @errlist)
+    die "volume deactivation failed: " . join(' ', @errlist)
        if scalar(@errlist);
 }