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

Вопрос или проблема

Недавно я сломал свою систему, изменив файл конфигурации так, что пользователь 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-систем. Соблюдение выше данной процедуры позволит избежать потери данных и вернет вашу систему в рабочее состояние.

Не забывайте, что каждое изменение данных на уровне блоков несет риски, и всегда полезно иметь актуальные резервные копии на случай непредвиденных ситуаций.

Оцените материал
Добавить комментарий

Капча загружается...