Provide relevant error message if datadir is not writable.
This commit is contained in:
parent
b225010a80
commit
8674e74b47
4 changed files with 33 additions and 0 deletions
|
@ -1165,6 +1165,9 @@ static bool LockDataDirectory(bool probeOnly)
|
||||||
{
|
{
|
||||||
// Make sure only a single Bitcoin process is using the data directory.
|
// Make sure only a single Bitcoin process is using the data directory.
|
||||||
fs::path datadir = GetDataDir();
|
fs::path datadir = GetDataDir();
|
||||||
|
if (!DirIsWritable(datadir)) {
|
||||||
|
return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string()));
|
||||||
|
}
|
||||||
if (!LockDirectory(datadir, ".lock", probeOnly)) {
|
if (!LockDirectory(datadir, ".lock", probeOnly)) {
|
||||||
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME)));
|
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -800,4 +800,20 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory)
|
||||||
fs::remove_all(dirname);
|
fs::remove_all(dirname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_DirIsWritable)
|
||||||
|
{
|
||||||
|
// Should be able to write to the system tmp dir.
|
||||||
|
fs::path tmpdirname = fs::temp_directory_path();
|
||||||
|
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
|
||||||
|
|
||||||
|
// Should not be able to write to a non-existent dir.
|
||||||
|
tmpdirname = fs::temp_directory_path() / fs::unique_path();
|
||||||
|
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), false);
|
||||||
|
|
||||||
|
fs::create_directory(tmpdirname);
|
||||||
|
// Should be able to write to it now.
|
||||||
|
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
|
||||||
|
fs::remove(tmpdirname);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
13
src/util.cpp
13
src/util.cpp
|
@ -418,6 +418,19 @@ void ReleaseDirectoryLocks()
|
||||||
dir_locks.clear();
|
dir_locks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DirIsWritable(const fs::path& directory)
|
||||||
|
{
|
||||||
|
fs::path tmpFile = directory / fs::unique_path();
|
||||||
|
|
||||||
|
FILE* file = fsbridge::fopen(tmpFile, "a");
|
||||||
|
if (!file) return false;
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
remove(tmpFile);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Interpret string as boolean, for argument parsing */
|
/** Interpret string as boolean, for argument parsing */
|
||||||
static bool InterpretBool(const std::string& strValue)
|
static bool InterpretBool(const std::string& strValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,6 +174,7 @@ int RaiseFileDescriptorLimit(int nMinFD);
|
||||||
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
|
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
|
||||||
bool RenameOver(fs::path src, fs::path dest);
|
bool RenameOver(fs::path src, fs::path dest);
|
||||||
bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
|
bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false);
|
||||||
|
bool DirIsWritable(const fs::path& directory);
|
||||||
|
|
||||||
/** Release all directory locks. This is used for unit testing only, at runtime
|
/** Release all directory locks. This is used for unit testing only, at runtime
|
||||||
* the global destructor will take care of the locks.
|
* the global destructor will take care of the locks.
|
||||||
|
|
Loading…
Reference in a new issue