diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2019-06-21 22:45:13 +0200 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2019-06-21 23:14:46 +0200 |
commit | cde8399310e56faaa6928411392184bc403eff66 (patch) | |
tree | 4001440b885ffacbfb314fa8380e8b2bd2da7f5b | |
parent | 67b51af0f9c7cab4d827ac1e63f8a83d03e2f23c (diff) | |
download | apt-cde8399310e56faaa6928411392184bc403eff66.tar.gz |
Improve locking messaging - pid and name, "do not remove lock file"
We want to tell users which process is holding the lock so they
can easily understand what's going on, and we want to advise
users not to remove the lock file, because ugh, that's bad.
Re-initalize the flock structure, in case it got mangled by
previous fcntl call.
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 798636647..336f979d6 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -223,6 +223,30 @@ bool RemoveFile(char const * const Function, std::string const &FileName)/*{{{*/ is done all other calls to GetLock in any other process will fail with -1. The return result is the fd of the file, the call should call close at some time. */ + +static std::string GetProcessName(int pid) +{ + struct HideError + { + int err; + HideError() : err(errno) { _error->PushToStack(); } + ~HideError() + { + errno = err; + _error->RevertToStack(); + } + } hideError; + std::string path; + strprintf(path, "/proc/%d/status", pid); + FileFd status(path, FileFd::ReadOnly); + std::string line; + while (status.ReadLine(line)) + { + if (line.substr(0, 5) == "Name:") + return line.substr(6); + } + return ""; +} int GetLock(string File,bool Errors) { // GetLock() is used in aptitude on directories with public-write access @@ -256,6 +280,20 @@ int GetLock(string File,bool Errors) { // always close to not leak resources int Tmp = errno; + + if ((errno == EACCES || errno == EAGAIN)) + { + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = -1; + fcntl(FD, F_GETLK, &fl); + } + else + { + fl.l_pid = -1; + } close(FD); errno = Tmp; @@ -266,8 +304,21 @@ int GetLock(string File,bool Errors) } if (Errors == true) - _error->Errno("open",_("Could not get lock %s"),File.c_str()); - + { + if (fl.l_pid != -1) + { + auto name = GetProcessName(fl.l_pid); + if (name.empty()) + _error->Errno("open", _("Could not get lock %s. It is held by process %d"), File.c_str(), fl.l_pid); + else + _error->Errno("open", _("Could not get lock %s. It is held by process %d (%s)"), File.c_str(), fl.l_pid, name.c_str()); + } + else + _error->Errno("open", _("Could not get lock %s"), File.c_str()); + + _error->Notice(_("Be aware that removing the lock file is not a solution and may break your system.")); + } + return -1; } |