How do I check to see if an apt lock file is locked?
Solution 1:
Well I thought there would be a simple answer here but I can't find anything. First, are you 100% sure that lock file is always there? Try running
lsof /var/lib/dpkg/lock
as root to see if any process has it open.
From what I've read, apt-get does an fcntl lock, but I haven't looked at the code to verify. I guess that wuld explain why the file is there all the time, apt just locks it as needed.
What about just doing a check of the process list when your script runs, and exiting if apt is running at the same time? Would that be sufficient for your use?
Looks like this person went down the same path as you did, without much success.
Solution 2:
I came here looking for a solution similar to what gondoi ended up using but written in Python instead of Ruby. The following seems to work well:
import fcntl
def is_dpkg_active():
"""
Check whether ``apt-get`` or ``dpkg`` is currently active.
This works by checking whether the lock file ``/var/lib/dpkg/lock`` is
locked by an ``apt-get`` or ``dpkg`` process, which in turn is done by
momentarily trying to acquire the lock. This means that the current process
needs to have sufficient privileges.
:returns: ``True`` when the lock is already taken (``apt-get`` or ``dpkg``
is running), ``False`` otherwise.
:raises: :py:exc:`exceptions.IOError` if the required privileges are not
available.
.. note:: ``apt-get`` doesn't acquire this lock until it needs it, for
example an ``apt-get update`` run consists of two phases (first
fetching updated package lists and then updating the local
package index) and only the second phase claims the lock (because
the second phase writes the local package index which is also
read from and written to by ``dpkg``).
"""
with open('/var/lib/dpkg/lock', 'w') as handle:
try:
fcntl.lockf(handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
return False
except IOError:
return True
Solution 3:
From a shell script (see flock(1)):
flock --timeout 60 --exclusive --close /var/lib/dpkg/lock apt-get -y -o Dpkg::Options::="--force-confold" upgrade
if [ $? -ne 0 ]; then
echo "Another process has f-locked /var/lib/dpkg/lock" 1>&2
exit 1
fi
Solution 4:
I found out that apt is using a fcntl. Since I am using Ruby for the scripting language, I had to create my own function to look for lock. The reason for this, is because Ruby does not implement the fcntl function entirely. It only provides the function call and constants. The ability to build flock structs and how to pass them is left out or not documented.
Here is the list I found talking about that.
Here is the function I ended up writing:
def flocked? &block
flockstruct = [Fcntl::F_RDLCK, 0, 0, 0, 0].pack("ssqqi")
fcntl Fcntl::F_GETLK, flockstruct
status = flockstruct.unpack("ssqqi")[0]
case status
when Fcntl::F_UNLCK
return false
when Fcntl::F_WRLCK|Fcntl::F_RDLCK
return true
else
raise SystemCallError, status
end
end