rbd: use DeepCopy to create a thick-provisioned clone

To create a full-allocated RBD image from a snapshot/clone DeepCopy()
can be used. This is needed when the parent of the new volume is
thick-provisioner, so that the new volume is independent of the parent
and thick-provisioned as well.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos
2021-05-27 09:09:49 +02:00
committed by mergify[bot]
parent 334f237e23
commit 6cc11c15d3
2 changed files with 63 additions and 13 deletions

View File

@ -152,6 +152,8 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
}
defer j.Destroy()
// TODO: if rv exists, delete the image and start over?
err = rv.doSnapClone(ctx, parentVol)
if err != nil {
return status.Error(codes.Internal, err.Error())
@ -170,6 +172,19 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
}
}
// TODO: copy thick provision config
thick, err := parentVol.isThickProvisioned()
if err != nil {
return fmt.Errorf("failed checking thick-provisioning of %q: %w", parentVol, err)
}
if thick {
err = rv.setThickProvisioned()
if err != nil {
return fmt.Errorf("failed mark %q thick-provisioned: %w", rv, err)
}
}
err = j.StoreImageID(ctx, rv.JournalPool, rv.ReservedID, rv.ImageID)
if err != nil {
util.ErrorLog(ctx, "failed to store volume %s: %v", rv, err)
@ -221,19 +236,28 @@ func (rv *rbdVolume) doSnapClone(ctx context.Context, parentVol *rbdVolume) erro
}
}
}()
// flatten clone
errFlatten = tempClone.flattenRbdImage(ctx, rv.conn.Creds, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
if errFlatten != nil {
return errFlatten
}
// create snap of temp clone from temporary cloned image
// create final clone
// delete snap of temp clone
errClone = createRBDClone(ctx, tempClone, rv, cloneSnap, rv.conn.Creds)
if errClone != nil {
// set errFlatten error to cleanup temporary snapshot and temporary clone
errFlatten = errors.New("failed to create user requested cloned image")
return errClone
if rv.ThickProvision {
err = tempClone.DeepCopy(rv)
if err != nil {
return fmt.Errorf("failed to deep copy %q into %q: %w", parentVol, rv, err)
}
} else {
// flatten clone
errFlatten = tempClone.flattenRbdImage(ctx, rv.conn.Creds, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
if errFlatten != nil {
return errFlatten
}
// create snap of temp clone from temporary cloned image
// create final clone
// delete snap of temp clone
errClone = createRBDClone(ctx, tempClone, rv, cloneSnap, rv.conn.Creds)
if errClone != nil {
// set errFlatten error to cleanup temporary snapshot and temporary clone
errFlatten = errors.New("failed to create user requested cloned image")
return errClone
}
}
return nil