Las instrucciones a continuación están diseñadas para funcionar con CentOS 7, pero deberían ser fácilmente transferibles a cualquier distribución que ejecute systemd. Todos los comandos se ejecutan como root.
Asegúrese de que el sistema esté en un estado estable
Asegúrese de que nadie más lo esté usando y que nada más importante esté sucediendo. Probablemente sea una buena idea detener las unidades que brindan servicios como httpd o ftpd, solo para asegurarse de que las conexiones externas no interrumpan las cosas en el medio.
systemctl stop httpd
systemctl stop nfs-server
# and so on....
Desmontar todos los sistemas de archivos no utilizados
umount -a
Esto imprimirá una serie de advertencias de 'El destino está ocupado', para el volumen raíz en sí y para varios FS temporales / del sistema. Estos pueden ser ignorados por el momento. Lo importante es que no quedan montados los sistemas de archivos en el disco, excepto el sistema de archivos raíz en sí. Verifica esto:
# mount alone provides the info, but column makes it possible to read
mount | column -t
Si ve algún sistema de archivos en el disco todavía montado, entonces todavía se está ejecutando algo que no debería. Comprueba lo que está usando fuser
:
# if necessary:
yum install psmisc
# then:
fuser -vm <mountpoint>
systemctl stop <whatever>
umount -a
# repeat as required...
Haz la raíz temporal
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/
Esto crea un sistema raíz muy mínimo, que interrumpe (entre otras cosas) la visualización de la página de manual (no /usr/share
), las personalizaciones a nivel de usuario (no /root
o /home
), etc. Esto es intencional, ya que constituye un estímulo para no permanecer en un sistema raíz tan manipulado por el jurado más de lo necesario.
En este punto, también debe asegurarse de que esté instalado todo el software necesario, ya que seguramente romperá el administrador de paquetes. Eche un vistazo a todos los pasos y asegúrese de tener los ejecutables necesarios.
Pivotar en la raíz
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 hace que los montajes permitan compartir subárbol de manera predeterminada (como con mount --make-shared
), y esto hace pivot_root
que falle. Por lo tanto, desactivamos esto globalmente con mount --make-rprivate /
. El sistema y los sistemas de archivos temporales se trasladan al por mayor a la nueva raíz. Esto es necesario para que funcione; los sockets para la comunicación con systemd, entre otras cosas, viven /run
, por lo que no hay forma de hacer que los procesos en ejecución lo cierren.
Asegúrese de que el acceso remoto haya sobrevivido al cambio
systemctl restart sshd
systemctl status sshd
Después de reiniciar sshd, asegúrese de poder ingresar abriendo otro terminal y conectándose nuevamente a la máquina a través de ssh. Si no puede, solucione el problema antes de continuar.
Una vez que haya verificado que puede conectarse nuevamente, salga del shell que está utilizando actualmente y vuelva a conectarse. Esto permite que la bifurcación restante sshd
salga y garantiza que la nueva no se mantenga /oldroot
.
Cierra todo lo que sigue usando la raíz antigua
fuser -vm /oldroot
Esto imprimirá una lista de procesos que aún se mantienen en el antiguo directorio raíz. En mi sistema, se veía así:
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
Debe lidiar con cada uno de estos procesos antes de poder desmontar /oldroot
. El enfoque de fuerza bruta es simplemente kill $PID
para cada uno, pero esto puede romper las cosas. Para hacerlo más suavemente:
systemctl | grep running
Esto crea una lista de servicios en ejecución. Debería poder correlacionar esto con la lista de procesos en espera /oldroot
, luego emitir systemctl restart
para cada uno de ellos. Algunos servicios se negarán a aparecer en la raíz temporal y entrarán en un estado fallido; estos realmente no importan por el momento.
Si la unidad raíz que desea cambiar de tamaño es una unidad LVM, es posible que también deba reiniciar algunos otros servicios en ejecución, incluso si no aparecen en la lista creada por fuser -vm /oldroot
. Si encuentra que no puede cambiar el tamaño de una unidad LVM en el Paso 7, intente systemctl restart systemd-udevd
.
Algunos procesos no pueden tratarse de manera simple systemctl restart
. Para mí estos incluidos auditd
(que no le gusta que lo maten a través de systemctl
, por lo que solo quería un kill -15
). Estos pueden ser tratados individualmente.
El último proceso que encontrarás, por lo general, es en systemd
sí mismo. Para esto, corre systemctl daemon-reexec
.
Una vez que haya terminado, la tabla debería verse así:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
Desmontar la antigua raíz
umount /oldroot
En este punto, puede realizar cualquier manipulación que requiera. La pregunta original necesitaba una resize2fs
invocación simple , pero puede hacer lo que quiera aquí; otro caso de uso es transferir el sistema de archivos raíz de una partición simple a LVM / RAID / lo que sea.
Gire la raíz hacia atrás
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
Esta es una inversión directa del paso 4.
Deseche la raíz temporal
Repita los pasos 5 y 6, excepto usar /tmp/tmproot
en lugar de /oldroot
. Entonces:
umount /tmp/tmproot
rmdir /tmp/tmproot
Como se trata de un tmpfs, en este punto, la raíz temporal se disuelve en el éter, para nunca volver a verse.
Poner las cosas nuevamente en sus lugares.
Montar sistemas de archivos nuevamente:
mount -a
En este punto, también debe actualizar /etc/fstab
y grub.cfg
de acuerdo con los ajustes que realizó durante el paso 7.
Reinicie los servicios fallidos:
systemctl | grep failed
systemctl restart <whatever>
Permitir subárboles compartidos nuevamente:
mount --make-rshared /
Inicie las unidades de servicio detenidas; puede usar este comando único:
systemctl isolate default.target
Y tu estas listo.
Muchas gracias a Andrew Wood, quien resolvió esta evolución en RHEL4, y Steve, que me proporcionó el enlace a la primera.