Поврежден XFS и нет пути к xfs_repair

У одного из моих серверов есть проблемы с XFS. после последнего сбоя некоторые из моих папок RRD были повреждены.

пример (извините, это по-французски):

# rm *
rm: impossible de supprimer « create_rrd.sh »: La structure a besoin d'un nettoyage
rm: impossible de supprimer « old »: est un dossier
rm: impossible de supprimer « tcgraph.log »: La structure a besoin d'un nettoyage
rm: impossible de supprimer « tcgraph.rrd »: La structure a besoin d'un nettoyage

Обычный шаг - перезапустить систему в режиме одного пользователя или использовать live cd и запустить xfs_repair в /dev/sda. К сожалению (это было бы слишком просто), хостинговая компания предоставляет возможность перезапустить на live cd, который не работает. И посещение центра обработки данных не вариант.

Кажется, что я вообще не могу дотронуться до inode, я получаю сообщение "структура нуждается в очистке" каждый раз.

Итак, вопрос: кто-нибудь знает способ восстановить / исправить эту файловую систему XFS вручную? Какой-нибудь низкоуровневый инструмент манипулирования XFS, который может помочь?

1 ответ

Решение

Краткий ответ: нет.

Более длинный ответ заключается в том, что было бы очень интересно попытаться скопировать все на виртуальный диск tmpfs, переключиться на него, затем размонтировать файловую систему с жестким диском и работать полностью от ram, пока вы восстанавливаете файловую систему диска.

Я не первый, кто подумал об этом, я нашел эту ветку, но не получил никакой информации о том, действительно ли эта схема работала. Так как целью было стереть диск, они не потрудились размонтировать его.

Для этого создайте каталог и mount -t tmpfs none /some/directory, затем начните заполнять его копией важных битов вашей системы (sshd, mount,umount, xfs tools, shell и всеми библиотеками, необходимыми для его запуска, вероятно, наверняка, всеми файлами / etc, и, наконец, init... здесь могут помочь скрипты создания chroot-джейла, как и наличие около 4 ГБ ОЗУ. Смонтируйте в нем копию proc и, если вы используете devfs, также смонтируйте копию devfs. Используя копию /etc/ssh/sshd_config, настройте sshd для запуска на другом порту. chroot на свой ramdisk и убедитесь, что все работает, и нет отсутствующих библиотек, затем запустите sshd на ramdisk (на альтернативном порту), чтобы он находился там. может подключиться к нему по ssh (для этого может потребоваться также скопировать туда каталог / home) (и открыть порт на любом брандмауэре, который у вас может быть).

Теперь волшебство начинается: вместо того, чтобы привязываться к этим tmpfs, вам нужно найти утилиту pivot_root. Его единственная цель в жизни - вызвать pivot_root(). Находится в util-linux на Debian. Целью pivot_root() является, по сути, синхронизация каждого процесса сразу. Первоначально использовался для перемещения / из образа виртуального диска initrd на реальный диск, если это работает, вы будете перемещаться / с фактического диска на образ виртуального диска. Итак, скажем, вы сделали mkdir /mnt/tmpfs; mount -t tmpfs none /mnt/tmpfs После копирования всего, что вам нужно, следующим шагом будет mkdir /mnt/tmpfs/oldroot; pivot_root /mnt/tmpfs /oldroot (Если вам не хватает места для копирования, размонтируйте / mnt / tmpfs и снова смонтируйте его, на этот раз с -o size=... поскольку по умолчанию разрешена только половина вашей памяти.)

Последний шаг - отключить / oldroot. Вам нужно размонтировать / oldroot / sysfs / oldroot / proc и т. Д. (Проверьте /proc/mounts). Если вы по-прежнему получаете "файловая система занята", вы можете попытаться форсировать ее или, по крайней мере, отследить все, что открыло файлы, посмотрев ls -l /proc/*/cwd /proc/*/fd/ | grep /oldroot/ и уничтожение всего, что по-прежнему ссылается на него (возможно, это относится и к серверу ssh, который не был привязан к chroot. Убедитесь, что вы вошли в этот альтернативный sshd, прежде чем начинать убивать объекты). Очевидно, не убивайте процесс 1 (init). Если вы не можете форсировать umount при запуске init, вам нужно использовать chroot /oldroot /sbin/telinit u2 (2 = уровень запуска, на котором вы находитесь в данный момент, или init, вероятно, убьет все, а затем вы перезагрузитесь и начнете сначала), чтобы получить init для "обновления", запустив "новый" init, который вы получили на виртуальном диске. Вам нужно будет выполнить chroot для / oldroot, чтобы использовать /oldroot/dev/initctl (ramdisk /dev/initctl не то же самое) (обратите внимание, что telinit будет использовать [/oldroot]/dev/initctl поговорить с существующим процессом init, который был pivot_rooted на виртуальный диск, поэтому процесс запуска, который он запускает, будет находиться на виртуальном диске, а не /oldroot).

Я не собираюсь пробовать это на производственном сервере здесь. Возможно я попробую это дома в эти выходные.

Другие вопросы по тегам