Невозможно перемонтировать / вернуться только для чтения после обновления пакета

13

Я использую Debian Stretch. Мой корневой раздел смонтирован read-only. Только когда я устанавливаю или обновляю пакеты, /перемонтируется read-write(с помощью apt hook), а затем перемонтируется обратно ro.

Иногда после обновления пакета я не могу перемонтировать /обратно только для чтения:

mount -o remount,ro /
mount: / is busy

В старых версиях Debian (Wheezy) я мог перечислить открытые файлы, которые не были связаны с lsof:

 lsof +L1

или, более конкретно, файлы, которые препятствуют /повторному подключению к ro:

{ lsof +L1 ; lsof|sed -n '/SYSV/d; /DEL|(path /p;' ; } | grep -Ev '/(dev|home|tmp|var)'

Тем не менее, в Debian Stretch lsof +L1не перечисляются никакие файлы.

Я не вижу каких - либо изменений +|-Lв man lsofтом , что бы объяснить , почему он перестал работать.

Почему lsof + L1 больше не выводит список открытых файлов, которые не были связаны?

Как я могу перечислить те файлы, которые предотвращают / не могут быть перемонтированы только для чтения?

ОБНОВИТЬ

Я остановил все процессы, которые можно остановить, и только они есть initи gettyработают, но я все еще не могу перемонтировать /их ro.

Мартин Вегтер
источник
Не связанные открытые файлы - не единственное препятствие. Ищите wили uв FDстолбце lsofвыходных данных, или для Fв выходных данных fuser -vm /, например. Я не могу дать вам исчерпывающий список. Вы также можете установить пакет needrestart .
Ференц Вагнер
глупый вопрос но ты исполняешь lsof как root?
Киви
1
Kiwy - да, я запускаю lsof от имени root.
Мартин Вегтер,
1
не fuser -m / говорит что использует root?
Руи Ф. Рибейро,
1
@Marcus Linsner - я не использую systemd. Я использую init.
Мартин Вегтер,

Ответы:

2

Как я могу перечислить те файлы, которые предотвращают / не могут быть перемонтированы только для чтения?

А) fuserможно найти в psmiscупаковке; это случай использования, где я нахожу fuserсияние и более полезным, чем lsof.

# fuser -v -m / 2>&1 | grep '[Ff]r.e'

Это покажет все процессы, в которых есть файлы, открытые для чтения (f) и записи (F). Файлы, которые препятствуют / не могут быть перемонтированы в режим только для чтения, - это файлы, которые открыты для записи (F).

Убейте процессы, которые являются исполняемыми файлами, запускаемыми с файлами корневого каталога, открытыми для записи ., Т.е.

# for fupid in $(fuser -v -m / 2>&1 | grep Fr.e | awk '{print $2}'); do kill $fupid; done

Это выше systemdкомментариев с оговоркой. Если systemdесть, initто fuserувидим это и есть другие соображения. При systemdзапуске он может (пере) запускать процессы за вашей спиной, даже если они только что были идентифицированы и уничтожены fuser. systemdгораздо более продвинутый, чем традиционный sysvinit.

Б) ОБНОВЛЕНИЕ в описании утверждает, что система имеет только ... initи gettyвсе еще работает ...

Я вижу комментарий, который говорит, что система не использует systemd, она использует init. На участке systemd есть init . В комментарии явно не сказано sysvinit, поэтому я предполагаю, что рассматриваемая система может использовать растяжение systemdпо умолчанию для init. Или что другие люди, которые наткнулись на этот пост, которые используют стрейч systemd, находят эту часть полезной.

Согласно вики Debian ,

Процесс инициализации системы обрабатывается демоном init. В squeeze и более ранних выпусках этот демон предоставляется пакетом sysvinit, и никакие альтернативы не поддерживаются. В wheezy по умолчанию демон init все еще работаетsysvinit , но доступен «предварительный просмотр технологии» systemd. В jessie и stretch по умолчанию используется система инициализацииsystemd , но поддерживается переключение на sysvinit.

Начиная с Джесси, полностью поддерживается только systemd; sysvinit в основном поддерживается, но пакеты Debian не обязаны предоставлять сценарии запуска sysvinit. runit также упакован, но не получил того же уровня тестирования и поддержки, что и другие, и в настоящее время не поддерживается как PID 1.

