From 961c1d12fd1637414c993aad60bdb9cbd5543c0a Mon Sep 17 00:00:00 2001 From: Yug Date: Thu, 18 Mar 2021 16:53:08 +0530 Subject: [PATCH] rbd: add support to create clone in different pool added support to create image in different pool. if the snapshot/rbd image exists in one pool we can create a clone the clone of the rbd image to a different pool. Co-authored-by: Madhu Rajanna Signed-off-by: Yug --- internal/rbd/clone.go | 2 +- internal/rbd/controllerserver.go | 6 +++++- internal/rbd/rbd_util.go | 17 +++++++++++++---- internal/rbd/snapshot.go | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/internal/rbd/clone.go b/internal/rbd/clone.go index b4662723a..1f4fb16a0 100644 --- a/internal/rbd/clone.go +++ b/internal/rbd/clone.go @@ -101,7 +101,7 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume) // need to check for flatten here. // as the snap exists,create clone image and delete temporary snapshot // and add task to flatten temporary cloned image - err = rv.cloneRbdImageFromSnapshot(ctx, snap) + err = rv.cloneRbdImageFromSnapshot(ctx, snap, parentVol) if err != nil { util.ErrorLog(ctx, "failed to clone rbd image %s from snapshot %s: %v", rv.RbdImageName, snap.RbdSnapName, err) err = fmt.Errorf("failed to clone rbd image %s from snapshot %s: %w", rv.RbdImageName, snap.RbdSnapName, err) diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index c657c3439..14fde0a2d 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -464,8 +464,12 @@ func (cs *ControllerServer) createVolumeFromSnapshot(ctx context.Context, cr *ut // update parent name(rbd image name in snapshot) rbdSnap.RbdImageName = rbdSnap.RbdSnapName + parentVol := generateVolFromSnap(rbdSnap) + // as we are operating on single cluster reuse the connection + parentVol.conn = rbdVol.conn.Copy() + // create clone image and delete snapshot - err = rbdVol.cloneRbdImageFromSnapshot(ctx, rbdSnap) + err = rbdVol.cloneRbdImageFromSnapshot(ctx, rbdSnap, parentVol) if err != nil { util.ErrorLog(ctx, "failed to clone rbd image %s from snapshot %s: %v", rbdVol, rbdSnap, err) return err diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index 0053c76ed..1d42a0bd9 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -1079,11 +1079,19 @@ func (rv *rbdVolume) deleteSnapshot(ctx context.Context, pOpts *rbdSnapshot) err return err } -func (rv *rbdVolume) cloneRbdImageFromSnapshot(ctx context.Context, pSnapOpts *rbdSnapshot) error { - image := rv.RbdImageName +func (rv *rbdVolume) cloneRbdImageFromSnapshot(ctx context.Context, pSnapOpts *rbdSnapshot, parentVol *rbdVolume) error { var err error logMsg := "rbd: clone %s %s (features: %s) using mon %s" + err = parentVol.openIoctx() + if err != nil { + return fmt.Errorf("failed to get parent IOContext: %w", err) + } + defer func() { + defer parentVol.ioctx.Destroy() + parentVol.ioctx = nil + }() + options := librbd.NewRbdImageOptions() defer options.Destroy() @@ -1096,7 +1104,7 @@ func (rv *rbdVolume) cloneRbdImageFromSnapshot(ctx context.Context, pSnapOpts *r } util.DebugLog(ctx, logMsg, - pSnapOpts, image, rv.imageFeatureSet.Names(), rv.Monitors) + pSnapOpts, rv, rv.imageFeatureSet.Names(), rv.Monitors) if rv.imageFeatureSet != 0 { err = options.SetUint64(librbd.RbdImageOptionFeatures, uint64(rv.imageFeatureSet)) @@ -1110,12 +1118,13 @@ func (rv *rbdVolume) cloneRbdImageFromSnapshot(ctx context.Context, pSnapOpts *r return fmt.Errorf("failed to set image features: %w", err) } + // As the clone is yet to be created, open the Ioctx. err = rv.openIoctx() if err != nil { return fmt.Errorf("failed to get IOContext: %w", err) } - err = librbd.CloneImage(rv.ioctx, pSnapOpts.RbdImageName, pSnapOpts.RbdSnapName, rv.ioctx, rv.RbdImageName, options) + err = librbd.CloneImage(parentVol.ioctx, pSnapOpts.RbdImageName, pSnapOpts.RbdSnapName, rv.ioctx, rv.RbdImageName, options) if err != nil { return fmt.Errorf("failed to create rbd clone: %w", err) } diff --git a/internal/rbd/snapshot.go b/internal/rbd/snapshot.go index b10be0dce..cd2a38453 100644 --- a/internal/rbd/snapshot.go +++ b/internal/rbd/snapshot.go @@ -33,7 +33,7 @@ func createRBDClone(ctx context.Context, parentVol, cloneRbdVol *rbdVolume, snap snap.RbdImageName = parentVol.RbdImageName // create clone image and delete snapshot - err = cloneRbdVol.cloneRbdImageFromSnapshot(ctx, snap) + err = cloneRbdVol.cloneRbdImageFromSnapshot(ctx, snap, parentVol) if err != nil { util.ErrorLog(ctx, "failed to clone rbd image %s from snapshot %s: %v", cloneRbdVol.RbdImageName, snap.RbdSnapName, err) err = fmt.Errorf("failed to clone rbd image %s from snapshot %s: %w", cloneRbdVol.RbdImageName, snap.RbdSnapName, err)