web-dev-qa-db-fra.com

Pourquoi apt n'affiche-t-il pas de message d'erreur même si flock est utilisé?

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)".

4
jarno

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 de fcntl(), alors que les verrous flock() 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 exclusif flock() sur un fichier, tandis qu'un autre processus dispose d'un verrou consultatif exclusif fcntl() 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.

2
muru