[pve-devel] [PATCH v4 storage 2/6] api: content: implement moving a volume between storages
Fiona Ebner
f.ebner at proxmox.com
Mon Oct 21 13:53:14 CEST 2024
Am 18.09.24 um 16:49 schrieb Filip Schauer:
> +sub volume_move {
> + my ($cfg, $source_volid, $target_storeid, $delete) = @_;
> +
> + my ($source_storeid, $source_volname) = PVE::Storage::parse_volume_id($source_volid, 0);
> +
> + die "source and target storage cannot be the same\n" if $source_storeid eq $target_storeid;
> +
> + my $source_scfg = PVE::Storage::storage_config($cfg, $source_storeid);
> + my $source_plugin = PVE::Storage::Plugin->lookup($source_scfg->{type});
> + my ($vtype) = $source_plugin->parse_volname($source_volname);
> +
> + die "source storage '$source_storeid' does not support volumes of type '$vtype'\n"
> + if !$source_scfg->{content}->{$vtype};
> +
> + my $target_scfg = PVE::Storage::storage_config($cfg, $target_storeid);
> + die "target storage '$target_storeid' does not support volumes of type '$vtype'\n"
> + if !$target_scfg->{content}->{$vtype};
> +
> + die "use pct move-volume or qm disk move\n" if $vtype eq 'images' || $vtype eq 'rootdir';
> + die "moving volume of type '$vtype' not implemented\n"
> + if ($vtype ne 'iso' && $vtype ne 'vztmpl' && $vtype ne 'snippets');
> +
> + PVE::Storage::activate_storage($cfg, $source_storeid);
> +
> + die "expected storage '$source_storeid' to be path based\n" if !$source_scfg->{path};
> + my $source_path = $source_plugin->path($source_scfg, $source_volname, $source_storeid);
> + die "$source_path does not exist" if (!-e $source_path);
> + my $source_dirname = dirname($source_path);
> +
> + die "expected storage '$target_storeid' to be path based\n" if !$target_scfg->{path};
> + my $target_plugin = PVE::Storage::Plugin->lookup($target_scfg->{type});
> + my $target_path = $target_plugin->path($target_scfg, $source_volname, $target_storeid);
> +
> + PVE::Storage::activate_storage($cfg, $target_storeid);
> + die "$target_path already exists" if (-e $target_path);
> +
What if a volume with the same name is created after this check, but
before the move/copy? I guess you'll need to lock the storage (see e.g.
vdisk_alloc() in Storage.pm for comparison).
> + my @created_files = ();
> +
> + eval {
> + if ($delete) {
> + move($source_path, $target_path) or die "failed to move $vtype: $!";
> + } else {
> + copy($source_path, $target_path) or die "failed to copy $vtype: $!";
> + }
> + };
> + if (my $err = $@) {
> + for my $created_file (@created_files) {
> + unlink $created_file or $!{ENOENT} or warn $!;
> + }
> + die $err;
> + }
> +
> + PVE::Storage::archive_remove($source_path) if $delete;
> +
> + return;
More information about the pve-devel
mailing list