Приведенные ниже инструкции предназначены для работы с CentOS 7, но их должно быть достаточно легко перенести в любой дистрибутив, на котором работает systemd. Все команды запускаются от имени пользователя root.
Убедитесь, что система находится в стабильном состоянии
Убедитесь, что никто не использует его, и ничего более важного не происходит. Вероятно, будет хорошей идеей прекратить предоставление сервисов, таких как httpd или ftpd, просто для того, чтобы внешние соединения не нарушали работу посередине.
systemctl stop httpd
systemctl stop nfs-server
# and so on....
Размонтировать все неиспользуемые файловые системы
umount -a
Это напечатает несколько предупреждений «Target is busy» для самого корневого тома и для различных временных / системных FS. Это может быть проигнорировано на данный момент. Важно то, что файловые системы на диске не остаются подключенными, кроме самой корневой файловой системы. Проверьте это:
# mount alone provides the info, but column makes it possible to read
mount | column -t
Если вы видите, что файловые системы на диске все еще смонтированы, значит, что-то еще работает, чего не должно быть. Проверьте, что он использует fuser
:
# if necessary:
yum install psmisc
# then:
fuser -vm <mountpoint>
systemctl stop <whatever>
umount -a
# repeat as required...
Сделать временный корень
mkdir /tmp/tmproot
mount -t tmpfs none /tmp/tmproot
mkdir /tmp/tmproot/{proc,sys,dev,run,usr,var,tmp,oldroot}
cp -ax /{bin,etc,mnt,sbin,lib,lib64} /tmp/tmproot/
cp -ax /usr/{bin,sbin,lib,lib64} /tmp/tmproot/usr/
cp -ax /var/{account,empty,lib,local,lock,nis,opt,preserve,run,spool,tmp,yp} /tmp/tmproot/var/
Это создает очень минимальную корневую систему, которая нарушает (среди прочего) просмотр man-страниц (нет /usr/share
), пользовательские настройки (нет /root
или /home
) и так далее. Это сделано намеренно, так как это поощрение не оставаться в такой фальсифицированной корневой системе больше, чем необходимо.
На этом этапе вы также должны убедиться, что установлено все необходимое программное обеспечение, так как оно также обязательно нарушит работу менеджера пакетов. Просмотрите все шаги и убедитесь, что у вас есть необходимые исполняемые файлы.
Поворот в корень
mount --make-rprivate / # necessary for pivot_root to work
pivot_root /tmp/tmproot /tmp/tmproot/oldroot
for i in dev proc sys run; do mount --move /oldroot/$i /$i; done
systemd заставляет монтирование разрешать совместное использование поддерева по умолчанию (как с mount --make-shared
), и это приводит pivot_root
к сбою. Следовательно, мы отключаем это глобально с mount --make-rprivate /
. Системные и временные файловые системы перемещаются оптом в новый корень. Это необходимо, чтобы заставить его работать вообще; сокеты для связи с systemd, между прочим, живут /run
, и поэтому нет способа заставить запущенные процессы закрыть его.
Убедитесь, что удаленный доступ пережил переход
systemctl restart sshd
systemctl status sshd
После перезапуска sshd убедитесь, что вы можете войти, открыв другой терминал и снова подключившись к машине через ssh. Если вы не можете исправить проблему, прежде чем двигаться дальше.
После того, как вы подтвердите, что вы можете подключиться снова, выйдите из оболочки, которую вы используете в данный момент, и снова подключитесь. Это позволяет оставшимся разветвленным sshd
выходам и гарантирует, что новый не держит /oldroot
.
Закройте все еще используя старый рут
fuser -vm /oldroot
Это напечатает список процессов, все еще удерживающих старый корневой каталог. В моей системе это выглядело так:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
root 1 ...e. systemd
root 549 ...e. systemd-journal
root 563 ...e. lvmetad
root 581 f..e. systemd-udevd
root 700 F..e. auditd
root 723 ...e. NetworkManager
root 727 ...e. irqbalance
root 730 F..e. tuned
root 736 ...e. smartd
root 737 F..e. rsyslogd
root 741 ...e. abrtd
chrony 742 ...e. chronyd
root 743 ...e. abrt-watch-log
libstoragemgmt 745 ...e. lsmd
root 746 ...e. systemd-logind
dbus 747 ...e. dbus-daemon
root 753 ..ce. atd
root 754 ...e. crond
root 770 ...e. agetty
polkitd 782 ...e. polkitd
root 1682 F.ce. master
postfix 1714 ..ce. qmgr
postfix 12658 ..ce. pickup
Вам нужно разобраться с каждым из этих процессов, прежде чем вы сможете размонтировать /oldroot
. Подход грубой силы просто kill $PID
для каждого, но это может сломать вещи. Чтобы сделать это более мягко:
systemctl | grep running
Это создает список запущенных сервисов. Вы должны быть в состоянии сопоставить это со списком процессов /oldroot
, выполняемых , а затем выполнить systemctl restart
для каждого из них. Некоторые службы отказываются входить во временный корень и переходить в состояние отказа; это на самом деле не имеет значения на данный момент.
Если корневой диск, размер которого вы хотите изменить, является диском LVM, вам также может потребоваться перезапустить некоторые другие работающие службы, даже если они не отображаются в списке, созданном fuser -vm /oldroot
. Если вы обнаружите, что не можете изменить размер диска LVM при выполнении шага 7, попробуйте systemctl restart systemd-udevd
.
Некоторые процессы не могут быть решены с помощью простых systemctl restart
. Для меня они включены auditd
(который не любит быть убитым через systemctl
, и поэтому просто хотел kill -15
). С ними можно разобраться индивидуально.
Последний процесс, который вы найдете, как правило, systemd
сам по себе. Для этого беги systemctl daemon-reexec
.
Как только вы закончите, таблица должна выглядеть так:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
Размонтировать старый рут
umount /oldroot
На этом этапе вы можете выполнять любые необходимые вам манипуляции. Первоначальный вопрос требовал простого resize2fs
вызова, но вы можете сделать все, что захотите; Еще один вариант использования - перенос корневой файловой системы из простого раздела в LVM / RAID / любой другой.
Поверните корень назад
mount <blockdev> /oldroot
mount --make-rprivate / # again
pivot_root /oldroot /oldroot/tmp/tmproot
for i in dev proc sys run; do mount --move /tmp/tmproot/$i /$i; done
Это прямое изменение шага 4.
Утилизировать временный корень
Повторите шаги 5 и 6, за исключением использования /tmp/tmproot
вместо /oldroot
. Затем:
umount /tmp/tmproot
rmdir /tmp/tmproot
Поскольку это tmpfs, в этот момент временный корень растворяется в эфире, и его больше никогда не увидеть.
Положите вещи на свои места
Снова смонтируйте файловые системы:
mount -a
На этом этапе вы также должны обновить /etc/fstab
и grub.cfg
в соответствии с любыми изменениями, которые вы сделали на шаге 7.
Перезапустите все неисправные службы:
systemctl | grep failed
systemctl restart <whatever>
Разрешить общие поддеревья снова:
mount --make-rshared /
Запустите остановленные сервисные единицы - вы можете использовать эту единственную команду:
systemctl isolate default.target
И вы сделали.
Большое спасибо Эндрю Вуду, который разработал эту эволюцию на RHEL4, и Стиву, который предоставил мне ссылку на первое.