При systemdзапуске есть несколько дополнительных шагов, которые необходимо предпринять, чтобы освободить / перемонтировать их без проблем.

Скорее всего, system.sliceон содержит открытые файлы для systemd-journald.serviceили systemd-udevd.service(оба из которых имеют зависимости сокетов). Или, если NetworkManagerон запущен, он может перезапустить, dhclientкоторый записывает аренды в / var / ... (& / var / не всегда является его собственным устройством), и т. Д. fuserМожет найти и вы убьете, dhclientно NetworkManagerзапустит его снова.

Мораль в том, что многие вещи автоматизированы, которые могут «хотеть» / (и даже более того systemd).

Чтобы быть уверенным, если это возможно, systemdэквивалент уровня выполнения 1 соответствует rescue.targetrunlevel1.targetявляется символической ссылкой на rescue.target).

1) Начните с изоляции системы до rescue.target

# systemctl isolate rescue.target

Это должно побудить вас ввести пароль root; следуйте инструкциям на экране.

2) В спасательной оболочке узнайте, что хочет /.

# systemctl show -p Wants /

Как правило, это system.slice; остановить все, что хочет /. например

# systemctl stop system.slice

3) На данный момент, перемонтирование не должно сообщаться mount: / is busyи mount -o remount,ro / должно работать. Если нет, проверьте снова с fuser.

4) FWIW; Я также видел случаи, когда происходит umountсбой, когда / если другое устройство монтируется в подкаталог другого монтирования, то есть во вложенные монтирования. Например, umount /произойдет сбой, если / var / или / boot / находится на другом устройстве (и смонтировано). Хотя mount -o remount,ro /все равно должно работать в этом случае.

lsblk может быть полезно для визуализации вложенных монтировок.

Почему lsof + L1 больше не выводит список открытых файлов, которые не были связаны?

Поскольку они недоступны (сокеты или большинство FIFO и каналов), они больше не являются открытыми файлами (родительский процесс закрыл дескриптор файла) или у них (по-прежнему) количество ссылок больше 1.

man lsof (8) подробнее ...

+ | -L [l]

Эта опция включает ('+') или отключает ('-') перечисление количества ссылок на файлы, где они доступны - например, они недоступны для сокетов или большинства FIFO и каналов.

Если + L указан без следующего номера, будут перечислены все количества ссылок. Если указан -L (по умолчанию), количество ссылок не будет отображаться.

Если после + L следует число, в списке будут отображаться только файлы с числом ссылок меньше этого числа . (Никакое число не может следовать за -L.) Спецификация формы '' + L1 '' выберет открытые файлы, которые не были связаны. Спецификация формы +aL1 <file_system>будет выбирать несвязанные открытые файлы в указанной файловой системе.

Джозеф Тингирис
источник
0

Вы /procустановили?

По-видимому, будучи тем, кто /большую часть времени заботится о том, чтобы монтировать его только для чтения, я могу себе представить, что вы также можете не монтировать procfs. Но для этого нужно lsofнайти открытые файлы.

Файлы, открытые процессами, открываются ядром через символические ссылки в procfs. Каталоги /proc/<pid>/fdсодержат символическую ссылку для каждого открытого файла. Имя символических ссылок - это номера дескрипторов файлов, а путь, на который ссылается символическая ссылка, - это путь к файлу.

Висячие символические ссылки все еще остаются /procдля открытых файлов, которые уже удалены. И указанный путь к файлу переименовывается в конец (удалено).

Что lsof +L1, по сути, ничем не отличается от быстрого однострочного:

stat -c%N /proc/[0-9]*/fd/* | grep deleted

Таким образом, вы можете использовать похожую однострочную, чтобы перечислить все открытых файлов, которые могут помешать перемонтированию корневой файловой системы (при условии работы /proc).

Однако, если вы сделали / сделали /procмонтирование, единственные другие причины, о которых я могу думать, это ошибки ... В любом случае, к вашему сведению, в моей нынешней системе Debian Stretch. lsof +L1работает как положено.

bash# lsb_release -d
Description:    Debian GNU/Linux 9.5 (stretch)

bash# uname -a
Linux bwp-249-8 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u4 (2018-08-21) x86_64 GNU/Linux

bash# lsof -v
lsof version information:
    revision: 4.89
    [...]
Hkoof
источник
да, я /procсмонтировал Я не слежу за твоими рассуждениями, почему у меня их не было. В любом случае, stat -c%N /proc/[0-9]*/fd/* | grep deletedничего не показывает мне.
Мартин Вегтер
0

Я мог воспроизвести эту проблему только один раз, и решил ее, просто используя mountс -n опцией.

Цитирую man mount :

-n, --no-mtab
      Mount without writing in /etc/mtab.  This is necessary for example when /etc is on a read-only filesystem.

Сама mountпрограмма, открывающая файл (ы) для записи в корневой файловой системе, звучала для меня как правдоподобное объяснение. Конкретно mountпишет /etc/mtabведь и/etc часто является частью корневой файловой системы. Однако я не мог воспроизвести это снова на той же машине после того, как я сделал это однажды ...

Может ли это решить вашу проблему?

Hkoof
источник
нет, использование -nс mount не имеет значения.
Мартин Вегтер
0

Без видимости вашей системы очень сложно точно сказать, в чем проблема. Комментарии и предыдущие ответы - хорошее начало.

Тем не менее, я бы прошел весь путь через вики Debian, в которой описаны prereq для монтирования / только для чтения.

Ссылка на документацию находится здесь: https://wiki.debian.org/ReadonlyRoot

Большой, я проведу тебя через здесь:

1 - есть определенные места в /, которые должны быть прочитаны и записаны. На основании документации это выглядит примерно так:

Debian Ro root

Ваши блочные устройства, вероятно, будут другими, в зависимости от конфигурации стека хранения (разделов, lvm без разделов и т. д.), но основная идея заключается в том, что вам нужны эти 4 точки монтирования, чтобы их последующая смонтированная файловая система имела опцию монтирования RW.

2 - в / etc есть несколько специальных файлов, для которых вам нужно либо создать символическую ссылку, либо внести некоторые другие изменения (подробно описано в связанной статье). Они могут или не могут применяться в зависимости от того, какие приложения работает ваш сервер Linux. некоторые файлы могут даже не существовать на вашем компьютере, но я включил все в документы. Имейте в виду, я настоятельно рекомендую вносить эти изменения, даже если вы убили pid процесса. Вот пути непосредственно из вики Debian:

  • adjtime
  • init.d / ALSA-Utils
  • / И т.д. / курьером / общий / индекс
  • любые файлы состояния чашек, classes.conf, cupsd.conf, printers.conf subscription.conf
  • /etc/lvm/lvm.conf
  • mtab (который, похоже, вы пытались решить, установив флаг -n для mount)
  • network / run (используется ifup и ifdown, в squeeze. может не применяться к растяжке, ymmv)
  • NOLOGIN
  • resolv.conf
  • как passwd, так и shadow файлы
  • самба / dhcp.conf
  • сосать
  • Udev

После того, как вы проверили все вышеперечисленное и подтвердили, что они соответствуют спецификации в вики, следующая вещь, которую нужно проверить, это /etc/apt/apt.conf

DPkg {
// Auto re-mounting of a readonly /
Pre-Invoke { "mount -o remount,rw /"; };
Post-Invoke { "test ${NO_APT_REMOUNT:-no} = yes || mount -o remount,ro / || true"; };
}; 

на основании вашей ошибки последнее, что вы можете проверить на основании документации, приведено ниже:

«После обновления пакетов вы можете столкнуться с проблемой, при которой mount отказывается перемонтировать файловую систему, сообщая вам только« / is busy ». Это вызвано тем, что удаленные файлы все еще используются процессом. Чтобы выяснить, какие процессы используют удаленные файлы, используйте инструмент checkrestart (1) из пакета debian-goodies или используйте следующую команду. Часто это демоны, использующие обновленные библиотеки. нужно перезапустить их, чтобы файлы были освобождены. "

Команда предоставлена ​​в док .:

{lsof +L1; lsof|sed -n '/SYSV/d; /DEL\|(path /p;'} |grep -Ev '/(dev|home|tmp|var)'

Не зная вашей точной конфигурации файловой системы, разбиения на разделы и конфигурации устройства хранения, трудно дать вам что-то еще. Я бы начал с возвращения и перепроверки ваших предварительных требований в документации (и обрисованной в общих чертах выше).

frontsidebus
источник