Skip to content

Conversation

ken2812221
Copy link
Contributor

@ken2812221 ken2812221 commented Aug 3, 2018

boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows.

This PR is seperated from #13426 for easier review.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 3, 2018

Note to reviewers: This pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@Empact
Copy link
Contributor

Empact commented Aug 3, 2018

Seems like a good opportunity to drop boost::interprocess::file_lock altogether, no?

src/fs.h Outdated
class FileLock
{
public:
FileLock(const fs::path& file);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could delete default and copy constructor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

src/fs.cpp Outdated
lock.l_start = 0;
lock.l_len = 0;
return -1 != fcntl(fd, F_SETLK, &lock);
}
Copy link
Contributor

@Empact Empact Aug 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relevant boost implementation, for reference:

inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
{
   struct ::flock lock;
   lock.l_type    = F_WRLCK;
   lock.l_whence  = SEEK_SET;
   lock.l_start   = 0;
   lock.l_len     = 0;
   int ret = ::fcntl(hnd, F_SETLK, &lock);
   if(ret == -1){
      return (errno == EAGAIN || errno == EACCES) ?
               acquired = false, true : false;
   }
   return (acquired = true);
}

https://www.boost.org/doc/libs/1_67_0/boost/interprocess/detail/os_file_functions.hpp

Should we distinguish between hard (e.g. EINVAL) and soft (EAGAIN, EACCES) failures, as they do? We could throw in the former case?
https://www.gnu.org/software/libc/manual/html_node/File-Locks.html

src/fs.cpp Outdated
}
_OVERLAPPED overlapped = {0};
return LockFileEx((HANDLE)hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlapped);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relevant boost implementation, for reference:

inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
{
   const unsigned long len = ((unsigned long)-1);
   winapi::interprocess_overlapped overlapped;
   std::memset(&overlapped, 0, sizeof(overlapped));
   if(!winapi::lock_file_ex
      (hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately,
       0, len, len, &overlapped)){
      return winapi::get_last_error() == winapi::error_lock_violation ?
               acquired = false, true : false;

   }
   return (acquired = true);
}

https://www.boost.org/doc/libs/1_67_0/boost/interprocess/detail/os_file_functions.hpp

Similar question re. GetLastError?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also is the (HANDLE) cast necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@ken2812221
Copy link
Contributor Author

ken2812221 commented Aug 3, 2018

@Empact In my opinion, we deal catching exception and try_lock fail much the same when we use boost, so no need to handle the extra exception for now.

@ken2812221 ken2812221 changed the title add unicode compatible file_lock for Windows utils: drop boost::interprocess::file_lock Aug 3, 2018
@Empact
Copy link
Contributor

Empact commented Aug 3, 2018

@ken2812221 FYI boost does throw on the failures noted above:

inline bool file_lock::try_lock()
{
   bool result;
   if(!ipcdetail::try_acquire_file_lock(m_file_hnd, result)){
      error_info err(system_error_code());
      throw interprocess_exception(err);
   }
   return result;
}

namespace boost {
namespace interprocess {
inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
{
   #if (defined BOOST_INTERPROCESS_WINDOWS)
   return winapi::get_last_error();
   #else
   return errno; // GCC 3.1 won't accept ::errno
   #endif
}

https://www.boost.org/doc/libs/1_67_0/boost/interprocess/sync/file_lock.hpp
https://www.boost.org/doc/libs/1_46_1/boost/interprocess/errors.hpp

@ken2812221
Copy link
Contributor Author

@Empact I simply return false in my code at those conditions.

@Empact
Copy link
Contributor

Empact commented Aug 3, 2018

Yeah so the net effect is the loss of this message:
return error("Error while attempting to lock directory %s: %s", directory.string(), e.what());

Certainly not a big deal but breadcrumbs can mean the difference between an easy fix and a maddening mystery.

@ken2812221
Copy link
Contributor Author

@Empact Updated to get error messages.

src/fs.cpp Outdated
return false;
}
_OVERLAPPED overlapped = {0};
return LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlapped);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CreateFileW with 0 sharing effectively opens the file as exclusive (locking it). It feels the TryLock() here is redundant because we don't require locking of specific bytes.

Perhaps the TryLock() should be the one doing the CreateFileW.
Apologies if I've misunderstood something here :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

src/fs.cpp Outdated
@@ -12,4 +21,82 @@ FILE *freopen(const fs::path& p, const char *mode, FILE *stream)
return ::freopen(p.string().c_str(), mode, stream);
}

#ifndef WIN32

std::string GetErrorReason() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: static

src/fs.cpp Outdated
}
#else

std::string GetErrorReason() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: static

return error("Error while attempting to lock directory %s: %s", directory.string(), e.what());
auto lock = MakeUnique<fsbridge::FileLock>(pathLockFile);
if (!lock->TryLock()) {
return error("Error while attempting to lock directory %s: %s", directory.string(), lock->GetReason());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference, how these are logged by the callers:

bitcoin/src/init.cpp

Lines 1183 to 1185 in 2b67354

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)));
}

bitcoin/src/wallet/db.cpp

Lines 136 to 139 in 2b67354

if (!LockDirectory(pathIn, ".walletlock")) {
LogPrintf("Cannot obtain a lock on wallet directory %s. Another instance of bitcoin may be using it.\n", strPath);
return false;
}

boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows.
This commit add a new class to handle those specific file for Windows.
@laanwj laanwj merged commit 1661a47 into bitcoin:master Aug 29, 2018
laanwj added a commit that referenced this pull request Aug 29, 2018
1661a47 add unicode compatible file_lock for Windows (Chun Kuan Lee)

Pull request description:

  boost::interprocess::file_lock cannot open the files that contain characters which cannot be parsed by the user's code page on Windows.

  This PR is seperated from #13426 for easier review.

Tree-SHA512: e240479cda65958bf6e1319840b83928b2b50da81d99f4f002fb3b62621370bcd4bcfacd2b8c0678c443a650d6ba53d9d12618b591e5bfd67ac14388a18fd822
@ken2812221 ken2812221 deleted the custom-filelock branch August 29, 2018 12:33
sipa added a commit that referenced this pull request Oct 20, 2018
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by #13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
Warrows added a commit to Warrows/PIVX that referenced this pull request Oct 14, 2019
Backports bitcoin#13862

boost::interprocess::file_lock cannot open the files that contain
characters which cannot be parsed by the user's code page on Windows.
Warrows added a commit to Warrows/PIVX that referenced this pull request Nov 23, 2019
Backports bitcoin#13862

boost::interprocess::file_lock cannot open the files that contain
characters which cannot be parsed by the user's code page on Windows.
fanquake added a commit to fanquake/bitcoin that referenced this pull request May 11, 2020
Since the merge of bitcoin#13862, and the inclusion of the <codecvt> header,
it hasn't been possible to compile bitcoind (targeting Windows) using
GCC 4.8.x. The libstdc++ packaged with GCC didn't include the <codecvt>
header until GCC 5.1. See the GCC 5 release notes:
https://gcc.gnu.org/gcc-5/changes.html.

Given that we'll be requiring a c++17 capable compiler at some point in
the near future, and, assuming no-one else has noticed this, I think we
can just adjust the docs to indicate that it's actually GCC 5.1+ that is
required (I don't think we need to break it down per target).
kwvg pushed a commit to kwvg/dash that referenced this pull request May 19, 2021
kwvg added a commit to kwvg/dash that referenced this pull request May 19, 2021
kwvg added a commit to kwvg/dash that referenced this pull request May 20, 2021
kwvg added a commit to kwvg/dash that referenced this pull request May 20, 2021
kwvg added a commit to kwvg/dash that referenced this pull request May 20, 2021
kwvg added a commit to kwvg/dash that referenced this pull request May 20, 2021
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 27, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 28, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 29, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
random-zebra added a commit to PIVX-Project/PIVX that referenced this pull request Aug 5, 2021
63e0be6 [Remove] By-pass logprint-scanner restriction. (furszy)
280ced3 utils: Fix broken Windows filelock (Chun Kuan Lee)
be89860 utils: Convert Windows args to utf-8 string (Chun Kuan Lee)
e8cfa6e Call unicode API on Windows (Chun Kuan Lee)
1a02a8a tests: Add test case for std::ios_base::ate (Chun Kuan Lee)
2e57cd4 Move boost/std fstream to fsbridge (furszy)
9d8bcd4 utils: Add fsbridge fstream function wrapper (Chun Kuan Lee)
d59d48d utils: Convert fs error messages from multibyte to utf-8 (ken2812221)
9ef58cc Logging: use "fmterr" variable name for errors instead of general "e" that can be used by any other function. (furszy)
dd94241 utils: Use _wfopen and _wreopen on Windows (Chun Kuan Lee)
3993641 add unicode compatible file_lock for Windows (Chun Kuan Lee)
48349f8 Provide relevant error message if datadir is not writable. (murrayn)

Pull request description:

  As the software is currently using the ANSI encoding on Windows, the user's language settings could affect the proper functioning of the node/wallet, to the point of not be able to open some non-ASCII name files and directories.

  This solves the Windows encoding issues, completing the entire bitcoin#13869 work path (and some other required backports). Enabling for example users that use non-english characters in directories and file names to be accepted.

  Backported PRs:
  * bitcoin#12422.
  * bitcoin#12630.
  * bitcoin#13862.
  * bitcoin#13866.
  * bitcoin#13877.
  * bitcoin#13878.
  * bitcoin#13883.
  * bitcoin#13884.
  * bitcoin#13886.
  * bitcoin#13888.
  * bitcoin#14192.
  * bitcoin#13734.
  * bitcoin#14426.

  This is built on top of other two PRs that i have open #2423 and #2369.
  Solves old issues #940 and #2163.

  TODO:
  * Backport `assert_start_raises_init_error` and `ErrorMatch` in TestNode` (bitcoin#12718)

ACKs for top commit:
  Fuzzbawls:
    ACK 63e0be6
  random-zebra:
    ACK 63e0be6 and merging...

Tree-SHA512: cb1f7c23abb5b7b3af50bba18652cc2cad93fd7c2fca9c16ffd3fee34c4c152a3b666dfa87fe6b44c430064dcdee4367144dcb4a41203c91b0173b805bdb3d7d
vijaydasmp pushed a commit to vijaydasmp/dash that referenced this pull request Sep 8, 2021
369244f utils: Fix broken Windows filelock (Chun Kuan Lee)

Pull request description:

  Fix broken filelock on Windows, also add a test for this. It's a regression introduced by bitcoin#13862.

Tree-SHA512: 15665b1930cf39ec71f3ab07def8e2897659f6fd4d2de749d63a5a8ec920e4a04282f12bc262f242b1b3d14d2dd9fa191ddbcf16a46fb927b5b2b14d9f6b5d01
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants