cephfs: log clone progress

log cephfs clone progress report during cephfs clone
operation

Signed-off-by: Nikhil-Ladha <nikhilladha1999@gmail.com>
This commit is contained in:
Nikhil-Ladha 2024-10-28 11:39:13 +05:30
parent cea8bf8110
commit c5da289e54
4 changed files with 39 additions and 18 deletions

View File

@ -28,16 +28,17 @@ import (
// cephFSCloneState describes the status of the clone. // cephFSCloneState describes the status of the clone.
type cephFSCloneState struct { type cephFSCloneState struct {
state admin.CloneState state admin.CloneState
errno string progressReport admin.CloneProgressReport
errorMsg string errno string
errorMsg string
} }
// CephFSCloneError indicates that fetching the clone state returned an error. // CephFSCloneError indicates that fetching the clone state returned an error.
var CephFSCloneError = cephFSCloneState{} var CephFSCloneError = &cephFSCloneState{}
// ToError checks the state of the clone if it's not cephFSCloneComplete. // ToError checks the state of the clone if it's not cephFSCloneComplete.
func (cs cephFSCloneState) ToError() error { func (cs *cephFSCloneState) ToError() error {
switch cs.state { switch cs.state {
case admin.CloneComplete: case admin.CloneComplete:
return nil return nil
@ -54,6 +55,14 @@ func (cs cephFSCloneState) ToError() error {
return nil return nil
} }
func (cs *cephFSCloneState) GetProgressReport() admin.CloneProgressReport {
return admin.CloneProgressReport{
PercentageCloned: cs.progressReport.PercentageCloned,
AmountCloned: cs.progressReport.AmountCloned,
FilesCloned: cs.progressReport.FilesCloned,
}
}
// CreateCloneFromSubvolume creates a clone from a subvolume. // CreateCloneFromSubvolume creates a clone from a subvolume.
func (s *subVolumeClient) CreateCloneFromSubvolume( func (s *subVolumeClient) CreateCloneFromSubvolume(
ctx context.Context, ctx context.Context,
@ -87,7 +96,7 @@ func (s *subVolumeClient) CreateCloneFromSubvolume(
return err return err
} }
var cloneState cephFSCloneState var cloneState *cephFSCloneState
cloneState, err = s.GetCloneState(ctx) cloneState, err = s.GetCloneState(ctx)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to get clone state: %v", err) log.ErrorLog(ctx, "failed to get clone state: %v", err)
@ -157,7 +166,7 @@ func (s *subVolumeClient) CreateCloneFromSnapshot(
} }
} }
}() }()
var cloneState cephFSCloneState var cloneState *cephFSCloneState
// avoid err variable shadowing // avoid err variable shadowing
cloneState, err = s.GetCloneState(ctx) cloneState, err = s.GetCloneState(ctx)
if err != nil { if err != nil {
@ -182,7 +191,7 @@ func (s *subVolumeClient) CreateCloneFromSnapshot(
} }
// GetCloneState returns the clone state of the subvolume. // GetCloneState returns the clone state of the subvolume.
func (s *subVolumeClient) GetCloneState(ctx context.Context) (cephFSCloneState, error) { func (s *subVolumeClient) GetCloneState(ctx context.Context) (*cephFSCloneState, error) {
fsa, err := s.conn.GetFSAdmin() fsa, err := s.conn.GetFSAdmin()
if err != nil { if err != nil {
log.ErrorLog( log.ErrorLog(
@ -209,10 +218,11 @@ func (s *subVolumeClient) GetCloneState(ctx context.Context) (cephFSCloneState,
errStr = failure.ErrStr errStr = failure.ErrStr
} }
state := cephFSCloneState{ state := &cephFSCloneState{
state: cs.State, state: cs.State,
errno: errno, progressReport: cs.ProgressReport,
errorMsg: errStr, errno: errno,
errorMsg: errStr,
} }
return state, nil return state, nil

View File

@ -28,11 +28,11 @@ import (
func TestCloneStateToError(t *testing.T) { func TestCloneStateToError(t *testing.T) {
t.Parallel() t.Parallel()
errorState := make(map[cephFSCloneState]error) errorState := make(map[cephFSCloneState]error)
errorState[cephFSCloneState{fsa.CloneComplete, "", ""}] = nil errorState[cephFSCloneState{fsa.CloneComplete, fsa.CloneProgressReport{}, "", ""}] = nil
errorState[CephFSCloneError] = cerrors.ErrInvalidClone errorState[*CephFSCloneError] = cerrors.ErrInvalidClone
errorState[cephFSCloneState{fsa.CloneInProgress, "", ""}] = cerrors.ErrCloneInProgress errorState[cephFSCloneState{fsa.CloneInProgress, fsa.CloneProgressReport{}, "", ""}] = cerrors.ErrCloneInProgress
errorState[cephFSCloneState{fsa.ClonePending, "", ""}] = cerrors.ErrClonePending errorState[cephFSCloneState{fsa.ClonePending, fsa.CloneProgressReport{}, "", ""}] = cerrors.ErrClonePending
errorState[cephFSCloneState{fsa.CloneFailed, "", ""}] = cerrors.ErrCloneFailed errorState[cephFSCloneState{fsa.CloneFailed, fsa.CloneProgressReport{}, "", ""}] = cerrors.ErrCloneFailed
for state, err := range errorState { for state, err := range errorState {
require.ErrorIs(t, state.ToError(), err) require.ErrorIs(t, state.ToError(), err)

View File

@ -75,7 +75,7 @@ type SubVolumeClient interface {
// CreateCloneFromSubVolume creates a clone from the subvolume. // CreateCloneFromSubVolume creates a clone from the subvolume.
CreateCloneFromSubvolume(ctx context.Context, parentvolOpt *SubVolume) error CreateCloneFromSubvolume(ctx context.Context, parentvolOpt *SubVolume) error
// GetCloneState returns the clone state of the subvolume. // GetCloneState returns the clone state of the subvolume.
GetCloneState(ctx context.Context) (cephFSCloneState, error) GetCloneState(ctx context.Context) (*cephFSCloneState, error)
// CreateCloneFromSnapshot creates a clone from the subvolume snapshot. // CreateCloneFromSnapshot creates a clone from the subvolume snapshot.
CreateCloneFromSnapshot(ctx context.Context, snap Snapshot) error CreateCloneFromSnapshot(ctx context.Context, snap Snapshot) error
// CleanupSnapshotFromSubvolume removes the snapshot from the subvolume. // CleanupSnapshotFromSubvolume removes the snapshot from the subvolume.

View File

@ -128,6 +128,17 @@ func CheckVolExists(ctx context.Context,
} }
err = cloneState.ToError() err = cloneState.ToError()
if errors.Is(err, cerrors.ErrCloneInProgress) { if errors.Is(err, cerrors.ErrCloneInProgress) {
progressReport := cloneState.GetProgressReport()
// append progress report only if the progress report parameters are present.
if progressReport.PercentageCloned != "" {
err = fmt.Errorf("%w. progress report: percentage cloned=%s, amount cloned=%s, files cloned=%s",
err,
progressReport.PercentageCloned,
progressReport.AmountCloned,
progressReport.FilesCloned)
log.ErrorLog(ctx, err.Error())
}
return nil, err return nil, err
} }
if errors.Is(err, cerrors.ErrClonePending) { if errors.Is(err, cerrors.ErrClonePending) {