Signed-off-by: Wolfgang Bumiller <w.bumil...@proxmox.com> --- src/PVE/Storage/BTRFSPlugin.pm | 11 +++++- src/PVE/Storage/LVMPlugin.pm | 12 ++++++- src/PVE/Storage/LvmThinPlugin.pm | 62 ++++++++++++++++++++------------ src/PVE/Storage/Plugin.pm | 12 ++++++- src/PVE/Storage/RBDPlugin.pm | 13 +++++-- src/PVE/Storage/ZFSPoolPlugin.pm | 14 ++++++-- 6 files changed, 94 insertions(+), 30 deletions(-)
diff --git a/src/PVE/Storage/BTRFSPlugin.pm b/src/PVE/Storage/BTRFSPlugin.pm index a0145bb..0bd5244 100644 --- a/src/PVE/Storage/BTRFSPlugin.pm +++ b/src/PVE/Storage/BTRFSPlugin.pm @@ -880,6 +880,7 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ) = @_; if ($format ne 'btrfs') { @@ -895,6 +896,14 @@ sub volume_import { die "btrfs-receiving volumes of type $volume_format ('$volname') is not supported\n" if $volume_format ne 'raw' && $volume_format ne 'subvol'; + if ( + defined($import_vtype) + && !PVE::Storage::Common::is_type_change_allowed($import_vtype, $vtype) + ) { + die "refusing import volume with name '$volname':" + . " name implies type '$vtype', import requested type '$import_vtype'\n"; + } + if (defined($base_snapshot)) { my $path = $class->path($scfg, $volname, $storeid, $base_snapshot); $path = raw_file_to_subvol($path) if $volume_format eq 'raw'; @@ -909,7 +918,7 @@ sub volume_import { if (!defined($base_snapshot) && -e $destination) { die "volume $volname already exists\n" if !$allow_rename; - $volname = $class->find_free_diskname($storeid, $scfg, $vmid, $volume_format, 1); + $volname = $class->find_free_diskname($storeid, $scfg, $vmid, $volume_format, 1, $vtype); } my $imagedir = $class->get_subdir($scfg, $vtype); diff --git a/src/PVE/Storage/LVMPlugin.pm b/src/PVE/Storage/LVMPlugin.pm index b578ff4..1811e05 100644 --- a/src/PVE/Storage/LVMPlugin.pm +++ b/src/PVE/Storage/LVMPlugin.pm @@ -1278,6 +1278,7 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ) = @_; die "volume import format $format not available for $class\n" if $format ne 'raw+size'; @@ -1290,6 +1291,14 @@ sub volume_import { die "cannot import format $format into a file of format $file_format\n" if $file_format ne 'raw'; + if ( + defined($import_vtype) + && !PVE::Storage::Common::is_type_change_allowed($import_vtype, $vtype) + ) { + die "refusing import volume with name '$volname':" + . " name implies type '$vtype', import requested type '$import_vtype'\n"; + } + my $vg = $scfg->{vgname}; my $lvs = lvm_list_volumes($vg); if ($lvs->{$vg}->{$volname}) { @@ -1302,7 +1311,8 @@ sub volume_import { $size = PVE::Storage::Common::align_size_up($size, 1024) / 1024; eval { - my $allocname = $class->alloc_image($storeid, $scfg, $vmid, 'raw', $name, $size); + my $allocname = + $class->alloc_image($storeid, $scfg, $vmid, 'raw', $name, $size, $vtype); my $oldname = $volname; $volname = $allocname; if (defined($name) && $allocname ne $oldname) { diff --git a/src/PVE/Storage/LvmThinPlugin.pm b/src/PVE/Storage/LvmThinPlugin.pm index 6462c22..c1ff474 100644 --- a/src/PVE/Storage/LvmThinPlugin.pm +++ b/src/PVE/Storage/LvmThinPlugin.pm @@ -6,6 +6,7 @@ use warnings; use IO::File; use PVE::Tools qw(run_command trim); +use PVE::Storage::Common; use PVE::Storage::Plugin; use PVE::Storage::LVMPlugin; use PVE::JSONSchema qw(get_standard_option); @@ -488,6 +489,7 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ) = @_; my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $file_format) = @@ -504,36 +506,50 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ); + } + + if ( + defined($import_vtype) + && !PVE::Storage::Common::is_type_change_allowed($import_vtype, $vtype) + ) { + die "refusing import volume with name '$volname':" + . " name implies type '$vtype', import requested type '$import_vtype'\n"; + } + + my $tempname; + my $vg = $scfg->{vgname}; + my $lvs = PVE::Storage::LVMPlugin::lvm_list_volumes($vg); + if ($lvs->{$vg}->{$volname}) { + die "volume $vg/$volname already exists\n" if !$allow_rename; + warn "volume $vg/$volname already exists - importing with a different name\n"; + + $tempname = $class->find_free_diskname($storeid, $scfg, $vmid, undef, 0, $vtype); } else { - my $tempname; - my $vg = $scfg->{vgname}; - my $lvs = PVE::Storage::LVMPlugin::lvm_list_volumes($vg); - if ($lvs->{$vg}->{$volname}) { - die "volume $vg/$volname already exists\n" if !$allow_rename; - warn "volume $vg/$volname already exists - importing with a different name\n"; - - $tempname = $class->find_free_diskname($storeid, $scfg, $vmid); + $tempname = $volname; + if ($tempname =~ /^base-vol-/) { + $tempname =~ substr($tempname, 5); } else { - $tempname = $volname; $tempname =~ s/base/vm/; } + } - my $newvolid = $class->SUPER::volume_import( - $scfg, - $storeid, - $fh, - $tempname, - $format, - $snapshot, - $base_snapshot, - $with_snapshots, - $allow_rename, - ); - ($storeid, my $newname) = PVE::Storage::parse_volume_id($newvolid); + my $newvolid = $class->SUPER::volume_import( + $scfg, + $storeid, + $fh, + $tempname, + $format, + $snapshot, + $base_snapshot, + $with_snapshots, + $allow_rename, + $import_vtype, + ); + ($storeid, my $newname) = PVE::Storage::parse_volume_id($newvolid); - $volname = $class->create_base($storeid, $scfg, $newname); - } + $volname = $class->create_base($storeid, $scfg, $newname); return "$storeid:$volname"; } diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index e418042..fc39df7 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -2289,6 +2289,7 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ) = @_; die "volume import format '$format' not available for $class\n" @@ -2303,6 +2304,14 @@ sub volume_import { my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $file_format) = $class->parse_volname($volname); + if ( + defined($import_vtype) + && !PVE::Storage::Common::is_type_change_allowed($import_vtype, $vtype) + ) { + die "refusing import volume with name '$volname':" + . " name implies type '$vtype', import requested type '$import_vtype'\n"; + } + # XXX: Should we bother with conversion routines at this level? This won't # happen without manual CLI usage, so for now we just error out... die "cannot import format $format into a file of format $file_format\n" @@ -2321,7 +2330,8 @@ sub volume_import { $size = PVE::Storage::Common::align_size_up($size, 1024) / 1024; eval { - my $allocname = $class->alloc_image($storeid, $scfg, $vmid, $file_format, $name, $size); + my $allocname = + $class->alloc_image($storeid, $scfg, $vmid, $file_format, $name, $size, $vtype); my $oldname = $volname; $volname = $allocname; if (defined($name) && $allocname ne $oldname) { diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm index 437dd07..7b54f7c 100644 --- a/src/PVE/Storage/RBDPlugin.pm +++ b/src/PVE/Storage/RBDPlugin.pm @@ -1068,20 +1068,29 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ) = @_; die "volume import format $format not available for $class\n" if $format ne 'raw+size'; die "cannot import volumes together with their snapshots in $class\n" if $with_snapshots; die "cannot import an incremental stream in $class\n" if defined($base_snapshot); - my (undef, $name, $vmid, undef, undef, undef, $file_format) = $class->parse_volname($volname); + my ($vtype, $name, $vmid, undef, undef, undef, $file_format) = $class->parse_volname($volname); die "cannot import format $format into a volume of format $file_format\n" if $file_format ne 'raw'; + if ( + defined($import_vtype) + && !PVE::Storage::Common::is_type_change_allowed($import_vtype, $vtype) + ) { + die "refusing import volume with name '$volname':" + . " name implies type '$vtype', import requested type '$import_vtype'\n"; + } + if (rbd_volume_exists($scfg, $storeid, $name)) { die "volume $name already exists\n" if !$allow_rename; warn "volume $name already exists - importing with a different name\n"; - $volname = $class->find_free_diskname($storeid, $scfg, $vmid, $file_format); + $volname = $class->find_free_diskname($storeid, $scfg, $vmid, $file_format, 0, $vtype); } my ($size) = PVE::Storage::Plugin::read_common_header($fh); diff --git a/src/PVE/Storage/ZFSPoolPlugin.pm b/src/PVE/Storage/ZFSPoolPlugin.pm index 34768d2..2cae090 100644 --- a/src/PVE/Storage/ZFSPoolPlugin.pm +++ b/src/PVE/Storage/ZFSPoolPlugin.pm @@ -9,6 +9,7 @@ use POSIX; use PVE::ProcFSTools; use PVE::RPCEnvironment; +use PVE::Storage::Common; use PVE::Storage::Plugin; use PVE::Tools qw(run_command); @@ -890,6 +891,7 @@ sub volume_import { $base_snapshot, $with_snapshots, $allow_rename, + $import_vtype, ) = @_; die "unsupported import stream format for $class: $format\n" @@ -899,9 +901,17 @@ sub volume_import { die "internal error: invalid file handle for volume_import\n" if !defined($fd); - my (undef, $dataset, $vmid, undef, undef, undef, $volume_format) = + my ($vtype, $dataset, $vmid, undef, undef, undef, $volume_format) = $class->parse_volname($volname); + if ( + defined($import_vtype) + && !PVE::Storage::Common::is_type_change_allowed($import_vtype, $vtype) + ) { + die "refusing import volume with name '$volname':" + . " name implies type '$vtype', import requested type '$import_vtype'\n"; + } + my $zfspath = "$scfg->{pool}/$dataset"; my $suffix = defined($base_snapshot) ? "\@$base_snapshot" : ''; my $exists = 0 == run_command( @@ -914,7 +924,7 @@ sub volume_import { } elsif ($exists) { die "volume '$zfspath' already exists\n" if !$allow_rename; warn "volume '$zfspath' already exists - importing with a different name\n"; - $dataset = $class->find_free_diskname($storeid, $scfg, $vmid, $volume_format); + $dataset = $class->find_free_diskname($storeid, $scfg, $vmid, $volume_format, 0, $vtype); $zfspath = "$scfg->{pool}/$dataset"; } -- 2.47.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel