Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions internal/rbd/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ var (
ErrMissingImageNameInVolID = errors.New("rbd image name information can not be empty in volID")
// ErrDecodeClusterIDFromMonsInVolID is returned when mons hash decoding on migration volID.
ErrDecodeClusterIDFromMonsInVolID = errors.New("failed to get clusterID from monitors hash in volID")
// ErrUnHealthyMirroredImage is returned when mirrored image is not healthy.
ErrUnHealthyMirroredImage = errors.New("mirrored image is not healthy")
)
34 changes: 34 additions & 0 deletions internal/rbd/replicationcontrollerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,11 @@ func (rs *ReplicationServer) PromoteVolume(ctx context.Context,
}
}

err = checkHealthyPrimary(ctx, rbdVol)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

var mode librbd.ImageMirrorMode
mode, err = getMirroringMode(ctx, req.GetParameters())
if err != nil {
Expand Down Expand Up @@ -565,6 +570,35 @@ func (rs *ReplicationServer) PromoteVolume(ctx context.Context,
return &replication.PromoteVolumeResponse{}, nil
}

// checkHealthyPrimary checks if the image is a healhty primary or not.
// healthy primary image will be in up+stopped state, for states other
// than this it returns an error message.
func checkHealthyPrimary(ctx context.Context, rbdVol *rbdVolume) error {
mirrorStatus, err := rbdVol.getImageMirroringStatus()
if err != nil {
return err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return err -> return fmt.Errorf("failed to get mirror status: %w", err) ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getImageMirroringStatus already returning the same error message. doing this will add a duplicate error message.

}
localStatus, err := mirrorStatus.LocalStatus()
if err != nil {
// LocalStatus can fail if the local site status is not found in
// mirroring status. Log complete sites status to debug why getting
// local status failed
log.ErrorLog(ctx, "mirroring status is %+v", mirrorStatus)

return fmt.Errorf("failed to get local status: %w", err)
}

if !localStatus.Up && localStatus.State != librbd.MirrorImageStatusStateStopped {
return fmt.Errorf("%s %w. State is up=%t, state=%q",
rbdVol,
ErrUnHealthyMirroredImage,
localStatus.Up,
localStatus.State)
}

return nil
}

// DemoteVolume extracts the RBD volume information from the
// volumeID, If the image is present, mirroring is enabled and the
// image is in promoted state it will demote the volume as secondary.
Expand Down