rbd: restart thick-provisioned PVC snapshot restoring after aborting

In case restoring a snapshot of a thick-PVC failed during DeepCopy(),
the image will exist, but have partial contents. Only when the image has
the thick-provisioned metadata set, it has completed DeepCopy().

When the metadata is missing, the image is deleted, and an error is
returned to the caller. Kubernetes will automatically retry provisioning
on the ABORTED error, and the restoring will get restarted from the
beginning.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2021-06-18 11:38:58 +02:00 committed by mergify[bot]
parent 7f1bdb49d1
commit d2c4cacb39

View File

@ -362,6 +362,27 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C
// rbdVol is a restore from snapshot, rbdSnap is passed // rbdVol is a restore from snapshot, rbdSnap is passed
case vcs.GetSnapshot() != nil: case vcs.GetSnapshot() != nil:
// When restoring of a thick-provisioned volume was happening,
// the image should be marked as thick-provisioned, unless it
// was aborted in flight. In order to restart the
// thick-restoring, delete the volume and let the caller retry
// from the start.
if isThickProvisionRequest(req.GetParameters()) {
thick, err := rbdVol.isThickProvisioned()
if err != nil {
return nil, status.Errorf(codes.Aborted, "failed to verify thick-provisioned volume %q: %s", rbdVol, err)
} else if !thick {
err = deleteImage(ctx, rbdVol, cr)
if err != nil {
return nil, status.Errorf(codes.Aborted, "failed to remove partially cloned volume %q: %s", rbdVol, err)
}
err = undoVolReservation(ctx, rbdVol, cr)
if err != nil {
return nil, status.Errorf(codes.Aborted, "failed to remove volume %q from journal: %s", rbdVol, err)
}
return nil, status.Errorf(codes.Aborted, "restoring thick-provisioned volume %q has been interrupted, please retry", rbdVol)
}
}
// restore from snapshot imploes rbdSnap != nil // restore from snapshot imploes rbdSnap != nil
// check if image depth is reached limit and requires flatten // check if image depth is reached limit and requires flatten
err := checkFlatten(ctx, rbdVol, cr) err := checkFlatten(ctx, rbdVol, cr)