From 36b061d426b4c683df11f7deedeb27f8bc8fbad5 Mon Sep 17 00:00:00 2001 From: Yati Padia Date: Wed, 14 Sep 2022 16:39:35 +0530 Subject: [PATCH] rbd: get description from remote status This commit gets the description from remote status instead of local status. Local status doesn't have ',' due to which we get array index out of range panic. Fixes: #3388 Signed-off-by: Yati Padia Co-authored-by: shyam Ranganathan --- internal/rbd/replicationcontrollerserver.go | 29 +++++++++++++++++-- .../rbd/replicationcontrollerserver_test.go | 6 ++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/internal/rbd/replicationcontrollerserver.go b/internal/rbd/replicationcontrollerserver.go index e7d359a55..7b7082c4e 100644 --- a/internal/rbd/replicationcontrollerserver.go +++ b/internal/rbd/replicationcontrollerserver.go @@ -898,14 +898,14 @@ func (rs *ReplicationServer) GetVolumeReplicationInfo(ctx context.Context, return nil, status.Error(codes.Internal, err.Error()) } - localStatus, err := mirrorStatus.LocalStatus() + remoteStatus, err := RemoteStatus(mirrorStatus) if err != nil { log.ErrorLog(ctx, err.Error()) - return nil, fmt.Errorf("failed to get local status: %w", err) + return nil, fmt.Errorf("failed to get remote status: %w", err) } - description := localStatus.Description + description := remoteStatus.Description lastSyncTime, err := getLastSyncTime(description) if err != nil { return nil, fmt.Errorf("failed to get last sync time: %w", err) @@ -918,6 +918,26 @@ func (rs *ReplicationServer) GetVolumeReplicationInfo(ctx context.Context, return resp, nil } +// RemoteStatus returns one SiteMirrorImageStatus item from the SiteStatuses +// slice that corresponds to the remote site's status. If the remote status +// is not found than the error ErrNotExist will be returned. +func RemoteStatus(gmis *librbd.GlobalMirrorImageStatus) (librbd.SiteMirrorImageStatus, error) { + var ( + ss librbd.SiteMirrorImageStatus + err error = librbd.ErrNotExist + ) + for i := range gmis.SiteStatuses { + if gmis.SiteStatuses[i].MirrorUUID != "" { + ss = gmis.SiteStatuses[i] + err = nil + + break + } + } + + return ss, err +} + // This function gets the local snapshot time from the description // of localStatus and converts it into required type. func getLastSyncTime(description string) (*timestamppb.Timestamp, error) { @@ -930,6 +950,9 @@ func getLastSyncTime(description string) (*timestamppb.Timestamp, error) { return nil, nil } splittedString := strings.SplitN(description, ",", 2) + if len(splittedString) == 1 { + return nil, nil + } type localStatus struct { LocalSnapshotTime int64 `json:"local_snapshot_timestamp"` } diff --git a/internal/rbd/replicationcontrollerserver_test.go b/internal/rbd/replicationcontrollerserver_test.go index d1e3a0041..7ea849cd1 100644 --- a/internal/rbd/replicationcontrollerserver_test.go +++ b/internal/rbd/replicationcontrollerserver_test.go @@ -469,6 +469,12 @@ func TestValidateLastSyncTime(t *testing.T) { nil, "failed to unmarshal description", }, + { + "description with no JSON", + `replaying`, + nil, + "", + }, } for _, tt := range tests { tt := tt