repository: don't hang when copying using a single connection
This commit is contained in:
parent
1b233c4e2e
commit
b03277ead5
3 changed files with 24 additions and 1 deletions
7
changelog/unreleased/issue-3897
Normal file
7
changelog/unreleased/issue-3897
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Bugfix: Fix stuck `copy` command when setting backend connections to 1
|
||||||
|
|
||||||
|
When calling the copy command using `copy -o <backend>.connections=1` this
|
||||||
|
caused the command to be stuck permanently. This has been fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/3897
|
||||||
|
https://github.com/restic/restic/pull/3898
|
|
@ -114,6 +114,10 @@ func repack(ctx context.Context, repo restic.Repository, dstRepo restic.Reposito
|
||||||
// as packs are streamed the concurrency is limited by IO
|
// as packs are streamed the concurrency is limited by IO
|
||||||
// reduce by one to ensure that uploading is always possible
|
// reduce by one to ensure that uploading is always possible
|
||||||
repackWorkerCount := int(repo.Connections() - 1)
|
repackWorkerCount := int(repo.Connections() - 1)
|
||||||
|
if repo != dstRepo {
|
||||||
|
// no need to share the upload and download connections for different repositories
|
||||||
|
repackWorkerCount = int(repo.Connections())
|
||||||
|
}
|
||||||
for i := 0; i < repackWorkerCount; i++ {
|
for i := 0; i < repackWorkerCount; i++ {
|
||||||
wg.Go(worker)
|
wg.Go(worker)
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,12 +292,24 @@ func TestRepackCopy(t *testing.T) {
|
||||||
repository.TestAllVersions(t, testRepackCopy)
|
repository.TestAllVersions(t, testRepackCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type oneConnectionRepo struct {
|
||||||
|
restic.Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r oneConnectionRepo) Connections() uint {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
func testRepackCopy(t *testing.T, version uint) {
|
func testRepackCopy(t *testing.T, version uint) {
|
||||||
repo, cleanup := repository.TestRepositoryWithVersion(t, version)
|
repo, cleanup := repository.TestRepositoryWithVersion(t, version)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
dstRepo, dstCleanup := repository.TestRepositoryWithVersion(t, version)
|
dstRepo, dstCleanup := repository.TestRepositoryWithVersion(t, version)
|
||||||
defer dstCleanup()
|
defer dstCleanup()
|
||||||
|
|
||||||
|
// test with minimal possible connection count
|
||||||
|
repoWrapped := &oneConnectionRepo{repo}
|
||||||
|
dstRepoWrapped := &oneConnectionRepo{dstRepo}
|
||||||
|
|
||||||
seed := time.Now().UnixNano()
|
seed := time.Now().UnixNano()
|
||||||
rand.Seed(seed)
|
rand.Seed(seed)
|
||||||
t.Logf("rand seed is %v", seed)
|
t.Logf("rand seed is %v", seed)
|
||||||
|
@ -308,7 +320,7 @@ func testRepackCopy(t *testing.T, version uint) {
|
||||||
_, keepBlobs := selectBlobs(t, repo, 0.2)
|
_, keepBlobs := selectBlobs(t, repo, 0.2)
|
||||||
copyPacks := findPacksForBlobs(t, repo, keepBlobs)
|
copyPacks := findPacksForBlobs(t, repo, keepBlobs)
|
||||||
|
|
||||||
_, err := repository.Repack(context.TODO(), repo, dstRepo, copyPacks, keepBlobs, nil)
|
_, err := repository.Repack(context.TODO(), repoWrapped, dstRepoWrapped, copyPacks, keepBlobs, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue