Running script

#!/bin/bash
(
 flock 9 
  # ... commands executed under lock ...
 fuser -v /var/lib/dpkg/lock
 apt-get -f --assume-no install
) 9>/var/lib/dpkg/lock

as superuser does not display an error message. But if there is e.g. synaptic running,apt-get will display an error message: "E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)".

dpkg (and in turn apt) doesn't use flock(2) for locking. Checking the system calls, involved, it seems they use fcntl(2):

$ sudo strace -f -e trace=desc apt install foo |& grep -B2 F_SETLK
close(4)                                = 0
open("/var/lib/dpkg/lock", O_RDWR|O_CREAT|O_NOFOLLOW, 0640) = 4
fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
fcntl(4, F_SETLK, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = -1 EAGAIN (Resource temporarily unavailable)
close(4)                                = 0

And from this SO post:

In Linux, lockf() is just a wrapper around fcntl(), while flock() locks are separate (and will only work on local filesystems, not on e.g. NFS mounts). That is, one process can have an advisory exclusive flock() lock on a file, while another process has an advisory exclusive fcntl() lock on that same file. Both are advisory locks, but they do not interact.

So flock isn't effective in locking it against other package management commands. (Thinking about it... if it were, then the subsequent apt-get would have failed anyway.)

  • But there are no commands fcntl or lockf in terminal. – jarno Nov 20 '17 at 14:14
  • @jarno click on the fcntl link in the answer. – muru Nov 20 '17 at 14:55
  • dpkg doesn't have to use commands to do locking. There are system calls for those. The flock command is merely a convenient wrapper around one of those system calls. There's no reason for all calls to have wrapper commands. – muru Nov 20 '17 at 15:42
  • What I want to achieve is that I want to lock dpkg database in a script so that user can choose interactively some packages, and thereafter do certain things with them by apt or dpkg without worrying that the packages have been changed e.g. by a background process in the mean time. – jarno Nov 21 '17 at 17:44
  • @jarno in that case, the simplest way I can think of is to create an immutable /var/lib/dpkg/lock file for the duration of the task. Or you can write a short C program that uses fcntl to lock it the way dpkg does. – muru Nov 22 '17 at 11:39

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.