Skip to content

Commit

Permalink
lockfile: handle same PID case and add hint for container user
Browse files Browse the repository at this point in the history
  • Loading branch information
jesec committed Feb 21, 2021
1 parent ab9a1ca commit 957f69e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
19 changes: 14 additions & 5 deletions src/core/download_store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,23 @@ DownloadStore::enable(bool lock) {
m_lockfile.set_path(std::string());

if (!m_lockfile.try_lock()) {
if (torrent::utils::error_number::current().is_bad_path())
if (torrent::utils::error_number::current().is_bad_path()) {
throw torrent::input_error(
"Could not lock session directory: \"" + m_path + "\", " +
torrent::utils::error_number::current().message());
else
throw torrent::input_error("Could not lock session directory: \"" +
m_path + "\", held by \"" +
m_lockfile.locked_by_as_string() + "\".");
} else {
auto msg = "Could not lock session directory: \"" + m_path +
"\", held by \"" + m_lockfile.locked_by_as_string() + "\".";

if (::getpid() < 10) {
// Hint for container users
msg += '\n';
msg += "Hint: use a consistent hostname so rTorrent can safely handle "
"stale locks.";
}

throw torrent::input_error(msg);
}
}
}

Expand Down
20 changes: 16 additions & 4 deletions src/utils/lockfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,27 @@ struct lockfile_valid_hostname {

bool
Lockfile::is_stale() {
process_type process = locked_by();
const auto [hostname, pid] = locked_by();

char buf[256];

if (process.second <= 0 || ::gethostname(buf, 255) != 0 ||
buf != process.first)
if (pid <= 0) {
// um... pid is not supposed to be negative
return false;
}

if (::gethostname(buf, 255) != 0 || buf != hostname) {
// it is probably locked by another machine
// maybe the directory is shared or the hostname has changed
return false;
}

if (::getpid() == pid) {
// this happens a lot with controlled environments like containers
return true;
}

return ::kill(process.second, 0) != 0 && errno != EPERM;
return ::kill(pid, 0) != 0 && errno != EPERM;
}

bool
Expand Down

0 comments on commit 957f69e

Please sign in to comment.