Вопрос или проблема
Недавно я сломал свою систему, изменив файл конфигурации так, что пользователь root больше не мог войти в систему из-за сбоя PAM. Я не хотел выключать систему и вместо этого хотел перевести её в спящий режим, изменить файл конфигурации из initramfs, а затем возобновить работу.
Сказанное излишне, но, похоже, это возможно. Как я могу изменить файл на XFS (или любой) файловой системе, не монтируя или не повредив файловую систему, если она сейчас смонтирована в другом месте?
Для XFS можно использовать команду xfs_bmap
или xfs_bmap -v
, чтобы определить диапазоны блоков всех участков файла. У других файловых систем есть аналогичные команды. Я повредил свой файл /etc/security/limits.conf и получил такой вывод:
$ xfs_bmap -v /etc/security/limits.conf
/etc/security/limits.conf:
EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL
0: [0..7]: 391598456..391598463 3 (2529656..2529663) 8
Вывод указывает на то, что файл имеет длину до 8 блоков, начиная с блока 391598456. Мои блоки были длиной 512 байт, что я выяснил методом проб и ошибок с вероятными степенями двойки.
Таким образом, я могу увидеть содержимое своего файла с помощью:
# dd if=/dev/my/block/device bs=512 skip=391598456 count=7
Это считывает его непосредственно из блочного устройства, а не через драйвер файловой системы. Это работает нормально, если файловая система не смонтирована.
Я сделал резервную копию вывода xfs_bmap, а также содержимого файла, а затем изменил содержимое резервной копии, чтобы исправить повреждение, и сохранил это как новый файл.
Поскольку я не изменяю метаданные файловой системы, старый файл и восстановленный файл должны быть точно одинаковой длины:
$ ls -l limits.conf.*
-rw-rw-r--. 1 user user 2703 Dec 14 15:38 limits.conf.new
-rw-rw-r--. 1 user user 2703 Dec 14 15:38 limits.conf.old
-rw-rw-r--. 1 user user 171 Dec 14 15:37 limits.conf.xfs_bmap.txt
Видите, оба файла имеют длину 2703 байта.
Эти операции с файлами могут выполняться на работающей системе, или файловая система может быть смонтирована в режиме только для чтения (пока работает на одной системе) с другой системы. Однако, похоже, что XFS воспроизводит журнал по умолчанию, когда файловая система смонтирована в режиме только для чтения, поэтому, вероятно, возникнет небольшое повреждение файловой системы, если эти данные будут собраны с другой системы, если только воспроизведение журнала не отключено или как-то не подавляется. Может оказаться эффективным создать монтирование устройства в виде только для чтения, чтобы предотвратить записи в него. В этот раз я не исследовал отключение воспроизведения журнала сам.
Это была система на основе dracut, и я мог попасть в аварийную оболочку, несмотря на невозможность входа как root и на то, что система была в спящем режиме, добавив noresume rd.break=pre-mount
в командной строке ядра. Я работал с языковой моделью для помощи, но в итоге мне пришлось изучить исходные файлы dracut в /usr/lib/dracut/modules.d на работающей системе или /bin в initramfs, чтобы найти все параметры командной строки. Без noresume
rd.break=pre-mount
не повлияло бы.
В экстренной оболочке я мог бы подключить данные, используя смещения из вывода xfs_bmap. Чтобы уменьшить вероятность повреждения других данных, я сохранил необходимые значения в переменные оболочки:
OFFSET=391598456
BS=512
COUNT=7
Затем я могу проверить, что у меня правильные данные:
dd if=/dev/my/block/device bs=$BS count=$COUNT skip=$OFFSET
И записать новые данные обратно!
dd if=limits.conf.new of=/dev/my/block/device conv=notrunc bs=$BS count=$COUNT seek=$OFFSET
Важно правильно указать имена параметров skip
и seek
. Один предназначен для ввода, а другой для вывода. Я использую conv=notrunc
в качестве меры предосторожности, когда записываю часть данных в существующие данные, но, вероятно, невозможно усечь блочное устройство.
Вернувшись в работающую систему, старые данные все еще кэшируются и должны быть обновлены с диска. Я смог использовать dd iflag=direct
, чтобы сделать это:
dd iflag=direct if=/etc/security/limits.conf
И затем PAM перестал ломаться, и я смог снова использовать свою восстановленную систему, не выключая рабочий стол и не закрывая ни один из открытых документов.
Ответ или решение
Как безопасно модифицировать файл на файловой системе XFS, замонтированной на другой или засыпанной системе?
Каждый системный администратор или ИТ-специалист может столкнуться с задачей модификации конфигурационных файлов, когда стандартные методы доступа к системе недоступны. Проблема, о которой вы упомянули, касается изменения конфигурационного файла, что привело к невозможности входа в систему. Рассмотрим, как можно безопасно модифицировать файл на файловой системе XFS, который монтируется другой или засыпанной системой.
1. Оценка ситуации
Перед тем как начинать любые действия, необходимо понять текущее состояние системы:
- Файловая система XFS обладает журналированием, что обеспечивает целостность данных, но затрудняет прямые изменения при открытом доступе к файловой системе.
- Гибернация (или "сопение") может сохранить состояние системы, но существует риск повреждения данных при попытке их изменения.
2. Использование xfs_bmap
Первым шагом в процессе модификации файловой системы является идентификация блоков, связанных с целевым файлом. Для этого вы можете использовать команду xfs_bmap
. Она позволяет выяснить, какие блоки используются файлом:
xfs_bmap -v /etc/security/limits.conf
Эта команда выдаст информацию о диапазонах блоков (extent) для указанного файла.
3. Чтение данных
Чтобы прочитать содержимое файла на уровне блоков, используйте команду dd
. Это позволит избежать взаимодействия с файловой системой, минимизируя риск её повреждения:
dd if=/dev/my/block/device bs=512 skip=391598456 count=8
Здесь skip
указывает начальный блок, а count
— количество блоков для чтения.
4. Резервное копирование
Обязательно создайте резервные копии оригинального содержимого файла и результатов команды xfs_bmap
. Это действие позволит восстановить данные в случае неудачи.
5. Модификация данных
После получения данных вы сможете внести нужные изменения в безопасной среде. Создайте новый файл с исправленным содержимым и убедитесь, что его размер совпадает с размером оригинала. Это критически важно, так как изменение размера файла может повлечь за собой изменения в метаданных файловой системы:
ls -l limits.conf.*
Убедитесь, что размер оригинала и нового файла совпадает.
6. Запись измененных данных
Теперь, когда у вас есть исправленный файл, вы можете записать его обратно на место оригинала, следуя аналогичному принципу с использованием dd
:
dd if=limits.conf.new of=/dev/my/block/device conv=notrunc bs=512 seek=391598456
Здесь seek
указывает место для записи нового содержимого. Параметр conv=notrunc
гарантирует, что данные будут записаны без обрезки файла.
7. Обновление кэша
После изменения данных в занимемом месте важно обновить кэш файловой системы, чтобы система увидела изменения:
dd iflag=direct if=/etc/security/limits.conf
8. Вывод
После выполнения вышеописанных шагов вы сможете успешно восстановить доступ к системе без перезагрузки или возможности потерять открытые данные.
Заключение
Модификация файлов на монтированной файловой системе XFS — это задача, требующая внимательного подхода и понимания особенностей работы LINUX-систем. Соблюдение выше данной процедуры позволит избежать потери данных и вернет вашу систему в рабочее состояние.
Не забывайте, что каждое изменение данных на уровне блоков несет риски, и всегда полезно иметь актуальные резервные копии на случай непредвиденных ситуаций.