Script en cours d'exécution
#!/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
en tant que superutilisateur n’affiche pas de message d’erreur. Mais s'il y a par exemple synaptic
en cours d'exécution, apt-get
affiche un message d'erreur: "E: Impossible d'obtenir le verrouillage/var/lib/dpkg/lock - open (11: la ressource n'est pas disponible temporairement)".
dpkg
(et à son tour apt) n'utilise pas flock(2)
pour le verrouillage. Vérification des appels système, impliqués, il semble qu'ils utilisent 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
Et de this SO post :
Sous Linux,
lockf()
est juste un wrapper autour defcntl()
, alors que les verrousflock()
sont séparés (et ne fonctionneront que sur les systèmes de fichiers locaux, pas sur les montages NFS, par exemple). Autrement dit, un processus peut avoir un verrou consultatif exclusifflock()
sur un fichier, tandis qu'un autre processus dispose d'un verrou consultatif exclusiffcntl()
sur ce même fichier. Les deux sont des verrous consultatifs, mais ils n'interagissent pas.
Donc, flock
n'est pas efficace pour le verrouiller contre d'autres commandes de gestion de paquets. (En y réfléchissant ... s'il en était ainsi, le apt-get
suivant aurait de toute façon échoué.)
Le moyen le plus simple auquel je puisse penser est de créer un fichier /var/lib/dpkg/lock
immuable pour la durée de la tâche.
touch /var/lib/dpkg/lock
chattr +i /var/lib/dpkg/lock
Vous pouvez également écrire un programme C court (ou n’importe quel langage offrant une interface simple à fcntl
) qui utilise fcntl
pour le verrouiller comme le fait dpkg.