mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-17 20:00:23 +00:00
cephfs: add snap reserve/unreserve and snap exist functionalities
Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
parent
38d005e4e6
commit
5bceb590fd
@ -246,3 +246,132 @@ func reserveVol(ctx context.Context, volOptions *volumeOptions, secret map[strin
|
|||||||
|
|
||||||
return &vid, nil
|
return &vid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reserveSnap is a helper routine to request a UUID reservation for the CSI SnapName and,
|
||||||
|
// to generate the snapshot identifier for the reserved UUID.
|
||||||
|
func reserveSnap(ctx context.Context, volOptions *volumeOptions, parentSubVolName string, snap *cephfsSnapshot, cr *util.Credentials) (*snapshotIdentifier, error) {
|
||||||
|
var (
|
||||||
|
vid snapshotIdentifier
|
||||||
|
imageUUID string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
j, err := snapJournal.Connect(volOptions.Monitors, cr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer j.Destroy()
|
||||||
|
|
||||||
|
imageUUID, vid.FsSnapshotName, err = j.ReserveName(
|
||||||
|
ctx, volOptions.MetadataPool, util.InvalidPoolID,
|
||||||
|
volOptions.MetadataPool, util.InvalidPoolID, snap.RequestName,
|
||||||
|
snap.NamePrefix, parentSubVolName, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate the snapshot ID to return to the CO system
|
||||||
|
vid.SnapshotID, err = util.GenerateVolID(ctx, volOptions.Monitors, cr, volOptions.FscID,
|
||||||
|
"", volOptions.ClusterID, imageUUID, volIDVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
util.DebugLog(ctx, "Generated Snapshot ID (%s) for request name (%s)",
|
||||||
|
vid.SnapshotID, snap.RequestName)
|
||||||
|
|
||||||
|
return &vid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// undoSnapReservation is a helper routine to undo a name reservation for a CSI SnapshotName.
|
||||||
|
func undoSnapReservation(ctx context.Context, volOptions *volumeOptions, vid snapshotIdentifier, snapName string, cr *util.Credentials) error {
|
||||||
|
j, err := snapJournal.Connect(volOptions.Monitors, cr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer j.Destroy()
|
||||||
|
|
||||||
|
err = j.UndoReservation(ctx, volOptions.MetadataPool,
|
||||||
|
volOptions.MetadataPool, vid.FsSnapshotName, snapName)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
checkSnapExists checks to determine if passed in RequestName in volOptions exists on the backend.
|
||||||
|
|
||||||
|
**NOTE:** These functions manipulate the rados omaps that hold information regarding
|
||||||
|
volume names as requested by the CSI drivers. Hence, these need to be invoked only when the
|
||||||
|
respective CSI driver generated volume name based locks are held, as otherwise racy
|
||||||
|
access to these omaps may end up leaving them in an inconsistent state.
|
||||||
|
|
||||||
|
These functions also cleanup omap reservations that are stale. I.e when omap entries exist and
|
||||||
|
backing subvolumes are missing, or one of the omaps exist and the next is missing. This is
|
||||||
|
because, the order of omap creation and deletion are inverse of each other, and protected by the
|
||||||
|
request name lock, and hence any stale omaps are leftovers from incomplete transactions and are
|
||||||
|
hence safe to garbage collect.
|
||||||
|
*/
|
||||||
|
func checkSnapExists(
|
||||||
|
ctx context.Context,
|
||||||
|
volOptions *volumeOptions,
|
||||||
|
parentSubVolName string,
|
||||||
|
snap *cephfsSnapshot,
|
||||||
|
cr *util.Credentials) (*snapshotIdentifier, *snapshotInfo, error) {
|
||||||
|
j, err := snapJournal.Connect(volOptions.Monitors, cr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
defer j.Destroy()
|
||||||
|
|
||||||
|
snapData, err := j.CheckReservation(
|
||||||
|
ctx, volOptions.MetadataPool, snap.RequestName, snap.NamePrefix, parentSubVolName, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if snapData == nil {
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
sid := &snapshotIdentifier{}
|
||||||
|
snapUUID := snapData.ImageUUID
|
||||||
|
snapID := snapData.ImageAttributes.ImageName
|
||||||
|
sid.FsSnapshotName = snapData.ImageAttributes.ImageName
|
||||||
|
snapInfo, err := getSnapshotInfo(ctx, volOptions, cr, volumeID(snapID), volumeID(parentSubVolName))
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, ErrSnapNotFound) {
|
||||||
|
err = j.UndoReservation(ctx, volOptions.MetadataPool,
|
||||||
|
volOptions.MetadataPool, snapID, snap.RequestName)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
err = deleteSnapshot(ctx, volOptions, cr, volumeID(snapID), volumeID(parentSubVolName))
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf(util.Log(ctx, "failed to delete snapshot %s: %v"), snapID, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = j.UndoReservation(ctx, volOptions.MetadataPool,
|
||||||
|
volOptions.MetadataPool, snapID, snap.RequestName)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf(util.Log(ctx, "removing reservation failed for snapshot %s: %v"), snapID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
tm, err := parseTime(ctx, snapInfo.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sid.CreationTime = tm
|
||||||
|
// found a snapshot already available, process and return it!
|
||||||
|
sid.SnapshotID, err = util.GenerateVolID(ctx, volOptions.Monitors, cr, volOptions.FscID,
|
||||||
|
"", volOptions.ClusterID, snapUUID, volIDVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
util.DebugLog(ctx, "Found existing snapshot (%s) with subvolume name (%s) for request (%s)",
|
||||||
|
snapData.ImageAttributes.RequestName, parentSubVolName, sid.FsSnapshotName)
|
||||||
|
|
||||||
|
return sid, &snapInfo, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user