Почему apt не отображает сообщение об ошибке, даже если используется стая?

Запуск сценария

#!/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

в качестве суперпользователя не отображает сообщение об ошибке. Но если есть, например, synaptic, apt-get отобразит сообщение об ошибке: «E: Не удалось получить lock / var / lib / dpkg / lock - open (11: временно недоступен ресурс)».

3
задан 15 November 2017 в 14:40

2 ответа

dpkg (и, в свою очередь, apt) не использует flock(2) для блокировки. При проверке задействованных системных вызовов кажется, что они используют 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

И из fcntl(2) :

В Linux lockf() - это всего лишь обертка вокруг fcntl(), а блокировки flock() - отдельные (и будут работать только в локальных файловых системах, а не на монтах NFS). То есть, один процесс может иметь специальную эксклюзивную блокировку flock() для файла, в то время как другой процесс имеет эксклюзивную блокировку fcntl() в этом же файле. Оба являются консультативными блокировками, но они не взаимодействуют.

Таким образом, flock не эффективен для блокировки его против других команд управления пакетами. (Размышляя об этом ... если бы это было так, то последующий apt-get потерпел бы неудачу в любом случае.)

1
ответ дан 18 July 2018 в 05:59

dpkg (и, в свою очередь, apt) не использует flock(2) для блокировки. При проверке задействованных системных вызовов кажется, что они используют 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

И из fcntl(2) :

В Linux lockf() - это всего лишь обертка вокруг fcntl(), а блокировки flock() - отдельные (и будут работать только в локальных файловых системах, а не на монтах NFS). То есть, один процесс может иметь специальную эксклюзивную блокировку flock() для файла, в то время как другой процесс имеет эксклюзивную блокировку fcntl() в этом же файле. Оба являются консультативными блокировками, но они не взаимодействуют.

Таким образом, flock не эффективен для блокировки его против других команд управления пакетами. (Размышляя об этом ... если бы это было так, то последующий apt-get потерпел бы неудачу в любом случае.)

1
ответ дан 24 July 2018 в 18:29
  • 1
    @jarno нажмите на ссылку fcntl в ответе. – muru 20 November 2017 в 18:55
  • 2
    dpkg не должен использовать команды для блокировки. Для них есть системные вызовы. Команда flock - это просто удобная оболочка вокруг одного из этих системных вызовов. Нет причин для всех вызовов иметь команды обёртки. – muru 20 November 2017 в 19:42
  • 3
    Я хочу добиться того, что я хочу заблокировать базу данных dpkg в сценарии, чтобы пользователь мог интерактивно выбирать некоторые пакеты, а затем делать с ними некоторые вещи с помощью apt или dpkg, не беспокоясь о том, что пакеты были изменены, например. фоновым процессом в среднее время. – jarno 21 November 2017 в 21:44
  • 4
    @jarno в этом случае, самый простой способ, о котором я могу думать, - создать неизменяемый файл /var/lib/dpkg/lock на время выполнения задачи. Или вы можете написать короткую программу на C, которая использует fcntl, чтобы заблокировать ее, как это делает dpkg. – muru 22 November 2017 в 15:39

Другие вопросы по тегам:

Похожие вопросы: