Цель этого поста: показать технику отладки в debian/ubuntu, связанную с "поиском первоисточника" в системном конфигурационном файле.


Тестовый пример: после долгих издевательств над tar.gz копией установленной ОС и после её восстановления и установки апдейтов мы получаем сообщение:


update-initramfs: Generating /boot/initrd.img-4.15.0-54-generic
W: initramfs-tools configuration sets RESUME=/dev/mapper/U1563304817I0-swap
W: but no matching swap device is available.
I: The initramfs will attempt to resume from /dev/dm-1
I: (/dev/mapper/foobar-swap)
I: Set the RESUME variable to override this.

Цель: понять, откуда это значение (U1563304817I0) пришло и как его правильно поменять. Это первый попавшийся пример, не особо интересный сам по себе, но удобный, чтобы показать практические методы работы с Linux.


Шаг номер 1: Откуда пришёл RESUME?


# cd /etc
# grep -r RESUME
initramfs-tools/conf.d/resume:RESUME=/dev/mapper/U1563304817I0-swap

Мы рекурсивно (-r) ищем упоминание этой переменной в каталоге /etc (там, где большинство конфигов). Мы находим conf.d сниппет, который явно используется пакетом initramfs-tools.


Откуда этот сниппет?


Есть три варианта:


  1. Магический артефакт (кто-то положил и забыл)
  2. Конфиг из пакета
  3. Конфиг, сгенерированный каким-то скриптом из системных пакетов

Проверяем №2 (как самый простой):


 dpkg -S initramfs-tools/conf.d/resume
dpkg-query: no path found matching pattern *initramfs-tools/conf.d/resume*

dpkg -S позволяет нам поискать по базе установленных файлов и найти к какому пакету файл относится. Вот пример удачного поиска:


dpkg -S resolv.conf
manpages: /usr/share/man/man5/resolv.conf.5.gz
systemd: /lib/systemd/resolv.conf

Возвращаемся к нашей задаче: файл initramfs-tools/conf.d/resume не устанавливается в систему из пакета. Может быть он генерируется в postinst/preinst скрипте пакета? Проверяем версию номер 3.


# cd /var/lib/dpkg/info/
# grep -r initramfs-tools/conf.d/resume *
initramfs-tools-core.postrm:    rm -f /etc/initramfs-tools/conf.d/resume

В каталоге /var/lib/dpkg/info/ лежат распакованные версии всех "метафайлов" пакетов (скрипты установки/удаления, описания пакетов и т.д.). Удивительно, но этот файл удаляется в postrm (при удалении) пакета initramfs-tools-core. Посмотрим содержимое его postinst… Ничего, касающегося conf.d директории.


Давайте посмотрим на файлы из состава пакета initramfs-tools-core.


# dpkg -L initramfs-tools-core
...
/usr/share/initramfs-tools/hooks/resume
...

Команда dpkg -L позволяет посмотреть все файлы, которые есть в системе от указанного пакета. Я выделил интересный для изучения файл. Изучение файла показывает как эта переменная используется, но не отвечает откуда он появляется.


debconf


Получается, это чей-то артефакт. Чей? Перед тем, как нырять в инсталлятор, глянем ещё в одну важную инфраструктуру Debian — ответы на вопросы. Каждый раз, когда пакет задаёт вопрос, и во многих случаях, когда он вопроса не задаёт, но использует вариант по-умолчанию, и вопрос, и ответ фиксируются в специальной базе в Debian, которая называется debconf. Мы можем посмотреть на базу ответов (и даже выставить их до установки самого пакета — debconf-set-selections), для этого нам потребуется утилита debconf-get-selections из состава debconf-utils. К сожалению, ничего интересного не нашлось: (debconf-get-selections |grep -i resume вернул пусто).


debian-installer


У установщика есть своя база ответов на вопросы: /var/log/installer/cdebconf/questions.dat. К сожалению, там тоже нет ни слова про наш resume.
Зато рядом есть логи, в т.ч. syslog, куда пишется весь лог инсталляции. Там упоминается пакет base-installer, и на его странице мы можем видеть ссылку на сырцы.


Внутри них мы с лёгкостью находим ответ на наш вопрос:


  resume="$(mapdevfs "$resume_devfs")"; then
...
    if [ "$do_initrd" = yes ]; then
     ...
            resumeconf=$IT_CONFDIR/resume
