mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
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:
parent
334f237e23
commit
6cc11c15d3
@ -152,6 +152,8 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
|
|||||||
}
|
}
|
||||||
defer j.Destroy()
|
defer j.Destroy()
|
||||||
|
|
||||||
|
// TODO: if rv exists, delete the image and start over?
|
||||||
|
|
||||||
err = rv.doSnapClone(ctx, parentVol)
|
err = rv.doSnapClone(ctx, parentVol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status.Error(codes.Internal, err.Error())
|
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)
|
err = j.StoreImageID(ctx, rv.JournalPool, rv.ReservedID, rv.ImageID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.ErrorLog(ctx, "failed to store volume %s: %v", rv, err)
|
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 rv.ThickProvision {
|
||||||
if errFlatten != nil {
|
err = tempClone.DeepCopy(rv)
|
||||||
return errFlatten
|
if err != nil {
|
||||||
}
|
return fmt.Errorf("failed to deep copy %q into %q: %w", parentVol, rv, err)
|
||||||
// create snap of temp clone from temporary cloned image
|
}
|
||||||
// create final clone
|
} else {
|
||||||
// delete snap of temp clone
|
// flatten clone
|
||||||
errClone = createRBDClone(ctx, tempClone, rv, cloneSnap, rv.conn.Creds)
|
errFlatten = tempClone.flattenRbdImage(ctx, rv.conn.Creds, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
|
||||||
if errClone != nil {
|
if errFlatten != nil {
|
||||||
// set errFlatten error to cleanup temporary snapshot and temporary clone
|
return errFlatten
|
||||||
errFlatten = errors.New("failed to create user requested cloned image")
|
}
|
||||||
return errClone
|
|
||||||
|
// 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
|
return nil
|
||||||
|
@ -1508,6 +1508,32 @@ func (rv *rbdVolume) RepairThickProvision() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopy creates an independent image (dest) from the source image. This
|
||||||
|
// process may take some time when the image is large.
|
||||||
|
func (rv *rbdVolume) DeepCopy(dest *rbdVolume) error {
|
||||||
|
opts := librbd.NewRbdImageOptions()
|
||||||
|
defer opts.Destroy()
|
||||||
|
|
||||||
|
// when doing DeepCopy, also flatten the new image
|
||||||
|
err := opts.SetUint64(librbd.ImageOptionFlatten, 1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dest.openIoctx()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
image, err := rv.open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer image.Close()
|
||||||
|
|
||||||
|
return image.DeepCopy(dest.ioctx, dest.RbdImageName, opts)
|
||||||
|
}
|
||||||
|
|
||||||
func (rv *rbdVolume) listSnapshots() ([]librbd.SnapInfo, error) {
|
func (rv *rbdVolume) listSnapshots() ([]librbd.SnapInfo, error) {
|
||||||
image, err := rv.open()
|
image, err := rv.open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user