mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rbd: fix resync issue
During the Demote volume store the image creation timestamp. During Resync do below operation * Check image creation timestamp stored during Demote operation and current creation timestamp during Resync and check both are equal and its for force resync then issue resync * If the image on both sides is not in unknown state, check last_snapshot_timestamp on the local mirror description, if its present send volumeReady as false or else return error message. If both the images are in up+unknown the send volumeReady as true. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
4016876c9d
commit
e013cfed15
@ -1558,6 +1558,19 @@ func (rv *rbdVolume) setImageOptions(ctx context.Context, options *librbd.ImageO
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetImageCreationTime returns the creation time of the image. if the image
|
||||
// creation time is not set, it queries the image info and returns the creation time.
|
||||
func (ri *rbdImage) GetImageCreationTime() (*timestamppb.Timestamp, error) {
|
||||
if ri.CreatedAt != nil {
|
||||
return ri.CreatedAt, nil
|
||||
}
|
||||
if err := ri.getImageInfo(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ri.CreatedAt, nil
|
||||
}
|
||||
|
||||
// getImageInfo queries rbd about the given image and returns its metadata, and returns
|
||||
// ErrImageNotFound if provided image is not found.
|
||||
func (ri *rbdImage) getImageInfo() error {
|
||||
|
@ -19,31 +19,19 @@ package rbd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
librbd "github.com/ceph/go-ceph/rbd"
|
||||
)
|
||||
|
||||
func (rv *rbdVolume) ResyncVol(localStatus librbd.SiteMirrorImageStatus, force bool) error {
|
||||
if resyncRequired(localStatus) {
|
||||
// If the force option is not set return the error message to retry
|
||||
// with Force option.
|
||||
if !force {
|
||||
return fmt.Errorf("%w: image is in %q state, description (%s). Force resync to recover volume",
|
||||
ErrFailedPrecondition, localStatus.State, localStatus.Description)
|
||||
}
|
||||
err := rv.resyncImage()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: failed to resync image: %w", ErrResyncImageFailed, err)
|
||||
}
|
||||
|
||||
// If we issued a resync, return a non-final error as image needs to be recreated
|
||||
// locally. Caller retries till RBD syncs an initial version of the image to
|
||||
// report its status in the resync request.
|
||||
return fmt.Errorf("%w: awaiting initial resync due to split brain", ErrUnavailable)
|
||||
func (rv *rbdVolume) ResyncVol(localStatus librbd.SiteMirrorImageStatus) error {
|
||||
if err := rv.resyncImage(); err != nil {
|
||||
return fmt.Errorf("%w: failed to resync image: %w", ErrResyncImageFailed, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
// If we issued a resync, return a non-final error as image needs to be recreated
|
||||
// locally. Caller retries till RBD syncs an initial version of the image to
|
||||
// report its status in the resync request.
|
||||
return fmt.Errorf("%w: awaiting initial resync due to split brain", ErrUnavailable)
|
||||
}
|
||||
|
||||
// repairResyncedImageID updates the existing image ID with new one.
|
||||
@ -66,22 +54,6 @@ func (rv *rbdVolume) RepairResyncedImageID(ctx context.Context, ready bool) erro
|
||||
return rv.repairImageID(ctx, j, true)
|
||||
}
|
||||
|
||||
// resyncRequired returns true if local image is in split-brain state and image
|
||||
// needs resync.
|
||||
func resyncRequired(localStatus librbd.SiteMirrorImageStatus) bool {
|
||||
// resync is required if the image is in error state or the description
|
||||
// contains split-brain message.
|
||||
// In some corner cases like `re-player shutdown` the local image will not
|
||||
// be in an error state. It would be also worth considering the `description`
|
||||
// field to make sure about split-brain.
|
||||
if localStatus.State == librbd.MirrorImageStatusStateError ||
|
||||
strings.Contains(localStatus.Description, "split-brain") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (rv *rbdVolume) DisableVolumeReplication(
|
||||
mirroringInfo *librbd.MirrorImageInfo,
|
||||
force bool,
|
||||
|
Reference in New Issue
Block a user