....
                echo "RESUME=$resume" >> $resumeconf

mapdevfs — это утилита с понятным назначением, а интересная нам функция это get_resume_partition, которая читает /proc/swaps и выбирает там самую большую. Swap же у нас приходит от partman'а.


Ответ на наше тестовое задание: файл создаётся инсталлятором в /target'е в момент установки, т.е. мы говорим про well-known, но артефакт. В существующих в системе пакетах нет никого и ничего, чтобы меняло этот файл.


Подводя итог


  1. dpkg и debconf — основные методы для поиска поставщиков файлов.
  2. поиск в /var/lib/dpkg/info позволяет увидеть операции над файлами на этапе установки.
  3. Установщик может создавать файлы-артефакты, которые потом никем никогда не меняются (кроме пользователя), и это можно увидеть в коде установщика.

Комментарии (23)


  1. gecube
    23.07.2019 19:37

    Очень интересное приключение.
    Занятно, а разработчики дебиан почему не сделали единый интерфейс для создания настроенных файлов? Или это в принципе на этой стадии установки системы невозможно ?


    1. amarao Автор
      23.07.2019 23:01
      +1

      Такой интерфейс есть, называется conffiles. К сожалению, в общем случае provenance (происхождение) файла конфигурации очень трудно установить административными методами, потому что иногда эти файлы генерируются утилитами софта (я смотрю на тебя, pg_cluster). В теории такая система была бы крутой, но… Поверьте мне, в мире update-initramfs/update-grub есть куда большие ужасы, чем отсутствие единой базы конфигов… Там гигантские стопки баша, вызвающие Си, который вызывает баш, который вызывает Си… Боль, легаси и привет из конца 90ых, когда это было "ок.


      1. gecube
        24.07.2019 00:11
        +1

        по мне вообще весь deb как принцип ущербен. Чего стоит миграции баз между версиями в пост-инсталл mysql пакета. Блин, парни, а ничего, что это не должно никогда на автомате производиться?
        Я уж не говорю, что транзакционность установки пакетов в rpm-based на порядок лучше, чем в дебиан (видели необходимость делать apt install с ключом force или dpkg reconfigure, если что-то пошло не так?)
        По идее может спасти этот мир CoreOS с докеризованными приложениями… но нет...


        Самое обидное в этой истории, что приходится двигаться за большинством… и тут внезапно в продакшене оказывается убунта… и хорошо, если еще LTS, ога.


        1. Magister7
          24.07.2019 09:53

          Хм, а мне вот наоборот, удобно что миграция версий происходит автоматически. Меньше ручной работы — обновил пакет, все что надо перезапустилось, если пакет использует debconf и я руками ничего не исправлял, то и конфиг обновился сам, и все — все работает.
          Минимум ручных операций.
          В чем тут проблема? Пакет же сам не прилетит с новой мажорной версией, а если я сам это доклад то явно и базы обновить хочу.


          Транзакционность — оно то да, но я вот даже не вспомню когда у меня что-то ломалось по этой причине. Бывало что пакет остаётся half-installed из-за ошибки в postinst-скрипте, но тут можно найти причину и поправить — скрипты лежат себе распакованные на своем месте, и продолжить процесс через apt -f install


        1. JTG
          24.07.2019 10:51

          > apt install с ключом force

          Особенно «полезен» этот совет, когда в процессе установки заканчивается место на /boot
          www.linux.org.ru/forum/general/11955554
          askubuntu.com/questions/345588/what-is-the-safest-way-to-clean-up-boot-partition/430944#430944


          1. amarao Автор
            24.07.2019 11:18
            +1

            Удивительные приключения цитаты при квотировании...


            Сказали apt -f install, в квоте появилось apt с ключом force. Хотя man страница говорит, что -f — это --fix-broken.


            А дальше с удобной цитатой удобно спорить.


            1. DaemonGloom
              24.07.2019 12:58

              Да нет, там gecube именно про ключ force сказал. Ошибся, видимо. Или не так понял параметр.


              1. amarao Автор
                24.07.2019 13:00

                А, пардон. Особенности древовидного чтения.


                1. gecube
                  24.07.2019 14:15

                  ну, может я и ошибся ) по памяти писал, а на абсолютное знание дебиан систем я не претендую )


          1. gecube
            24.07.2019 14:18

            Да, кстати, на ситуации по ссылкам я попадал. И как-то с грехом пополам их решал.


      1. NetBUG
        24.07.2019 09:53

        А единая база конфига на реальной, работающей системе (т.е. у нас есть несколько сотен пакетов — включая служебные, которые в этой системе работают минимум два релиза, т.е. есть legacy-параметры) приводит… внезапно, к появлению свалки типа «реестр».
        Несколько могло бы помочь решение с разделением полномочий (т.е. один пользователь пишет в одну ветку, одно приложение пишет в одну ветку), которого так не хватает Windows Registry. Но проблемы бессмысленных, не читаемых никем параметров это не снимает.

        Если каждому параметру добавить last_access_time — эта помойка ещё и тормозить будет.


        1. gecube
          24.07.2019 14:16

          Ага. А в распределенных системах роль такой базы выполняет Consul, который при неаккуратном обращении так же превращается в свалку неактуальных k/v значений. Но это судьба любого стейтфул — рано или поздно превратиться в помойку.


          1. amarao Автор
            24.07.2019 14:43
            +1

            Наличие свалки определяется тем, является ли полученная конструкция жёсткой или нет. Теоретически, при должном фашизме, у нас может быть схема, которая позволяет отвечать на вопрос "кто отвечает за эту настройку?" и "когда это можно удалять?". Например, даже при многих своих недостатках, debian может сказать, когда конфиги приложения надо удалять и что именно "конфиг" (так называемый purge).


            Но полноценная поддержка такого требует реального схемо-фашизма и проверки связности всех узлов графа. Может быть, кто-нибудь, когда-нибудь осилит такое. Пока что наслаждаемся креативным анархизмом.


  1. Andrey_Rogovsky
    23.07.2019 20:13

    — Сынок, у тебя опять мусор в комнате?
    — Мам, отстань, это — артефакты!


    1. amarao Автор
      23.07.2019 22:56
      +3

      — Мы уже много раз обсуждали, что все артефакты должны помещаться в централизованное хранилище с заданной retention policy.


  1. Cenzo
    23.07.2019 21:54

    Эх, когда же будут по дефолту конфиги по типу git, чтобы было ясно, кто, откуда, когда и какую строчку. Сохранил как шпаргалку, так как часто подобное приходилось делать в RPM-based.

    оператор ЭВМ

    Вспомнил свои корочки оператора ЭВМ на втором курсе универа, вытер скупую слезу.


    1. evg_krsk
      24.07.2019 06:18

      Отчасти эту проблему решает etckeeper — он умеет на каждое изменение в /etc писать в commit message, какие пакеты были удалены/установлены (как для deb так и для rpm). Кто конкретно создал файл он не покажет, но поможет с точностью до дня/пакета установить причастных.


      1. gecube
        24.07.2019 08:20

        отчасти эту проблему решает любой SCM (да даже ансибл в принципе, не говоря уже о нормальных системах — chef/puppet/salt), тем более, если в нем (в конф файле) пришивается заголовок, что все ручные изменения файла будут перетерты. Но, к сожалению, SCM и пакетный менеджер иногда тоже устраивает драку за то, чьи правки более верные )


        1. Cenzo
          25.07.2019 03:53

          Ansible не решит части проблем, если при апдейте системы приползёт новый системный скрипт, который внезапно добавит или изменит конфиг, который до этого Ansible вообще не трогал. Но etcd/consul выглядит для конфигов более удобным, чем Ансибл, хотя проблемы остаются те же, все системные конфиги в него не запихаешь. (Как девелопер сейчас смотрю на эту кухню более со стороны)


    1. vin2809
      24.07.2019 08:28
      +1

      Вы еще, наверно, "математик-вычислитель" не видели...


      1. NetBUG
        24.07.2019 09:54

        Вычислитель — это же железяка, за которой работает математик?


  1. Gamliel_Fishkin
    24.07.2019 05:55

    update-initramfs: Generating /boot/initrd.img-4.15.0-54-generic
    Судя по номеру ядра, это Ubuntu 18.04 Bionic Beaver — в Debian 10.0.0 Buster ядро 4.19.


    1. amarao Автор
      24.07.2019 11:12

      Ага. Но пост как раз про дебиановскую подсистему, которая в убунте до сих пор основная (сколько бы они не пытались своё придумать).