Skip to content

Commit

Permalink
feat(restore): implement backup restore finish
Browse files Browse the repository at this point in the history
longhorn/longhorn-6613

Signed-off-by: Chin-Ya Huang <chin-ya.huang@suse.com>
  • Loading branch information
c3y1huang committed Aug 16, 2024
1 parent 42e9ff1 commit 0d60bae
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 10 deletions.
64 changes: 64 additions & 0 deletions pkg/spdk/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -1759,6 +1759,14 @@ func (e *Engine) BackupRestore(spdkClient *spdkclient.Client, backupUrl, engineN
}

Check warning on line 1759 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1756-L1759

Added lines #L1756 - L1759 were not covered by tests
}

defer func() {
go func() {
if err := e.completeBackupRestore(spdkClient); err != nil {
logrus.WithError(err).Warn("Failed to complete backup restore")
}

Check warning on line 1766 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1762-L1766

Added lines #L1762 - L1766 were not covered by tests
}()
}()

resp := &spdkrpc.EngineBackupRestoreResponse{
Errors: map[string]string{},
}
Expand Down Expand Up @@ -1796,6 +1804,62 @@ func (e *Engine) BackupRestore(spdkClient *spdkclient.Client, backupUrl, engineN
return resp, nil
}

func (e *Engine) completeBackupRestore(spdkClient *spdkclient.Client) error {
if err := e.waitForRestoreComplete(); err != nil {
return errors.Wrapf(err, "failed to wait for restore complete")
}

Check warning on line 1810 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1807-L1810

Added lines #L1807 - L1810 were not covered by tests

return e.BackupRestoreFinish(spdkClient)

Check warning on line 1812 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1812

Added line #L1812 was not covered by tests
}

func (e *Engine) waitForRestoreComplete() error {
periodicChecker := time.NewTicker(time.Duration(restorePeriodicRefreshInterval.Seconds()) * time.Second)
defer periodicChecker.Stop()

var err error
for range periodicChecker.C {
isReplicaRestoreCompleted := true
for replicaName, replicaAddress := range e.ReplicaAddressMap {
isReplicaRestoreCompleted, err = e.isReplicaRestoreCompleted(replicaName, replicaAddress)
if err != nil {
return errors.Wrapf(err, "failed to check replica %s restore status", replicaName)
}

Check warning on line 1826 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1815-L1826

Added lines #L1815 - L1826 were not covered by tests

if !isReplicaRestoreCompleted {
break

Check warning on line 1829 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1828-L1829

Added lines #L1828 - L1829 were not covered by tests
}
}

if isReplicaRestoreCompleted {
e.log.Info("Backup restoration completed successfully")
return nil
}

Check warning on line 1836 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1833-L1836

Added lines #L1833 - L1836 were not covered by tests
}

return errors.Errorf("failed to wait for engine %s restore complete", e.Name)

Check warning on line 1839 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1839

Added line #L1839 was not covered by tests
}

func (e *Engine) isReplicaRestoreCompleted(replicaName, replicaAddress string) (bool, error) {
log := e.log.WithFields(logrus.Fields{
"replica": replicaName,
"address": replicaAddress,
})
log.Trace("Checking replica restore status")

replicaServiceCli, err := GetServiceClient(replicaAddress)
if err != nil {
return false, errors.Wrapf(err, "failed to get replica %v service client %s", replicaName, replicaAddress)
}
defer replicaServiceCli.Close()

status, err := replicaServiceCli.ReplicaRestoreStatus(replicaName)
if err != nil {
return false, errors.Wrapf(err, "failed to check replica %s restore status", replicaName)
}

Check warning on line 1858 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1842-L1858

Added lines #L1842 - L1858 were not covered by tests

return !status.IsRestoring, nil

Check warning on line 1860 in pkg/spdk/engine.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/engine.go#L1860

Added line #L1860 was not covered by tests
}

func (e *Engine) BackupRestoreFinish(spdkClient *spdkclient.Client) error {
e.Lock()
defer e.Unlock()
Expand Down
31 changes: 21 additions & 10 deletions pkg/spdk/replica.go
Original file line number Diff line number Diff line change
Expand Up @@ -1952,7 +1952,17 @@ func (r *Replica) BackupRestore(spdkClient *spdkclient.Client, backupUrl, snapsh
}
}()

if newRestore.LastRestored == "" {
isFullRestore := newRestore.LastRestored == ""

defer func() {
go func() {
if err := r.completeBackupRestore(spdkClient, isFullRestore); err != nil {
logrus.WithError(err).Warn("Failed to complete backup restore")
}

Check warning on line 1961 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L1955-L1961

Added lines #L1955 - L1961 were not covered by tests
}()
}()

if isFullRestore {

Check warning on line 1965 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L1965

Added line #L1965 was not covered by tests
r.log.Infof("Starting a new full restore for backup %v", backupUrl)
if err := r.backupRestore(backupUrl, newRestore.LvolName, concurrentLimit); err != nil {
return errors.Wrapf(err, "failed to start full backup restore")
Expand All @@ -1966,12 +1976,6 @@ func (r *Replica) BackupRestore(spdkClient *spdkclient.Client, backupUrl, snapsh
r.log.Infof("Successfully initiated incremental restore for %v to %v", backupUrl, newRestore.LvolName)

Check warning on line 1976 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L1976

Added line #L1976 was not covered by tests
}

go func() {
if err := r.completeBackupRestore(spdkClient); err != nil {
logrus.WithError(err).Warn("Failed to complete backup restore")
}
}()

return nil

}
Expand Down Expand Up @@ -2024,7 +2028,7 @@ func (r *Replica) canDoIncrementalRestore(restore *Restore, backupURL, requested
return true
}

func (r *Replica) completeBackupRestore(spdkClient *spdkclient.Client) (err error) {
func (r *Replica) completeBackupRestore(spdkClient *spdkclient.Client, isFullRestore bool) (err error) {

Check warning on line 2031 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L2031

Added line #L2031 was not covered by tests
defer func() {
if extraErr := r.finishRestore(err); extraErr != nil {
r.log.WithError(extraErr).Error("Failed to finish backup restore")
Expand All @@ -2039,9 +2043,11 @@ func (r *Replica) completeBackupRestore(spdkClient *spdkclient.Client) (err erro
restore := r.restore.DeepCopy()
r.RUnlock()

// TODO: Support postIncrementalRestoreOperations
if isFullRestore {
return r.postFullRestoreOperations(spdkClient, restore)
}

Check warning on line 2048 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L2046-L2048

Added lines #L2046 - L2048 were not covered by tests

return r.postFullRestoreOperations(spdkClient, restore)
return r.postIncrementalRestoreOperations(restore)

Check warning on line 2050 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L2050

Added line #L2050 was not covered by tests
}

func (r *Replica) waitForRestoreComplete() error {
Expand Down Expand Up @@ -2072,6 +2078,11 @@ func (r *Replica) waitForRestoreComplete() error {
return nil
}

func (r *Replica) postIncrementalRestoreOperations(restore *Restore) error {
r.log.Infof("Done running incremental restore %v to lvol %v", restore.BackupURL, restore.LvolName)
return nil

Check warning on line 2083 in pkg/spdk/replica.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/replica.go#L2081-L2083

Added lines #L2081 - L2083 were not covered by tests
}

func (r *Replica) postFullRestoreOperations(spdkClient *spdkclient.Client, restore *Restore) error {
if r.restore.State == btypes.ProgressStateCanceled {
r.log.Info("Doing nothing for canceled backup restoration")
Expand Down

0 comments on commit 0d60bae

Please sign in to comment.