Как безопасно размонтировать / var / usr на systemd без перезагрузки

У меня есть сервер Linux на виртуальной машине, при перезагрузке которого происходит отключение питания из-за неправильной настройки стороннего поставщика У меня нет доступа к конфигурации ВМ.

Человек, который установил систему, запутался в хранилище и безответственно смонтировал по одной точке для каждого каталога ( /var , /home , /usr и т. Д.), Что привело к тому, что у одних их стало легко, а у других – пусто.

Чтобы исправить этот беспорядок, я реорганизую точки монтирования, я смог управлять большинством из них, выполнив mount --bind / /mnt последующим rsync а затем перезапустив процесс, использующий их после umount .

Проблема в том, что /var и /usr используются самим процессом systemd init. systemd-remount-fs ли systemd-remount-fs ? Как я мог сделать это? Будет ли достаточно простого редактирования с помощью fstab за которым следует rsync ? Будет ли перезапущен все сервисы?

Я знаю, какие точки действительно требуют отдельных разделов для моего случая, и это не случай /var и /usr вообще.

Предполагается, что я не могу использовать umount -l как после перемонтирования мне придется уничтожить раздел, и я хотел бы избежать kexec поскольку не знаю, будет ли он иметь такой же kexec на этой неправильно настроенной виртуальной машине, что он не сможет поднимите это снова.

Я планирую создать сжатый раздел btrfs для /var/log и другой btrfs или xfs для /var/lib/docker , а также собрать все остальные вместе с минимально необходимым пространством, насколько это возможно, когда они будут почти статическими. И в будущем я могу поместить их как squashfs вместе с корневым и смонтировать overlayfs чтобы упростить обнаружение неправильной конфигурации. Я хотел бы иметь возможность делать все это без перезагрузки, хотя я не знаю, смогу ли я это сделать.

ВНИМАНИЕ: эти операции чрезвычайно рискованны, я не даю никаких гарантий по этому поводу, рекомендуется, чтобы вы понимали каждый шаг и применяли его на свой страх и риск, если вы этого не сделаете, вы, вероятно, сломаете свою систему, и я не несу ответственности за любые убытки, возникающие в результате его использования.

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

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

Мы могли бы воспользоваться этой возможностью, чтобы снова сменить корень, если в клонированной среде на другом диске будут сняты блокировки, которые система удерживает в более старой среде, так что вы можете безопасно смонтировать эти точки – фактически это в основном даже не будет установлен. Но эта клонированная среда должна гарантировать правильную конфигурацию, чтобы снова подключить сеть и предоставить доступ по ssh. Если это не так, считайте себя обреченным.

Важно, чтобы у вас был отдельный раздел: если вы выполняете привязку к каталогу внутри другого раздела, а не к самому устройству, система все еще может удерживать устройство родительского раздела, для этого случая использования следует учитывать, что он не блокирует какой-либо ,

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

Даже если у вас нет свободного дискового пространства и недостаточно памяти, вы все равно можете создать образ диска со сжатым разделом btrfs внутри точки монтирования памяти tmpfs , который позволит вам записать больше данных, чем обычно у вас есть в памяти. В этом случае будьте осторожны, когда раздел становится доступным только для чтения, если это случается, вероятно, голодает.

Важно отметить, что выполнение chroot внутри раздела памяти может привести к блокировке этой памяти в более старой среде, так что вы не сможете освободить ее без reboot или kexec .

После предоставления необходимых разделов для клонированной среды, вот как это будет работать:

 $ sudo mount /dev/clone_environment_device /mnt # mount other separate partitions if required $ sudo mkdir -p /mnt/mnt /mnt/dev /mnt/proc /mnt/sys /mnt/tmp /mnt/var/tmp /mnt/run $ sudo chmod 1777 /mnt/tmp /mnt/var/tmp $ sudo ln -s ../run /mnt/var/run $ sudo rsync -aAHXSv \ --exclude 'mnt' \ --exclude 'dev' \ --exclude 'run' \ --exclude 'sys' \ --exclude 'proc' \ --exclude 'tmp' \ --exclude 'var/tmp' \ / \ /mnt 

Важно настроить путь устройств и uuid ( blkid ), чтобы они соответствовали новым.

 $ sudo vi /mnt/etc/fstab $ sudo vi /mnt/etc/default/grub 

Затем, чтобы выполнить chroot:

 $ sudo mkdir /sysroot $ sudo mount --rbind /mnt /sysroot $ sudo touch /etc/initrd-release $ sudo systemctl --no-block isolate initrd-switch-root # it will stop all other services (isolate) and call systemctl switch-root /sysroot 

Обратите внимание, что связывать proc и dev не требуется, как вы это обычно делаете при выполнении chroot, systemd сделает это за вас. Вы можете потерять связь, если вы подождете некоторое время и все еще не сможете подключиться, у вас есть мои соболезнования, вы пропали даром.

Хотя, если вам повезло и вы смогли подключиться, не забудьте установить загрузчик для новой среды, чтобы в случае выключения сделать его снова:

 $ sudo grub2-install /dev/intended_bootable_disk $ sudo grub2-mkconfig -o /etc/grub2.cfg 

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

Помните, делайте это на свой страх и риск.