* [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/.. @ 2025-04-23 13:59 Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 1/3] rbd: extend get_rbd_(dev_)path helpers with $snap parameter Fabian Grünbichler ` (3 more replies) 0 siblings, 4 replies; 9+ messages in thread From: Fabian Grünbichler @ 2025-04-23 13:59 UTC (permalink / raw) To: pve-devel the 'rbd' CLI tool has two ways of specifying which images/snapshots to operate on: - the deprecated --(dest-)pool, --namespace, --image and --snap parameters - the new style 'spec'-based variant, passing [pool/[namespace/]]image[@snapshot] we are currently using a mix of both (passing pool, namespace and snap as needed via parameters, and the image-name as argument). this patch series switches everything to use image or snap specs, except for `ls`, which can't be switched over, because it doesn't operate on images at all. `unmap` doesn't support `--namespace` (but doesn't need it, since it takes the kernel dev as argument). `import` doesn't either, but does require it when a namespace is used as import target (this bug prompted the whole excursion resulting in this patch series). I smoke-tested the changes, but it's possible I missed some operation or corner case when converting, so additional testing is highly appreciated. Fabian Grünbichler (3): rbd: extend get_rbd_(dev_)path helpers with $snap parameter fix #6338: rbd: use image-/snap-spec consistently rbd: add protect/unprotect helpers src/PVE/Storage/RBDPlugin.pm | 167 ++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 81 deletions(-) -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* [pve-devel] [PATCH storage 1/3] rbd: extend get_rbd_(dev_)path helpers with $snap parameter 2025-04-23 13:59 [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Fabian Grünbichler @ 2025-04-23 13:59 ` Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 2/3] fix #6338: rbd: use image-/snap-spec consistently Fabian Grünbichler ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Fabian Grünbichler @ 2025-04-23 13:59 UTC (permalink / raw) To: pve-devel this helper effectively converts a storage config entry and a volume/image name into an RBD image-spec as specified in rbd(8): image-spec is [pool-name/[namespace-name/]]image-name by extending it with an optional $snap parameter it can also convert to a snap-spec: snap-spec is [pool-name/[namespace-name/]]image-name@snap-name this is a needed preparatory step for dropping the (mostly) deprecated `--pool ..`, `--namespace ..` and `--snap ..` parameters when invoking the `rbd` CLI tool. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> --- src/PVE/Storage/RBDPlugin.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm index 73bc97e..8c67a37 100644 --- a/src/PVE/Storage/RBDPlugin.pm +++ b/src/PVE/Storage/RBDPlugin.pm @@ -42,15 +42,16 @@ my $librados_connect = sub { }; my sub get_rbd_path { - my ($scfg, $volume) = @_; + my ($scfg, $volume, $snap) = @_; my $path = $scfg->{pool} ? $scfg->{pool} : 'rbd'; $path .= "/$scfg->{namespace}" if defined($scfg->{namespace}); $path .= "/$volume" if defined($volume); + $path .= "\@$snap" if defined($snap); return $path; }; my sub get_rbd_dev_path { - my ($scfg, $storeid, $volume) = @_; + my ($scfg, $storeid, $volume, $snap) = @_; my $cluster_id = ''; if ($scfg->{fsid}) { @@ -70,7 +71,7 @@ my sub get_rbd_dev_path { die "cluster fsid has invalid format\n"; } - my $rbd_path = get_rbd_path($scfg, $volume); + my $rbd_path = get_rbd_path($scfg, $volume, $snap); my $pve_path = "/dev/rbd-pve/${cluster_id}/${rbd_path}"; my $path = "/dev/rbd/${rbd_path}"; -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* [pve-devel] [PATCH storage 2/3] fix #6338: rbd: use image-/snap-spec consistently 2025-04-23 13:59 [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 1/3] rbd: extend get_rbd_(dev_)path helpers with $snap parameter Fabian Grünbichler @ 2025-04-23 13:59 ` Fabian Grünbichler 2025-05-05 14:24 ` Fiona Ebner 2025-04-23 13:59 ` [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers Fabian Grünbichler 2025-04-30 15:51 ` [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Aaron Lauterer 3 siblings, 1 reply; 9+ messages in thread From: Fabian Grünbichler @ 2025-04-23 13:59 UTC (permalink / raw) To: pve-devel this is the recommended way upstream to pass this information, and all commands (other than those not operating on images/snapshots) consume them (rbd(8)): > image-spec is [pool-name/[namespace-name/]]image-name > snap-spec is [pool-name/[namespace-name/]]image-name@snap-name > [..] > You may specify each name individually, using --pool, --namespace, --image, > and --snap options, but this is discouraged in favor of the above spec > syntax. We already had a few places calling `get_rbd_path` previously (which meant passing the pool and namespace information twice to Ceph). It also allows us to replace the custom import and unmap handling with just custom `ls` handling, reducing the workarounds in rbd_cmd. Fixes: #6338 , because `rbd import` doesn't handle a separate `--namespace ..` at all.. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> --- we could probably switch some more only-technically-public subs over to take a spec instead of image name or image + snapshot name, if desired.. alternatively, we could also just special case the import call, and/or convince upstream to implement --namespace handling there as well or send a patch doing that their way.. src/PVE/Storage/RBDPlugin.pm | 133 ++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm index 8c67a37..3bb5807 100644 --- a/src/PVE/Storage/RBDPlugin.pm +++ b/src/PVE/Storage/RBDPlugin.pm @@ -89,22 +89,17 @@ my $rbd_cmd = sub { my ($scfg, $storeid, $op, @options) = @_; my $cmd_option = PVE::CephConfig::ceph_connect_option($scfg, $storeid); - my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; my $cmd = ['/usr/bin/rbd']; - if ($op eq 'import') { - push $cmd->@*, '--dest-pool', $pool; - } else { + # `ls` doesn't take an image-spec, otherwise pool and namespace should be specified there + if ($op eq 'ls') { + my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; push $cmd->@*, '-p', $pool; + if (defined($scfg->{namespace})) { + push @$cmd, '--namespace', $cfg->{namespace}; + } } - if (defined(my $namespace = $scfg->{namespace})) { - # some subcommands will fail if the --namespace parameter is present - my $no_namespace_parameter = { - unmap => 1, - }; - push @$cmd, '--namespace', "$namespace" if !$no_namespace_parameter->{$op}; - } push @$cmd, '-c', $cmd_option->{ceph_conf} if ($cmd_option->{ceph_conf}); push @$cmd, '-m', $cmd_option->{mon_host} if ($cmd_option->{mon_host}); push @$cmd, '--auth_supported', $cmd_option->{auth_supported} if ($cmd_option->{auth_supported}); @@ -144,9 +139,11 @@ my $krbd_feature_update = sub { my $to_disable = join(',', grep { $active_features->{$_} } @disable); my $to_enable = join(',', grep { !$active_features->{$_} } @enable ); + my $image_spec = get_rbd_path($scfg, $name); + if ($to_disable) { print "disable RBD image features this kernel RBD drivers is not compatible with: $to_disable\n"; - my $cmd = $rbd_cmd->($scfg, $storeid, 'feature', 'disable', $name, $to_disable); + my $cmd = $rbd_cmd->($scfg, $storeid, 'feature', 'disable', $image_spec, $to_disable); run_rbd_command( $cmd, errmsg => "could not disable krbd-incompatible image features '$to_disable' for rbd image: $name", @@ -155,7 +152,7 @@ my $krbd_feature_update = sub { if ($to_enable) { print "enable RBD image features this kernel RBD drivers supports: $to_enable\n"; eval { - my $cmd = $rbd_cmd->($scfg, $storeid, 'feature', 'enable', $name, $to_enable); + my $cmd = $rbd_cmd->($scfg, $storeid, 'feature', 'enable', $image_spec, $to_enable); run_rbd_command( $cmd, errmsg => "could not enable krbd-compatible image features '$to_enable' for rbd image: $name", @@ -234,9 +231,9 @@ sub rbd_ls { } sub rbd_ls_snap { - my ($scfg, $storeid, $name) = @_; + my ($scfg, $storeid, $image_spec) = @_; - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'ls', $name, '--format', 'json'); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'ls', $image_spec, '--format', 'json'); my $raw = ''; run_rbd_command($cmd, errmsg => "rbd error", errfunc => sub {}, outfunc => sub { $raw .= shift; }); @@ -244,9 +241,9 @@ sub rbd_ls_snap { my $list; if ($raw =~ m/^(\[.*\])$/s) { # untaint $list = eval { JSON::decode_json($1) }; - die "invalid JSON output from 'rbd snap ls $name': $@\n" if $@; + die "invalid JSON output from 'rbd snap ls $image_spec': $@\n" if $@; } else { - die "got unexpected data from 'rbd snap ls $name': '$raw'\n"; + die "got unexpected data from 'rbd snap ls $image_spec': '$raw'\n"; } $list = [] if !defined($list); @@ -269,11 +266,9 @@ sub rbd_volume_info { my ($scfg, $storeid, $volname, $snap) = @_; my $cmd = undef; + my $spec = get_rbd_path($scfg, $volname, $snap); - my @options = ('info', $volname, '--format', 'json'); - if ($snap) { - push @options, '--snap', $snap; - } + my @options = ('info', $spec, '--format', 'json'); $cmd = $rbd_cmd->($scfg, $storeid, @options); @@ -300,7 +295,8 @@ sub rbd_volume_info { sub rbd_volume_du { my ($scfg, $storeid, $volname) = @_; - my @options = ('du', $volname, '--format', 'json'); + my $spec = get_rbd_path($scfg, $volname); + my @options = ('du', $spec, '--format', 'json'); my $cmd = $rbd_cmd->($scfg, $storeid, @options); my $raw = ''; @@ -471,14 +467,13 @@ sub path { my $cmd_option = PVE::CephConfig::ceph_connect_option($scfg, $storeid); my ($vtype, $name, $vmid) = $class->parse_volname($volname); - $name .= '@'.$snapname if $snapname; if ($scfg->{krbd}) { - my $rbd_dev_path = get_rbd_dev_path($scfg, $storeid, $name); + my $rbd_dev_path = get_rbd_dev_path($scfg, $storeid, $name, $snapname); return ($rbd_dev_path, $vmid, $vtype); } - my $rbd_path = get_rbd_path($scfg, $name); + my $rbd_path = get_rbd_path($scfg, $name, $snapname); my $path = "rbd:${rbd_path}"; $path .= ":conf=$cmd_option->{ceph_conf}" if $cmd_option->{ceph_conf}; @@ -560,8 +555,9 @@ sub create_base { my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $newname, $snap); if (!$protected){ - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $newname, '--snap', $snap); - run_rbd_command($cmd, errmsg => "rbd protect $newname snap '$snap' error"); + my $snap_spec = get_rbd_path($scfg, $newname, $snap); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); } return $newvolname; @@ -588,8 +584,9 @@ sub clone_image { my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $volname, $snapname); if (!$protected) { - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $volname, '--snap', $snapname); - run_rbd_command($cmd, errmsg => "rbd protect $volname snap $snapname error"); + my $snap_spec = get_rbd_path($scfg, $volname, $snapname); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); } } @@ -597,8 +594,7 @@ sub clone_image { $newvol = $name if length($snapname); my @options = ( - get_rbd_path($scfg, $basename), - '--snap', $snap, + get_rbd_path($scfg, $basename, $snap), ); push @options, ('--data-pool', $scfg->{'data-pool'}) if $scfg->{'data-pool'}; @@ -623,7 +619,7 @@ sub alloc_image { ); push @options, ('--data-pool', $scfg->{'data-pool'}) if $scfg->{'data-pool'}; - my $cmd = $rbd_cmd->($scfg, $storeid, 'create', @options, $name); + my $cmd = $rbd_cmd->($scfg, $storeid, 'create', @options, get_rbd_path($scfg, $name)); run_rbd_command($cmd, errmsg => "rbd create '$name' error"); return $name; @@ -635,22 +631,23 @@ sub free_image { my ($vtype, $name, $vmid, undef, undef, undef) = $class->parse_volname($volname); - - my $snaps = rbd_ls_snap($scfg, $storeid, $name); + my $image_spec = get_rbd_path($scfg, $name); + my $snaps = rbd_ls_snap($scfg, $storeid, $image_spec); foreach my $snap (keys %$snaps) { if ($snaps->{$snap}->{protected}) { - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $name, '--snap', $snap); - run_rbd_command($cmd, errmsg => "rbd unprotect $name snap '$snap' error"); + my $snap_spec = get_rbd_path($scfg, $name, $snap); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd unprotect $snap_spec error"); } } $class->deactivate_volume($storeid, $scfg, $volname); - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'purge', $name); - run_rbd_command($cmd, errmsg => "rbd snap purge '$name' error"); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'purge', $image_spec); + run_rbd_command($cmd, errmsg => "rbd snap purge '$image_spec' error"); - $cmd = $rbd_cmd->($scfg, $storeid, 'rm', $name); - run_rbd_command($cmd, errmsg => "rbd rm '$name' error"); + $cmd = $rbd_cmd->($scfg, $storeid, 'rm', $image_spec); + run_rbd_command($cmd, errmsg => "rbd rm '$image_spec' error"); return undef; } @@ -725,20 +722,18 @@ sub deactivate_storage { sub map_volume { my ($class, $storeid, $scfg, $volname, $snapname) = @_; - my ($vtype, $img_name, $vmid) = $class->parse_volname($volname); + my ($vtype, $name, $vmid) = $class->parse_volname($volname); - my $name = $img_name; - $name .= '@'.$snapname if $snapname; - - my $kerneldev = get_rbd_dev_path($scfg, $storeid, $name); + my $kerneldev = get_rbd_dev_path($scfg, $storeid, $name, $snapname); return $kerneldev if -b $kerneldev; # already mapped # features can only be enabled/disabled for image, not for snapshot! - $krbd_feature_update->($scfg, $storeid, $img_name); + $krbd_feature_update->($scfg, $storeid, $name); - my $cmd = $rbd_cmd->($scfg, $storeid, 'map', $name); - run_rbd_command($cmd, errmsg => "can't map rbd volume $name"); + my $spec = get_rbd_path($scfg, $name, $snapname); + my $cmd = $rbd_cmd->($scfg, $storeid, 'map', $spec); + run_rbd_command($cmd, errmsg => "can't map rbd volume '$spec'"); return $kerneldev; } @@ -747,9 +742,8 @@ sub unmap_volume { my ($class, $storeid, $scfg, $volname, $snapname) = @_; my ($vtype, $name, $vmid) = $class->parse_volname($volname); - $name .= '@'.$snapname if $snapname; - my $kerneldev = get_rbd_dev_path($scfg, $storeid, $name); + my $kerneldev = get_rbd_dev_path($scfg, $storeid, $name, $snapname); if (-b $kerneldev) { my $cmd = $rbd_cmd->($scfg, $storeid, 'unmap', $kerneldev); @@ -791,8 +785,10 @@ sub volume_resize { my ($vtype, $name, $vmid) = $class->parse_volname($volname); - my $cmd = $rbd_cmd->($scfg, $storeid, 'resize', '--size', int(ceil($size/1024/1024)), $name); - run_rbd_command($cmd, errmsg => "rbd resize '$volname' error"); + my $image_spec = get_rbd_path($scfg, $volname); + $size = int(ceil($size/1024/1024)); + my $cmd = $rbd_cmd->($scfg, $storeid, 'resize', '--size', $size, $image_spec); + run_rbd_command($cmd, errmsg => "rbd resize '$image_spec' error"); return undef; } @@ -801,8 +797,9 @@ sub volume_snapshot { my ($vtype, $name, $vmid) = $class->parse_volname($volname); - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'create', '--snap', $snap, $name); - run_rbd_command($cmd, errmsg => "rbd snapshot '$volname' error"); + my $snap_spec = get_rbd_path($scfg, $name, $snap); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'create', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd snapshot '$snap_spec' error"); return undef; } @@ -811,8 +808,9 @@ sub volume_snapshot_rollback { my ($vtype, $name, $vmid) = $class->parse_volname($volname); - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'rollback', '--snap', $snap, $name); - run_rbd_command($cmd, errmsg => "rbd snapshot $volname to '$snap' error"); + my $snap_spec = get_rbd_path($scfg, $name, $snap); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'rollback', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd snapshot rollback to '$snap_spec' error"); } sub volume_snapshot_delete { @@ -823,14 +821,16 @@ sub volume_snapshot_delete { my ($vtype, $name, $vmid) = $class->parse_volname($volname); my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $name, $snap); + my $snap_spec = get_rbd_path($scfg, $volname, $snap); + if ($protected){ - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $name, '--snap', $snap); - run_rbd_command($cmd, errmsg => "rbd unprotect $name snap '$snap' error"); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd unprotect '$snap_spec' error"); } - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'rm', '--snap', $snap, $name); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'rm', $snap_spec); - run_rbd_command($cmd, errmsg => "rbd snapshot '$volname' error"); + run_rbd_command($cmd, errmsg => "rbd snapshot delete '$snap_spec' error"); return undef; } @@ -890,7 +890,9 @@ sub volume_export { my ($size) = $class->volume_size_info($scfg, $storeid, $volname); PVE::Storage::Plugin::write_common_header($fh, $size); - my $cmd = $rbd_cmd->($scfg, $storeid, 'export', '--export-format', '1', $volname, '-'); + + my $snap_spec = get_rbd_path($scfg, $volname, $snapshot); + my $cmd = $rbd_cmd->($scfg, $storeid, 'export', '--export-format', '1', $snap_spec, '-'); run_rbd_command( $cmd, errmsg => 'could not export image', @@ -938,8 +940,9 @@ sub volume_import { my ($size) = PVE::Storage::Plugin::read_common_header($fh); $size = PVE::Storage::Common::align_size_up($size, 1024) / 1024; + my $image_spec = get_rbd_path($scfg, $volname); eval { - my $cmd = $rbd_cmd->($scfg, $storeid, 'import', '--export-format', '1', '-', $volname); + my $cmd = $rbd_cmd->($scfg, $storeid, 'import', '--export-format', '1', '-', $image_spec); run_rbd_command( $cmd, errmsg => 'could not import image', @@ -976,11 +979,13 @@ sub rename_volume { die "target volume '${target_volname}' already exists\n" if rbd_volume_exists($scfg, $storeid, $target_volname); - my $cmd = $rbd_cmd->($scfg, $storeid, 'rename', $source_image, $target_volname); + my $source_spec = get_rbd_path($scfg, $source_volname); + my $target_spec = get_rbd_path($scfg, $target_volname); + my $cmd = $rbd_cmd->($scfg, $storeid, 'rename', $source_spec, $target_spec); run_rbd_command( $cmd, - errmsg => "could not rename image '${source_image}' to '${target_volname}'", + errmsg => "could not rename image '${source_spec}' to '${target_spec}'", ); eval { $class->unmap_volume($storeid, $scfg, $source_volname); }; -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pve-devel] [PATCH storage 2/3] fix #6338: rbd: use image-/snap-spec consistently 2025-04-23 13:59 ` [pve-devel] [PATCH storage 2/3] fix #6338: rbd: use image-/snap-spec consistently Fabian Grünbichler @ 2025-05-05 14:24 ` Fiona Ebner 0 siblings, 0 replies; 9+ messages in thread From: Fiona Ebner @ 2025-05-05 14:24 UTC (permalink / raw) To: Proxmox VE development discussion, Fabian Grünbichler Am 23.04.25 um 15:59 schrieb Fabian Grünbichler: > diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm > index 8c67a37..3bb5807 100644 > --- a/src/PVE/Storage/RBDPlugin.pm > +++ b/src/PVE/Storage/RBDPlugin.pm > @@ -89,22 +89,17 @@ my $rbd_cmd = sub { > my ($scfg, $storeid, $op, @options) = @_; > > my $cmd_option = PVE::CephConfig::ceph_connect_option($scfg, $storeid); > - my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; > > my $cmd = ['/usr/bin/rbd']; > - if ($op eq 'import') { > - push $cmd->@*, '--dest-pool', $pool; > - } else { > + # `ls` doesn't take an image-spec, otherwise pool and namespace should be specified there > + if ($op eq 'ls') { > + my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; > push $cmd->@*, '-p', $pool; > + if (defined($scfg->{namespace})) { > + push @$cmd, '--namespace', $cfg->{namespace}; Typo here that's fixed in next commit > @@ -890,7 +890,9 @@ sub volume_export { > > my ($size) = $class->volume_size_info($scfg, $storeid, $volname); > PVE::Storage::Plugin::write_common_header($fh, $size); > - my $cmd = $rbd_cmd->($scfg, $storeid, 'export', '--export-format', '1', $volname, '-'); > + > + my $snap_spec = get_rbd_path($scfg, $volname, $snapshot); > + my $cmd = $rbd_cmd->($scfg, $storeid, 'export', '--export-format', '1', $snap_spec, '-'); > run_rbd_command( > $cmd, > errmsg => 'could not export image', Oh, so a snapshot was never exported before, but always the image? Mea culpa. Can only be reached via manual CLI luckily, but still good to get fixed. You'll need to adapt getting the size too in the lines above, that still uses just $volname. Other than those, looks good to me. _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers 2025-04-23 13:59 [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 1/3] rbd: extend get_rbd_(dev_)path helpers with $snap parameter Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 2/3] fix #6338: rbd: use image-/snap-spec consistently Fabian Grünbichler @ 2025-04-23 13:59 ` Fabian Grünbichler 2025-05-05 14:24 ` Fiona Ebner 2025-04-30 15:51 ` [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Aaron Lauterer 3 siblings, 1 reply; 9+ messages in thread From: Fabian Grünbichler @ 2025-04-23 13:59 UTC (permalink / raw) To: pve-devel this is a bit repetitive otherwise, no functional changes intended. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> --- src/PVE/Storage/RBDPlugin.pm | 55 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm index 3bb5807..6604bc3 100644 --- a/src/PVE/Storage/RBDPlugin.pm +++ b/src/PVE/Storage/RBDPlugin.pm @@ -96,7 +96,7 @@ my $rbd_cmd = sub { my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; push $cmd->@*, '-p', $pool; if (defined($scfg->{namespace})) { - push @$cmd, '--namespace', $cfg->{namespace}; + push @$cmd, '--namespace', $scfg->{namespace}; } } @@ -262,6 +262,25 @@ sub rbd_ls_snap { return $res; } +my sub rbd_protect_snap { + my ($scfg, $storeid, $image, $snap) = @_; + my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $image, $snap); + + if (!$protected){ + my $snap_spec = get_rbd_path($scfg, $image, $snap); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); + } +} + +my sub rbd_unprotect_snap { + my ($scfg, $storeid, $image, $snap) = @_; + + my $snap_spec = get_rbd_path($scfg, $image, $snap); + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $snap_spec); + run_rbd_command($cmd, errmsg => "rbd unprotect '$snap_spec' error"); +} + sub rbd_volume_info { my ($scfg, $storeid, $volname, $snap) = @_; @@ -552,13 +571,7 @@ sub create_base { $class->volume_snapshot($scfg, $storeid, $newname, $snap, $running); - my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $newname, $snap); - - if (!$protected){ - my $snap_spec = get_rbd_path($scfg, $newname, $snap); - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); - run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); - } + rbd_protect_snap($scfg, $storeid, $newname, $snap); return $newvolname; @@ -580,15 +593,7 @@ sub clone_image { warn "clone $volname: $basename snapname $snap to $name\n"; - if (length($snapname)) { - my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $volname, $snapname); - - if (!$protected) { - my $snap_spec = get_rbd_path($scfg, $volname, $snapname); - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); - run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); - } - } + rbd_protect_snap($scfg, $storeid, $volname, $snap) if length($snapname); my $newvol = "$basename/$name"; $newvol = $name if length($snapname); @@ -634,11 +639,8 @@ sub free_image { my $image_spec = get_rbd_path($scfg, $name); my $snaps = rbd_ls_snap($scfg, $storeid, $image_spec); foreach my $snap (keys %$snaps) { - if ($snaps->{$snap}->{protected}) { - my $snap_spec = get_rbd_path($scfg, $name, $snap); - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $snap_spec); - run_rbd_command($cmd, errmsg => "rbd unprotect $snap_spec error"); - } + rbd_unprotect_snap($scfg, $storeid, $name, $snap) + if $snaps->{$snap}->{protected}; } $class->deactivate_volume($storeid, $scfg, $volname); @@ -821,13 +823,10 @@ sub volume_snapshot_delete { my ($vtype, $name, $vmid) = $class->parse_volname($volname); my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $name, $snap); + + rbd_unprotect_snap($scfg, $storeid, $volname, $snap) if $protected; + my $snap_spec = get_rbd_path($scfg, $volname, $snap); - - if ($protected){ - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'unprotect', $snap_spec); - run_rbd_command($cmd, errmsg => "rbd unprotect '$snap_spec' error"); - } - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'rm', $snap_spec); run_rbd_command($cmd, errmsg => "rbd snapshot delete '$snap_spec' error"); -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers 2025-04-23 13:59 ` [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers Fabian Grünbichler @ 2025-05-05 14:24 ` Fiona Ebner 2025-05-06 11:07 ` Fabian Grünbichler 0 siblings, 1 reply; 9+ messages in thread From: Fiona Ebner @ 2025-05-05 14:24 UTC (permalink / raw) To: Proxmox VE development discussion, Fabian Grünbichler Am 23.04.25 um 15:59 schrieb Fabian Grünbichler: > this is a bit repetitive otherwise, no functional changes intended. > > Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> > --- > src/PVE/Storage/RBDPlugin.pm | 55 ++++++++++++++++++------------------ > 1 file changed, 27 insertions(+), 28 deletions(-) > > diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm > index 3bb5807..6604bc3 100644 > --- a/src/PVE/Storage/RBDPlugin.pm > +++ b/src/PVE/Storage/RBDPlugin.pm > @@ -96,7 +96,7 @@ my $rbd_cmd = sub { > my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; > push $cmd->@*, '-p', $pool; > if (defined($scfg->{namespace})) { > - push @$cmd, '--namespace', $cfg->{namespace}; > + push @$cmd, '--namespace', $scfg->{namespace}; > } > } > Should be squashed into previous commit. > @@ -262,6 +262,25 @@ sub rbd_ls_snap { > return $res; > } > > +my sub rbd_protect_snap { > + my ($scfg, $storeid, $image, $snap) = @_; > + my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $image, $snap); > + > + if (!$protected){ Style nit: missing space between '){' > + my $snap_spec = get_rbd_path($scfg, $image, $snap); > + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); > + run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); > + } > +} > + > @@ -580,15 +593,7 @@ sub clone_image { > > warn "clone $volname: $basename snapname $snap to $name\n"; > > - if (length($snapname)) { > - my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $volname, $snapname); > - > - if (!$protected) { > - my $snap_spec = get_rbd_path($scfg, $volname, $snapname); > - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); > - run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); > - } > - } > + rbd_protect_snap($scfg, $storeid, $volname, $snap) if length($snapname); Last argument should be $snapname > > my $newvol = "$basename/$name"; > $newvol = $name if length($snapname); _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers 2025-05-05 14:24 ` Fiona Ebner @ 2025-05-06 11:07 ` Fabian Grünbichler 2025-05-06 11:40 ` Fiona Ebner 0 siblings, 1 reply; 9+ messages in thread From: Fabian Grünbichler @ 2025-05-06 11:07 UTC (permalink / raw) To: Fiona Ebner, Proxmox VE development discussion On May 5, 2025 4:24 pm, Fiona Ebner wrote: > Am 23.04.25 um 15:59 schrieb Fabian Grünbichler: >> this is a bit repetitive otherwise, no functional changes intended. >> >> Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> >> --- >> src/PVE/Storage/RBDPlugin.pm | 55 ++++++++++++++++++------------------ >> 1 file changed, 27 insertions(+), 28 deletions(-) >> >> diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm >> index 3bb5807..6604bc3 100644 >> --- a/src/PVE/Storage/RBDPlugin.pm >> +++ b/src/PVE/Storage/RBDPlugin.pm >> @@ -96,7 +96,7 @@ my $rbd_cmd = sub { >> my $pool = $scfg->{pool} ? $scfg->{pool} : 'rbd'; >> push $cmd->@*, '-p', $pool; >> if (defined($scfg->{namespace})) { >> - push @$cmd, '--namespace', $cfg->{namespace}; >> + push @$cmd, '--namespace', $scfg->{namespace}; >> } >> } >> > > Should be squashed into previous commit. ack > >> @@ -262,6 +262,25 @@ sub rbd_ls_snap { >> return $res; >> } >> >> +my sub rbd_protect_snap { >> + my ($scfg, $storeid, $image, $snap) = @_; >> + my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $image, $snap); >> + >> + if (!$protected){ > > Style nit: missing space between '){' ack > >> + my $snap_spec = get_rbd_path($scfg, $image, $snap); >> + my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); >> + run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); >> + } >> +} >> + > > >> @@ -580,15 +593,7 @@ sub clone_image { >> >> warn "clone $volname: $basename snapname $snap to $name\n"; >> >> - if (length($snapname)) { >> - my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $volname, $snapname); >> - >> - if (!$protected) { >> - my $snap_spec = get_rbd_path($scfg, $volname, $snapname); >> - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); >> - run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); >> - } >> - } >> + rbd_protect_snap($scfg, $storeid, $volname, $snap) if length($snapname); > > Last argument should be $snapname not really - this is saying "protect the snapshot $snap if it is not the (already protected) '__base__' snapshot". probably the whole logic should be adapted to make this explicit though, e.g., something like: diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm index 6604bc3..5c1a8e2 100644 --- a/src/PVE/Storage/RBDPlugin.pm +++ b/src/PVE/Storage/RBDPlugin.pm @@ -580,23 +580,26 @@ sub create_base { sub clone_image { my ($class, $scfg, $storeid, $volname, $vmid, $snapname) = @_; - my $snap = '__base__'; - $snap = $snapname if length $snapname; - my ($vtype, $basename, $basevmid, undef, undef, $isBase) = $class->parse_volname($volname); - die "$volname is not a base image and snapname is not provided\n" - if !$isBase && !length($snapname); + my $snap; + + if ($snapname) { + $snap = $snapname; + } elsif ($isBase) { + $snap = '__base__'; + } else { + die "$volname is not a base image and snapname is not provided\n"; + } my $name = $class->find_free_diskname($storeid, $scfg, $vmid); warn "clone $volname: $basename snapname $snap to $name\n"; - rbd_protect_snap($scfg, $storeid, $volname, $snap) if length($snapname); + rbd_protect_snap($scfg, $storeid, $volname, $snap) if $snap ne '__base__'; - my $newvol = "$basename/$name"; - $newvol = $name if length($snapname); + my $newvol = $snapname ? $name : "$basename/$name"; my @options = ( get_rbd_path($scfg, $basename, $snap), _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers 2025-05-06 11:07 ` Fabian Grünbichler @ 2025-05-06 11:40 ` Fiona Ebner 0 siblings, 0 replies; 9+ messages in thread From: Fiona Ebner @ 2025-05-06 11:40 UTC (permalink / raw) To: Fabian Grünbichler, Proxmox VE development discussion Am 06.05.25 um 13:07 schrieb Fabian Grünbichler: >>> @@ -580,15 +593,7 @@ sub clone_image { >>> >>> warn "clone $volname: $basename snapname $snap to $name\n"; >>> >>> - if (length($snapname)) { >>> - my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, $volname, $snapname); >>> - >>> - if (!$protected) { >>> - my $snap_spec = get_rbd_path($scfg, $volname, $snapname); >>> - my $cmd = $rbd_cmd->($scfg, $storeid, 'snap', 'protect', $snap_spec); >>> - run_rbd_command($cmd, errmsg => "rbd protect '$snap_spec' error"); >>> - } >>> - } >>> + rbd_protect_snap($scfg, $storeid, $volname, $snap) if length($snapname); >> >> Last argument should be $snapname > > not really - this is saying "protect the snapshot $snap if it is not the > (already protected) '__base__' snapshot". probably the whole logic > should be adapted to make this explicit though, e.g., something like: Oh right, it doesn't matter semantically, because there is $snap = $snapname if length $snapname; further above. I just compared with the old code that used $snapname as the argument, which you don't anymore. > diff --git a/src/PVE/Storage/RBDPlugin.pm b/src/PVE/Storage/RBDPlugin.pm > index 6604bc3..5c1a8e2 100644 > --- a/src/PVE/Storage/RBDPlugin.pm > +++ b/src/PVE/Storage/RBDPlugin.pm > @@ -580,23 +580,26 @@ sub create_base { > sub clone_image { > my ($class, $scfg, $storeid, $volname, $vmid, $snapname) = @_; > > - my $snap = '__base__'; > - $snap = $snapname if length $snapname; > - > my ($vtype, $basename, $basevmid, undef, undef, $isBase) = > $class->parse_volname($volname); > > - die "$volname is not a base image and snapname is not provided\n" > - if !$isBase && !length($snapname); > + my $snap; > + > + if ($snapname) { > + $snap = $snapname; > + } elsif ($isBase) { > + $snap = '__base__'; > + } else { > + die "$volname is not a base image and snapname is not provided\n"; > + } > > my $name = $class->find_free_diskname($storeid, $scfg, $vmid); > > warn "clone $volname: $basename snapname $snap to $name\n"; > > - rbd_protect_snap($scfg, $storeid, $volname, $snap) if length($snapname); > + rbd_protect_snap($scfg, $storeid, $volname, $snap) if $snap ne '__base__'; > > - my $newvol = "$basename/$name"; > - $newvol = $name if length($snapname); > + my $newvol = $snapname ? $name : "$basename/$name"; > > my @options = ( > get_rbd_path($scfg, $basename, $snap), > Looks fine to me at a glance. _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/.. 2025-04-23 13:59 [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Fabian Grünbichler ` (2 preceding siblings ...) 2025-04-23 13:59 ` [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers Fabian Grünbichler @ 2025-04-30 15:51 ` Aaron Lauterer 3 siblings, 0 replies; 9+ messages in thread From: Aaron Lauterer @ 2025-04-30 15:51 UTC (permalink / raw) To: Proxmox VE development discussion, Fabian Grünbichler Tested this patch series by: * create a new VM on ceph RBD * took & removed snapshot (with memory) * cloned VM * converted to template (rename from vm-… to base-… worked) * created linked clone * destroy template -> fail due to linked clone * destroy linked clone * destroy template namespace tests: * create rbd namespace * move-disk of VM to namespace (main disk, EFI, tpm) * remote migrate from rbd namespace to other node with local-lvm * remote migrate back from local-lvm to rbd namespace storage The code changes look good and I didn't notice anything there. So with this, consider this series Reviewed-By: Aaron Lauterer <a.lauterer@proxmox.com> Tested-By: Aaron Lauterer <a.lauterer@proxmox.com> On 2025-04-23 15:59, Fabian Grünbichler wrote: > the 'rbd' CLI tool has two ways of specifying which images/snapshots to > operate on: > - the deprecated --(dest-)pool, --namespace, --image and --snap parameters > - the new style 'spec'-based variant, passing [pool/[namespace/]]image[@snapshot] > > we are currently using a mix of both (passing pool, namespace and snap > as needed via parameters, and the image-name as argument). this patch > series switches everything to use image or snap specs, except for `ls`, > which can't be switched over, because it doesn't operate on images at > all. > > `unmap` doesn't support `--namespace` (but doesn't need it, since it > takes the kernel dev as argument). `import` doesn't either, but does > require it when a namespace is used as import target (this bug prompted > the whole excursion resulting in this patch series). > > I smoke-tested the changes, but it's possible I missed some operation or > corner case when converting, so additional testing is highly > appreciated. > > Fabian Grünbichler (3): > rbd: extend get_rbd_(dev_)path helpers with $snap parameter > fix #6338: rbd: use image-/snap-spec consistently > rbd: add protect/unprotect helpers > > src/PVE/Storage/RBDPlugin.pm | 167 ++++++++++++++++++----------------- > 1 file changed, 86 insertions(+), 81 deletions(-) > _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-05-06 11:41 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-04-23 13:59 [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 1/3] rbd: extend get_rbd_(dev_)path helpers with $snap parameter Fabian Grünbichler 2025-04-23 13:59 ` [pve-devel] [PATCH storage 2/3] fix #6338: rbd: use image-/snap-spec consistently Fabian Grünbichler 2025-05-05 14:24 ` Fiona Ebner 2025-04-23 13:59 ` [pve-devel] [PATCH storage 3/3] rbd: add protect/unprotect helpers Fabian Grünbichler 2025-05-05 14:24 ` Fiona Ebner 2025-05-06 11:07 ` Fabian Grünbichler 2025-05-06 11:40 ` Fiona Ebner 2025-04-30 15:51 ` [pve-devel] [RFC storage 0/3] rbd: use image-/snap-spec instead of --pool/ Aaron Lauterer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inboxService provided by Proxmox Server Solutions GmbH | Privacy | Legal