Summary: | запуск триггеров навсегда отключается при запуске apt-get install через ssh | ||
---|---|---|---|
Product: | Sisyphus | Reporter: | Alexey Sheplyakov <asheplyakov> |
Component: | rpm | Assignee: | placeholder <placeholder> |
Status: | NEW --- | QA Contact: | qa-sisyphus |
Severity: | normal | ||
Priority: | P3 | CC: | aen, asy, at, avm, boyarsh, darktemplaralt, evg, glebfm, imz, inger, iv, lav, ldv, mike, placeholder, rider, vt |
Version: | unstable | Keywords: | regression, usability |
Hardware: | all | ||
OS: | Linux | ||
Bug Depends on: | 42201 | ||
Bug Blocks: | 34231 |
Description
Alexey Sheplyakov
2018-09-17 18:27:23 MSK
А screen или tmux на удалённой машине помогает? > А screen или tmux на удалённой машине помогает?
Вопрос не понят.
Это, наверное, ещё происходит при конфигурации с systemd ? > Это, наверное, ещё происходит при конфигурации с systemd?
Да.
В systemd есть настройка - прибивать пользовательские процессы после закрытия сеанса. KillUserProcesses=no https://www.freedesktop.org/software/systemd/man/logind.conf.html попробуйте выставить в это значение, скорее всего поможет. > В systemd есть настройка - прибивать пользовательские процессы после закрытия
сеанса.
Дык и без systemd есть масса ситуаций, к примеру,
apt-get -y dist-upgrade && shutdown -r now
(тут даже и по ssh ходить не надо).
Ошибка в том, что apt выходит раньше, чем завершается обновление, а не в том, что злой systemd что-то там убивает. Причем проявляется эта ошибка совершенно в неожиданных ситуациях, "на ровном месте".
P.S. А костыль я и сам придумал (&& sleep 10)
Это apt или rpm не ждёт завершения файлтриггеров? или речь идёт исключительно об обновлении пакета rpm? После запуска apt get dist-upgrade файлтриггеры rpm выполняются в фоновом режиме. Кто там из них не ждёт - непонятно. скорее всего rpm/librpm. > Ошибка в том, что apt выходит раньше, чем завершается обновление. Это не баг, это фича^{tm}. Не сдержусь и распишу подробности. Файлтриггеры намеренно откладываются[1][2] чтобы они выполнялись после перестроения базы rpm; а это может происходить только после того, как apt, использующий rpm как библиотеку, завершит работу. [1]: http://git.altlinux.org/gears/r/rpm.git?p=rpm.git;a=blob;f=alt/rpm.spec;h=925462302b2cceaf05cdd10416385061c65e1394#l358 [2]: http://git.altlinux.org/gears/r/rpm.git?p=rpm.git;a=blob;f=scripts/postupdate.in;h=519efcfa1d5670809fedb60b318efe7a5b7ae925 Так что их вообще никто не ждёт, и ждать их некому (кроме пользователя), и это как бы by design. Проблемы же тут видятся две, и хотелось бы посмотреть на них отдедельно. Во-первых, пользователь, похоже, может красиво запороть себе систему невинно выглядящим `apt-get dist-upgrade && reboot`, если в этом dist-upgrade обновился rpm. Во-вторых, чтобы вывести систему из этого состояния необходимы нетривиальные действия вроде запуска /usr/lib/rpm/postupdate вручную. пример с ssh выглядит более реалистичным. > пример с ssh выглядит более реалистичным.
Мне удалось "вступить" в оба варианта на практике.
Более изящный костыль: sudo systemd-run --service-type=forking --wait apt-get install -y rpm systemd запускает "временный" сервис и дожидается, пока не выйдут все процессы-потомки (благодаря --service-type=forking) Приколачивать rpm к systemd из-за корявости systemd -- это даже не костыль... Нет, конечно корявость systemd тут не при чём. Он позволяет исправить архитектуру обновления apt + rpm. Ведь при apt-get -y dist-upgrade && reboot systemd может и не быть. Уход в фон был, как мне кажется, сделан из соображений удобства человека -- тогда уж разумней переделать на синхрон и всё. если это возможно. я не вижу много удобств в фоновом выполнении скриптов после установки - мало ли что вылезет в них плохого. Как отработать код возврата ? Сталкивался уже с ситуацией, когда один кривой скрипт в filetrigger ломает запуск всех остальных. (In reply to comment #16) > Уход в фон был, как мне кажется, сделан из соображений удобства человека -- Уход в фон был сделан для того, чтобы дождаться завершения всех пользователей старой базы данных. Это для перестройки базы. а для filetrigger ? (In reply to comment #19) > Это для перестройки базы. Да, и это сейчас происходит при каждом обновлении пакета rpm. > а для filetrigger ? Обычно файлтриггеры выполняются синхронно по окончании транзакции. Выполнение файлтриггеров откладывается и происходит в фоне только в одном случае - при обновлении пакета rpm с 4.0.4: %triggerpostun -- rpm <= 4.0.4 touch /var/lib/rpm/delay-posttrans-filetriggers (In reply to comment #5) > В systemd есть настройка - прибивать пользовательские процессы после закрытия > сеанса. > KillUserProcesses=no На всякий случай о моменте, когда оно началось, и почему: https://lists.altlinux.org/pipermail/sisyphus/2018-April/366620.html "Теперь значение по умолчанию default-kill-user-processes=true" > На всякий случай о моменте, когда оно началось, и почему: https://lists.altlinux.org/pipermail/sisyphus/2018-April/366620.html Вызывающе неверная информация. Проблема в том, что apt выходит раньше, чем завершаются триггеры. Именно поэтому apt-get dist-upgrade -y && shutdown -r now оставляет систему в "интересном" состоянии P.S. Подход "во всем виноват systemd" не позволяет ничего понять (не говоря уж об исправлении) (In reply to comment #22) > Проблема в том, что apt выходит раньше, чем завершаются триггеры. Именно > поэтому Нет, проблема в том, что systemd прибивает процессы, когда это, скажем так, не очень нужно. Или очень не нужно. > apt-get dist-upgrade -y && shutdown -r now А что же не "... && reboot -f" то сразу. (In reply to comment #22) > P.S. Подход "во всем виноват systemd" не позволяет ничего понять (не говоря уж > об исправлении) По-моему тут всё разобрано и совершенно понятно. И, кстати, этот баг - явный кандидат на WONTFIX, так как единственное решение - это kill-user-processes=no ввиду того, что и базу перестраивать, и триггреры исполнять после обновления 4.0.4 > 4.13 надо после завершения rpm. Но сделать этого нельзя ввиду того, рази чего было сделано true. > единственное решение - это kill-user-processes=no проблема в том, что apt выходит раньше, чем завершаются триггеры, потому пользователь (или скрипт, запущенный пользователем), не может определить, когда обновление завершилось и можно безопасно запустить следующее действие (например, reboot). apt вынужден выходить до запуска триггеров по причине тупости librpm. Более подробно изложено в https://bugzilla.altlinux.org/show_bug.cgi?id=35405#c10 > этот баг - явный кандидат на WONTFIX Сколько ярлыков ни приклей, проблема не перестанет от этого существовать: обновление может легко и без видимых причин запороть систему, и как ее потом выводить из этого состояния -- совершенно не очевидно. (In reply to comment #25) > apt вынужден выходить до запуска триггеров по причине тупости librpm. > Более подробно изложено в comment #10 Я, вообще-то, умею читать. И там написно, что это - не баг. > > этот баг - явный кандидат на WONTFIX > > Сколько ярлыков ни приклей, проблема не перестанет от этого существовать: > обновление может легко и без видимых причин запороть систему, и как ее потом > выводить из этого состояния -- совершенно не очевидно. Автоматическое обновление. Но автоматическое обновление всегда опасно и само по себе. Надо просто отдавать себе в этом отчёт. А в скрипте, на самом деле, и перестроение базы можно отследить, и работу триггеров. ps в помощь, что называется. В качестве рекомендации, "&& reboot" я бы вообще никогда не советовал. Всегда надо посмотреть, что там как прошло, рестарт сервисов и т.п. Я согласен с тем, что обновление должно уметь проходить в автоматическом режиме и для этого было бы отлично иметь инструмент, отслеживающий окончания процесса обновления. По идее, если отменить запуск filetrigger в background, то должно стать легче. > А в скрипте, на самом деле, и перестроение базы можно отследить, и работу триггеров. ps в помощь, что называется. Автоматизация 80 lvl. Вам не стыдно? > В качестве рекомендации, "&& reboot" я бы вообще никогда не советовал. Всегда надо посмотреть, что там как прошло, рестарт сервисов и т.п. То есть Вы утверждаете, что apt-rpm -- настолько ненадежный инструмент, что результат его работы нужно всегда проверять вручную? А почему, собственно, apt'у обязательно нужно завершиться для перестройки rpmdb? $ git grep -n rpmtsOpenDB apt-pkg/rpm/rpmhandler.cc:405: if (rpmtsOpenDB(Handler, O_RDONLY) != 0) apt-pkg/rpm/rpmpm.cc:802: if (rpmtsOpenDB(TS, O_RDWR) != 0) apt-pkg/rpm/rpmsystem.cc:263: if (rpmtsOpenDB(ts, O_RDONLY)) $ git grep -e 'rpmtsCloseDB' |wc -l 0 А потому, что он умеет открывать rpmdb, но не умеет ее закрывать. P.S. Жду новых удивительных историй о том, что это не баг, и о том, что завершения триггеров можно дождаться с помощью ps (In reply to comment #28) > То есть Вы утверждаете, что apt-rpm -- настолько ненадежный инструмент, что > результат его работы нужно всегда проверять вручную? Я, наверное, открою страшную тайну, но я скажу. Нет ни одного способа проверить, что произвольный пакет обновился на 100% хорошо. Ни у одного пакетного менеджера, ни в одном дистрибутиве. (In reply to comment #29) [...] > $ git grep -e 'rpmtsCloseDB' |wc -l > 0 TIMTOWDI. Try `git grep rpmtsFree`. (In reply to Alexey Sheplyakov from comment #29) > А почему, собственно, apt'у обязательно нужно завершиться для перестройки > rpmdb? > > $ git grep -n rpmtsOpenDB > apt-pkg/rpm/rpmhandler.cc:405: if (rpmtsOpenDB(Handler, O_RDONLY) != 0) > apt-pkg/rpm/rpmpm.cc:802: if (rpmtsOpenDB(TS, O_RDWR) != 0) > apt-pkg/rpm/rpmsystem.cc:263: if (rpmtsOpenDB(ts, O_RDONLY)) > > $ git grep -e 'rpmtsCloseDB' |wc -l > 0 > > А потому, что он умеет открывать rpmdb, но не умеет ее закрывать. > > P.S. Жду новых удивительных историй о том, что это не баг, и о том, что > завершения триггеров можно дождаться с помощью ps (In reply to Ivan A. Melnikov from comment #31) > (In reply to comment #29) > [...] > > $ git grep -e 'rpmtsCloseDB' |wc -l > > 0 > > TIMTOWDI. Try `git grep rpmtsFree`. Сейчас в apt-0.5.15lorg2-alt79 есть обёртки над основным процессом, которые выполняют в конце действия из POST_UPDATE_SCRIPT -- туда rpm их запишет (например, перестройку базы данных, я так думаю, с последующим запуском отложенных триггеров). Мне кажется, что лучше будет это сделать не с помощью обёрток, а внутри функций apt в те моменты по завершении транзакций, когда база данных rpm закрывается. Там, надеюсь, будет ясно, что apt работает с один экземпляром "системного пакетного менеджера" и не будет сомнений, что кто-то ещё держит базу открытой. В случае apt-shell это будет более правильный подход, потому что он позволяет делать транзакции многократно. Также это сработает для клиентов libapt (таких как packagekit, synaptic, etc.), которые сами напрямую базу данных rpm не открывают, конечно, т.е. всё нам интересное может контролировать libapt. |