mirror of
https://github.com/restic/restic.git
synced 2024-12-26 01:37:12 +00:00
debug: fix crash in debug examine --reupload-blobs
This commit is contained in:
parent
24a2e5cab9
commit
11a4bb051e
1 changed files with 73 additions and 66 deletions
|
@ -325,87 +325,94 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
|
||||||
Name: packID.String(),
|
Name: packID.String(),
|
||||||
Type: restic.PackFile,
|
Type: restic.PackFile,
|
||||||
}
|
}
|
||||||
for _, blob := range list {
|
|
||||||
Printf(" loading blob %v at %v (length %v)\n", blob.ID, blob.Offset, blob.Length)
|
wg, ctx := errgroup.WithContext(ctx)
|
||||||
buf := make([]byte, blob.Length)
|
|
||||||
err := be.Load(ctx, h, int(blob.Length), int64(blob.Offset), func(rd io.Reader) error {
|
if reuploadBlobs {
|
||||||
n, err := io.ReadFull(rd, buf)
|
repo.StartPackUploader(ctx, wg)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Go(func() error {
|
||||||
|
for _, blob := range list {
|
||||||
|
Printf(" loading blob %v at %v (length %v)\n", blob.ID, blob.Offset, blob.Length)
|
||||||
|
buf := make([]byte, blob.Length)
|
||||||
|
err := be.Load(ctx, h, int(blob.Length), int64(blob.Offset), func(rd io.Reader) error {
|
||||||
|
n, err := io.ReadFull(rd, buf)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("read error after %d bytes: %v", n, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("read error after %d bytes: %v", n, err)
|
Warnf("error read: %v\n", err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
Warnf("error read: %v\n", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := repo.Key()
|
key := repo.Key()
|
||||||
|
|
||||||
nonce, plaintext := buf[:key.NonceSize()], buf[key.NonceSize():]
|
nonce, plaintext := buf[:key.NonceSize()], buf[key.NonceSize():]
|
||||||
plaintext, err = key.Open(plaintext[:0], nonce, plaintext, nil)
|
plaintext, err = key.Open(plaintext[:0], nonce, plaintext, nil)
|
||||||
outputPrefix := ""
|
outputPrefix := ""
|
||||||
filePrefix := ""
|
filePrefix := ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error decrypting blob: %v\n", err)
|
Warnf("error decrypting blob: %v\n", err)
|
||||||
if tryRepair || repairByte {
|
if tryRepair || repairByte {
|
||||||
plaintext = tryRepairWithBitflip(ctx, key, buf, repairByte)
|
plaintext = tryRepairWithBitflip(ctx, key, buf, repairByte)
|
||||||
|
}
|
||||||
|
if plaintext != nil {
|
||||||
|
outputPrefix = "repaired "
|
||||||
|
filePrefix = "repaired-"
|
||||||
|
} else {
|
||||||
|
plaintext = decryptUnsigned(ctx, key, buf)
|
||||||
|
err = storePlainBlob(blob.ID, "damaged-", plaintext)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if plaintext != nil {
|
|
||||||
outputPrefix = "repaired "
|
if blob.IsCompressed() {
|
||||||
filePrefix = "repaired-"
|
decompressed, err := dec.DecodeAll(plaintext, nil)
|
||||||
|
if err != nil {
|
||||||
|
Printf(" failed to decompress blob %v\n", blob.ID)
|
||||||
|
}
|
||||||
|
if decompressed != nil {
|
||||||
|
plaintext = decompressed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id := restic.Hash(plaintext)
|
||||||
|
var prefix string
|
||||||
|
if !id.Equal(blob.ID) {
|
||||||
|
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID does not match, wanted %v\n", outputPrefix, len(plaintext), id, blob.ID)
|
||||||
|
prefix = "wrong-hash-"
|
||||||
} else {
|
} else {
|
||||||
plaintext = decryptUnsigned(ctx, key, buf)
|
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID matches\n", outputPrefix, len(plaintext), id)
|
||||||
err = storePlainBlob(blob.ID, "damaged-", plaintext)
|
prefix = "correct-"
|
||||||
|
}
|
||||||
|
if extractPack {
|
||||||
|
err = storePlainBlob(id, filePrefix+prefix, plaintext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
}
|
||||||
|
if reuploadBlobs {
|
||||||
|
_, _, _, err := repo.SaveBlob(ctx, blob.Type, plaintext, id, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
Printf(" uploaded %v %v\n", blob.Type, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if blob.IsCompressed() {
|
|
||||||
decompressed, err := dec.DecodeAll(plaintext, nil)
|
|
||||||
if err != nil {
|
|
||||||
Printf(" failed to decompress blob %v\n", blob.ID)
|
|
||||||
}
|
|
||||||
if decompressed != nil {
|
|
||||||
plaintext = decompressed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id := restic.Hash(plaintext)
|
|
||||||
var prefix string
|
|
||||||
if !id.Equal(blob.ID) {
|
|
||||||
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID does not match, wanted %v\n", outputPrefix, len(plaintext), id, blob.ID)
|
|
||||||
prefix = "wrong-hash-"
|
|
||||||
} else {
|
|
||||||
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID matches\n", outputPrefix, len(plaintext), id)
|
|
||||||
prefix = "correct-"
|
|
||||||
}
|
|
||||||
if extractPack {
|
|
||||||
err = storePlainBlob(id, filePrefix+prefix, plaintext)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if reuploadBlobs {
|
if reuploadBlobs {
|
||||||
_, _, _, err := repo.SaveBlob(ctx, blob.Type, plaintext, id, true)
|
return repo.Flush(ctx)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
Printf(" uploaded %v %v\n", blob.Type, id)
|
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
if reuploadBlobs {
|
return wg.Wait()
|
||||||
err := repo.Flush(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func storePlainBlob(id restic.ID, prefix string, plain []byte) error {
|
func storePlainBlob(id restic.ID, prefix string, plain []byte) error {
|
||||||
|
|
Loading…
Reference in a new issue