From 651d82e5116a35872ffd11e456a6dc42b347fed0 Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Tue, 20 Jun 2017 14:38:09 -0400 Subject: [PATCH] Check directory existence again when failing to create it to avoid erroring out on race condition --- integration_tests/test_functions.sh | 1 - integration_tests/threaded_test.sh | 17 +++++++++++++++++ src/duplicacy_filestorage.go | 6 +++++- src/duplicacy_sftpstorage.go | 6 +++++- 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100755 integration_tests/threaded_test.sh diff --git a/integration_tests/test_functions.sh b/integration_tests/test_functions.sh index 2043356..f517742 100644 --- a/integration_tests/test_functions.sh +++ b/integration_tests/test_functions.sh @@ -93,7 +93,6 @@ function add_file() FILE_NAME=$1 pushd ${TEST_REPO} dd if=/dev/urandom of=${FILE_NAME} bs=1000 count=20000 - echo ${FILE_NAME} > "${FILE_NAME}" popd } diff --git a/integration_tests/threaded_test.sh b/integration_tests/threaded_test.sh new file mode 100755 index 0000000..6b0bebe --- /dev/null +++ b/integration_tests/threaded_test.sh @@ -0,0 +1,17 @@ +#!/bin/bash + + +. ./test_functions.sh + +fixture + +pushd ${TEST_REPO} +${DUPLICACY} init integration-tests $TEST_STORAGE -c 1k + +add_file file3 +add_file file4 + + +${DUPLICACY} backup -threads 16 +${DUPLICACY} check --files -stats +popd diff --git a/src/duplicacy_filestorage.go b/src/duplicacy_filestorage.go index 74c289a..db95935 100644 --- a/src/duplicacy_filestorage.go +++ b/src/duplicacy_filestorage.go @@ -158,7 +158,11 @@ func (storage *FileStorage) FindChunk(threadIndex int, chunkID string, isFossil err = os.Mkdir(subDir, 0744) if err != nil { - return "", false, 0, err + // The directory may have been created by other threads so check it again. + stat, _ := os.Stat(subDir) + if stat == nil || !stat.IsDir() { + return "", false, 0, err + } } dir = subDir diff --git a/src/duplicacy_sftpstorage.go b/src/duplicacy_sftpstorage.go index d505980..9cfead7 100644 --- a/src/duplicacy_sftpstorage.go +++ b/src/duplicacy_sftpstorage.go @@ -215,7 +215,11 @@ func (storage *SFTPStorage) FindChunk(threadIndex int, chunkID string, isFossil err = storage.client.Mkdir(subDir) if err != nil { - return "", false, 0, fmt.Errorf("Failed to create the directory %s: %v", subDir, err) + // The directory may have been created by other threads so check it again. + stat, _ := storage.client.Stat(subDir) + if stat == nil || !stat.IsDir() { + return "", false, 0, fmt.Errorf("Failed to create the directory %s: %v", subDir, err) + } } dir = subDir