Каждый раз при обновлении системы до Sisyphus обновление прерывается на последнем устанавливаемом пакете с диагностикой: \"ошибка: ошибка(4) db-30988 из dbcursor->c_get: DB_PAGE_NOTFOUND: Requested page not found\" --- --- Система: когда-то Junior 1.1, периодически обновляемый до текущего состояния Sisyphus (apt-get dist-upgrade). Ошибка появилась в последние две недели.
Имеет место не вполне корректная работа с блокировками базы данных /var/lib/rpm/Packages. Ситуация может возникнуть, например, при обновлении пакета, содержащего menu entry.
*** Bug 4323 has been marked as a duplicate of this bug. ***
Created attachment 429 [details] Test of locking
Zerg, твой тест демонстрирует вполне нормальную блокировку rpm'а.
(In reply to comment #5) > Zerg, твой тест демонстрирует вполне нормальную блокировку rpm'а. Не понял, в процессе установки пакетов база должна быть разблокирована для чтения?
Zerg, твой тест демонстрирует вполне нормальную работу блокировок rpm'а, и ненормальную работу блокировок apt'а, поскольку последний после создания блокировки запускает подпроцессы, и в результате блокировка теряется.
На самом деле проблема в libapt, блокировка теряется при запуске подпроцессов, поскольку дескриптор, на котором эта блокировка, CLOEXEC.
*** Bug 5197 has been marked as a duplicate of this bug. ***
*** Bug 2674 has been marked as a duplicate of this bug. ***
Сделать хотя бы какой-нибудь любой другой лок, который не будет слетать.
Отлично видно как слетает блокировка при работе apt-shell: 1) запускаем apt-shell 2) в другом терминале пробуем rpm -q <установленный пакет>, обламываемся на заблокированной базе 3) устанавливаем или удаляем пакет в apt-shell (например install ntdate и commit -y) 4) пытаемся в соседнем терминале запросить информацию о пакете.. наблюдаем успешно разблокированную базу включаем максимальный уровень отладки у librpm через rpmIncreaseVerbosity();, вызываем в libapt наблюдаем в логах только одну попытку залочить базу: fgrep "/var/lib/rpm/Packages" Log D: opening db environment /var/lib/rpm/Packages create:mpool D: opening db index /var/lib/rpm/Packages mode=0x2 D: locked db index /var/lib/rpm/Packages D: closed db index /var/lib/rpm/Packages D: closed db environment /var/lib/rpm/Packages D: removed db environment /var/lib/rpm/Packages D: verified db index /var/lib/rpm/Packages D: opening db environment /var/lib/rpm/Packages create:mpool D: opening db index /var/lib/rpm/Packages mode=0x2 D: closed db index /var/lib/rpm/Packages D: closed db environment /var/lib/rpm/Packages D: removed db environment /var/lib/rpm/Packages D: verified db index /var/lib/rpm/Packages D: opening db environment /var/lib/rpm/Packages create:mpool D: opening db index /var/lib/rpm/Packages mode=0x2 D: closed db index /var/lib/rpm/Packages D: closed db environment /var/lib/rpm/Packages D: removed db environment /var/lib/rpm/Packages D: verified db index /var/lib/rpm/Packages сам apt-get использует для блокировки базы rpmdbOpen(), кода fork() я в нем не нашел (может плохо искал?) все-таки возникает подозрение, что блокировку не устанавливает заново librpm
да, забыл добавить: судя по всему не прокатывает одно из условий в librpmdb: в rpmdb/db3.c добавлен следущий код: printf("db3open, fcntl:%i\n", (rc == 0 && dbi->dbi_lockdbfd && (!dbi->dbi_use_dbenv || _lockdbfd++ == 0))); соответственно вот вывод работы apt-shell: LD_LIBRARY_PATH=./ apt-shell 2>Log RPMDBHandler:WriteLock1 rpmdbOpen:2, 1a4 Enter to db3open db3open, fcntl:1 LockRpm:1 Чтение списков пакетов... Завершено Построение дерева зависимостей... Завершено Добро пожаловать в APT shell. Используйте команду "help" для дополнительной информации. apt> remove icewm apt> commit -y Следующие пакеты будут УДАЛЕНЫ: icewm 0 будет обновлено, 0 новых установлено, 1 пакетов будет удалено и 1 не будет обновлено. Необходимо получить 0B архивов. После распаковки будет освобождено 984kB дискового пространства. UnLockRpm:0 rpmdbOpen:2, 1a4 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Совершаем изменения... Preparing... Enter to db3open db3open, fcntl:0 ################################################################################################### [100%] Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Enter to db3open db3open, fcntl:0 Завершено. RPMDBHandler:WriteLock1 rpmdbOpen:2, 1a4 Enter to db3open db3open, fcntl:0 LockRpm:1 Чтение списков пакетов... Завершено Построение дерева зависимостей... Завершено apt>
Created attachment 937 [details] rpm-4_0-4.0.4-lock-fixed.patch Патч, исправляющий эту ошибку в librpmdb. Пояснение: static переменная, которую я убрал не позволяет провести вторую блокировку в случае, когда librpm используется кем-то вроде apt'а, который несколько раз открывает и закрывает базу rpm. в коде для db1 такой переменной не обнаружено. rpm с таким патчем работает нормально, apt-get, apt-shell - тоже. в случае apt-shell при наличии этого патча поведение меняется следущим образом: 1) открывается база rpm 2) в момент commit'а база закрывается и запускается процесс установки пакетов, который снова открывает и лочит базу 3) после установки пакетов база закрывается (блокировка снимается) 4) базу снова открывает apt-shell и восстанавливает блокировку.
Вот как это выглядит с патчем (просьба не обращать внимания на разную отладочную информацию. fcntl_mod: 2 означает установку блокировки на базу. после работы commit'а база получается залоченной (как оно и должно быть). # LD_LIBRARY_PATH=./ apt-shell 2>Log RPMDBHandler:WriteLock1 rpmdbOpen:2, 1a4 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 1, 1, 0 db3open, fcntl3:0, 1, 1, 1 fcntl_mod: 2 LockRpm:1 Чтение списков пакетов... Завершено Построение дерева зависимостей... Завершено Добро пожаловать в APT shell. Используйте команду "help" для дополнительной информации. apt> remove icewm Пакет icewm не установлен, и не может быть удалён. apt> install icewm apt> commit Следующие НОВЫЕ пакеты будут установлены: icewm 0 будет обновлено, 1 новых установлено, 0 пакетов будет удалено и 1 не будет обновлено. Необходимо получить 0B/398kB архивов. После распаковки потребуется дополнительно 984kB дискового пространства. Продолжить? [Y/n] UnLockRpm:0 rpmdbOpen:2, 1a4 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 1, 1, 0 db3open, fcntl3:0, 1, 1, 1 fcntl_mod: 2 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Совершаем изменения... Preparing... ################################################################################################### [100%] 1: icewm ################################################################################################### [100%] Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 0, 1, 0 Завершено. RPMDBHandler:WriteLock1 rpmdbOpen:2, 1a4 Enter to db3open db3open, fcntl:0 db3open, fcntl2:0, 1, 1, 0 db3open, fcntl3:0, 1, 1, 1 fcntl_mod: 2 LockRpm:1 Чтение списков пакетов... Завершено Построение дерева зависимостей... Завершено apt>
Hopefully fixed in slightly different way. Please test rpm-4.0.4-alt44.