From f9ab14e82685c2d3ba4709c17823c653a58e1584 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Mon, 22 Jul 2024 18:18:26 +0200 Subject: [PATCH] rbd: check if an image is part of a group before adding it A RBD image can only be part of a single group. While an image is added to a group, check if the image is already part of a group, and return an error in case it is. Signed-off-by: Niels de Vos --- internal/rbd/group.go | 23 ++++++++++++++++++++++- internal/rbd/group/volume_group.go | 6 ------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/internal/rbd/group.go b/internal/rbd/group.go index af59776aa..46c7739d7 100644 --- a/internal/rbd/group.go +++ b/internal/rbd/group.go @@ -38,7 +38,28 @@ func (rv *rbdVolume) AddToGroup(ctx context.Context, vg types.VolumeGroup) error return fmt.Errorf("could not get name for volume group %q: %w", vg, err) } - return librbd.GroupImageAdd(ioctx, name, rv.ioctx, rv.RbdImageName) + // check if the image is already part of a group + // "rbd: ret=-17, File exists" is returned if the image is part of ANY group + image, err := rv.open() + if err != nil { + return fmt.Errorf("failed to open image %q: %w", rv, err) + } + + info, err := image.GetGroup() + if err != nil { + return fmt.Errorf("could not get group information for image %q: %w", rv, err) + } + + if info.Name != "" && info.Name != name { + return fmt.Errorf("image %q is already part of volume group %q", rv, info.Name) + } + + err = librbd.GroupImageAdd(ioctx, name, rv.ioctx, rv.RbdImageName) + if err != nil { + return fmt.Errorf("failed to add image %q to volume group %q: %w", rv, vg, err) + } + + return nil } // RemoveFromGroup removes the image from the group. This is called from the diff --git a/internal/rbd/group/volume_group.go b/internal/rbd/group/volume_group.go index c41db02d0..e4f818b3c 100644 --- a/internal/rbd/group/volume_group.go +++ b/internal/rbd/group/volume_group.go @@ -356,12 +356,6 @@ func (vg *volumeGroup) Delete(ctx context.Context) error { func (vg *volumeGroup) AddVolume(ctx context.Context, vol types.Volume) error { err := vol.AddToGroup(ctx, vg) if err != nil { - // rados.ErrObjectExists does not match the rbd error (there is no EEXISTS error) - if errors.Is(rados.ErrObjectExists, err) || strings.Contains(err.Error(), "ret=-17") { - log.DebugLog(ctx, "volume %q is already part of volume group %q: %v", vol, vg, err) - return nil - } - return fmt.Errorf("failed to add volume %q to volume group %q: %w", vol, vg, err) }