enhance CBT retrievement to indicate the result in error message

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
Lyndon-Li
2026-09-04 13:32:24 +08:00
parent 6cf70c3e3a
commit 6ec84c30f8
4 changed files with 69 additions and 17 deletions
+4 -8
View File
@@ -110,10 +110,10 @@ func snapshotSource(
bitmap := cbt.NewBitmap(blockSize, uint64(source.size), cbtSource.Snapshot, parentBackup.changeID, parentBackup.volumeID)
err := cbt.SetBitmapOrFull(ctx, cbtService, bitmap)
err := cbt.SetBitmapOrFull(ctx, cbtService, bitmap, false)
if err != nil {
parentBackup.parentObject = ""
log.WithError(err).Warnf("Failed to create CBT with source %v, fallback to real full backup", cbtSource)
log.WithError(err).Warnf("Failed to create CBT with source %v", cbtSource)
}
snap, backupSize, err := u.Backup(source, parentBackup.parentObject, bitmap.Iterator(), uploaderCfg)
@@ -218,16 +218,12 @@ func Restore(ctx context.Context, blkUp Uploader, rep udmrepo.BackupRepo, snapsh
if incremental {
if snapshot.Tags == nil {
log.Warnf("No tag from snapshot %s, fallback to full restore", snapshotID)
incremental = false
} else if snapshot.Tags[uploader.CBTChangeIDTag] == "" {
log.Warnf("No ChangeID tag from snapshot %s, fallback to full restore", snapshotID)
incremental = false
} else if snapshot.Tags[uploader.CBTVolumeIDTag] == "" {
log.Warnf("No VolumeID tag from snapshot %s, fallback to full restore", snapshotID)
incremental = false
} else if snapshot.Tags[uploader.CBTVolumeIDTag] != cbtSource.VolumeID {
log.Warnf("VolumeID %s from snapshot %s is not expected as %s, fallback to full restore", snapshot.Tags[uploader.CBTVolumeIDTag], snapshotID, cbtSource.VolumeID)
incremental = false
} else {
volumeSnapshot = cbtSource.Snapshot
changeID = snapshot.Tags[uploader.CBTChangeIDTag]
@@ -237,8 +233,8 @@ func Restore(ctx context.Context, blkUp Uploader, rep udmrepo.BackupRepo, snapsh
bitmap := cbt.NewBitmap(blockSize, uint64(snapshot.TotalSize), volumeSnapshot, changeID, volumeID)
if incremental {
if err = cbt.SetBitmapOrFull(ctx, cbtService, bitmap); err != nil {
log.WithError(err).Warnf("Failed to create CBT with source %v, fallback to full restore", cbtSource)
if err = cbt.SetBitmapOrFull(ctx, cbtService, bitmap, true); err != nil {
log.WithError(err).Warnf("Failed to create CBT with source %v", cbtSource)
}
} else {
bitmap.SetFull()
+13
View File
@@ -36,6 +36,7 @@ type bitmapImpl struct {
snapshot string
changeID string
volumeID string
cbtError error
}
type bitmapIterator struct {
@@ -89,6 +90,14 @@ func (c *bitmapImpl) VolumeID() string {
return c.volumeID
}
func (c *bitmapImpl) SetError(err error) {
c.cbtError = err
}
func (c *bitmapImpl) Error() error {
return c.cbtError
}
func (c *bitmapImpl) Iterator() types.Iterator {
if c.bitmap == nil {
return nil
@@ -115,3 +124,7 @@ func (c *bitmapIterator) Count() uint64 {
func (c *bitmapIterator) BlockSize() uint {
return c.blockSize
}
func (c *bitmapIterator) Error() error {
return c.cbtError
}
+43 -9
View File
@@ -26,36 +26,70 @@ import (
)
// SetBitmapOrFull translates the allocated/changed blocks from CBT service to the given bitmap or set the bitmap to full when error happens
func SetBitmapOrFull(ctx context.Context, service cbtservice.Service, bitmap types.Bitmap) (err error) {
func SetBitmapOrFull(ctx context.Context, service cbtservice.Service, bitmap types.Bitmap, incOnly bool) (ret error) {
setFull := false
defer func() {
if err != nil {
bitmap.SetError(ret)
if setFull {
bitmap.SetFull()
}
}()
if service == nil {
return errors.New("CBT service is absent")
setFull = true
return errors.New("CBT service is absent, fallback to real full")
}
if bitmap.Snapshot() == "" {
return errors.New("invalid snapshot")
setFull = true
return errors.New("invalid snapshot, fallback to real full")
}
if bitmap.ChangeID() == "" {
return errors.Wrapf(service.GetAllocatedBlocks(ctx, bitmap.Snapshot(), func(blocks []cbtservice.Range) error {
if incOnly && bitmap.ChangeID() == "" {
setFull = true
return errors.New("invalid changeID, fallback to real full")
}
var changedErr error
if bitmap.ChangeID() != "" {
err := service.GetChangedBlocks(ctx, bitmap.Snapshot(), bitmap.ChangeID(), func(blocks []cbtservice.Range) error {
for _, b := range blocks {
bitmap.Set(b.Offset, b.Length)
}
return nil
}), "error getting allocated blocks from CBT service")
})
if err == nil {
return nil
}
if incOnly {
setFull = true
return errors.Wrap(err, "error getting changed blocks from CBT service, fallback to real full")
}
changedErr = err
}
return errors.Wrapf(service.GetChangedBlocks(ctx, bitmap.Snapshot(), bitmap.ChangeID(), func(blocks []cbtservice.Range) error {
err := service.GetAllocatedBlocks(ctx, bitmap.Snapshot(), func(blocks []cbtservice.Range) error {
for _, b := range blocks {
bitmap.Set(b.Offset, b.Length)
}
return nil
}), "error getting changed blocks from CBT service")
})
if err != nil {
setFull = true
return errors.Wrap(err, "error getting allocated blocks from CBT service, fallback to real full")
}
if changedErr != nil {
return errors.Wrap(changedErr, "error getting changed blocks from CBT service, fallback to full")
}
return nil
}
+9
View File
@@ -35,6 +35,12 @@ type Bitmap interface {
// Iterator returns the iterator for the CBT Bitmap
Iterator() Iterator
// SetError sets CBT error when preparing this bitmap
SetError(error)
// Error returns the CBT error when preparing this bitmap
Error() error
}
// Iterator defines the methods to iterate the CBT bitmap and query the associated information
@@ -56,4 +62,7 @@ type Iterator interface {
// Next returns the offset of the next set block and whether it comes to the end of the iteration
Next() (uint64, bool)
// Error returns the CBT error when preparing this bitmap
Error() error
}