Skip to content

Commit

Permalink
rbd: make VolumeGroup Create/Delete/AddVolume/RemoveVolume idempotent
Browse files Browse the repository at this point in the history
Add extra error checking to make sure trying to create an existing
volume group does not result in a failure. The same counts for deleting
a non-existing volume group, and adding/removing volumes to/from the
volume group.

Signed-off-by: Niels de Vos <ndevos@ibm.com>
  • Loading branch information
nixpanic committed Jul 22, 2024
1 parent 5c8bdb0 commit 6dec5e0
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion internal/csi-addons/rbd/volumegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (vs *VolumeGroupServer) CreateVolumeGroup(
err.Error())
}

log.DebugLog(ctx, fmt.Sprintf("VolumeGroup %q had been created", req.GetName()))
log.DebugLog(ctx, fmt.Sprintf("VolumeGroup %q had been created: %+v", req.GetName(), vg))

// add each rbd-image to the RBDVolumeGroup
for _, vol := range volumes {
Expand Down
27 changes: 22 additions & 5 deletions internal/rbd/group/volume_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"strings"

"github.com/ceph/go-ceph/rados"
librbd "github.com/ceph/go-ceph/rbd"
Expand Down Expand Up @@ -131,7 +132,7 @@ func GetVolumeGroup(
volumes = append(volumes, vol)
}

return &volumeGroup{
vg := &volumeGroup{
journal: j,
credentials: creds,
id: id,
Expand All @@ -143,7 +144,11 @@ func GetVolumeGroup(
volumes: volumes,
// all allocated volumes need to be free'd at Destroy() time
volumesToFree: volumes,
}, nil
}

log.DebugLog(ctx, "GetVolumeGroup(%s) returns %+v", id, *vg)

return vg, nil
}

// String makes it easy to include the volumeGroup object in log and error
Expand Down Expand Up @@ -302,8 +307,12 @@ func (vg *volumeGroup) Destroy(ctx context.Context) {
log.DebugLog(ctx, "destroyed volume group instance with id %q", vg.id)
}

func (vg *volumeGroup) Create(ctx context.Context, name string) error {
// TODO: if the group already exists, resolve details and use that
func (vg *volumeGroup) Create(ctx context.Context) error {
name, err := vg.GetName(ctx)
if err != nil {
return fmt.Errorf("missing name to create volume group: %w", err)
}

ioctx, err := vg.GetIOContext(ctx)
if err != nil {
return err
Expand All @@ -314,7 +323,6 @@ func (vg *volumeGroup) Create(ctx context.Context, name string) error {
return fmt.Errorf("failed to create volume group %q: %w", name, err)
}

vg.name = name
log.DebugLog(ctx, "volume group %q has been created", vg)

return nil
Expand Down Expand Up @@ -344,6 +352,11 @@ 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") {
return nil
}

return fmt.Errorf("failed to add volume %q to volume group %q: %w", vol, vg, err)
}

Expand Down Expand Up @@ -390,6 +403,10 @@ func (vg *volumeGroup) RemoveVolume(ctx context.Context, vol types.Volume) error

err := vol.RemoveFromGroup(ctx, vg)
if err != nil {
if errors.Is(librbd.ErrNotExist, err) {
return nil
}

return fmt.Errorf("failed to remove volume %q from volume group %q: %w", vol, vg, err)
}

Expand Down
11 changes: 2 additions & 9 deletions internal/rbd/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,16 +223,9 @@ func (mgr *rbdManager) CreateVolumeGroup(ctx context.Context, name string) (type
}
}()

// check if the volume group exists in the backend
existingName, err := vg.GetName(ctx)
err = vg.Create(ctx)
if err != nil {
// the volume group does not exist yet
err = vg.Create(ctx, vgName)
if err != nil {
return nil, fmt.Errorf("failed to create volume group %q: %w", name, err)
}
} else if existingName != vgName {
return nil, fmt.Errorf("volume group id %q has a name mismatch, expected %q, not %q", name, vgName, existingName)
return nil, fmt.Errorf("failed to create volume group %q: %w", name, err)
}

return vg, nil
Expand Down
2 changes: 1 addition & 1 deletion internal/rbd/types/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type VolumeGroup interface {
ToCSI(ctx context.Context) (*volumegroup.VolumeGroup, error)

// Create makes a new group in the backend storage.
Create(ctx context.Context, name string) error
Create(ctx context.Context) error

// Delete removes the VolumeGroup from the backend storage.
Delete(ctx context.Context) error
Expand Down

0 comments on commit 6dec5e0

Please sign in to comment.