Le seguenti istruzioni sono concepite per funzionare con CentOS 7, ma dovrebbero essere facilmente trasferibili su qualsiasi distribuzione che esegua systemd. Tutti i comandi vengono eseguiti come root.
Assicurarsi che il sistema sia in uno stato stabile
Assicurati che nessun altro lo stia usando e che non stia succedendo niente di importante. È probabilmente una buona idea interrompere le unità che forniscono servizi come httpd o ftpd, solo per garantire che le connessioni esterne non interrompano le cose nel mezzo.
systemctl stop httpd
systemctl stop nfs-server
# and so on....
Smonta tutti i filesystem inutilizzati
umount -a
Ciò stamperà una serie di avvisi "Destinazione occupata", per il volume radice stesso e per vari FS temporanei / di sistema. Questi possono essere ignorati per il momento. Ciò che è importante è che nessun filesystem su disco rimanga montato, tranne il filesystem di root stesso. Verifica questo:
# mount alone provides the info, but column makes it possible to read
mount | column -t
Se vedi ancora dei filesystem su disco montati, qualcosa è ancora in esecuzione che non dovrebbe essere. Controlla cosa sta usando fuser
:
# if necessary:
yum install psmisc
# then:
fuser -vm <mountpoint>
systemctl stop <whatever>
umount -a
# repeat as required...
Crea la radice temporanea
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/
Questo crea un sistema di root molto minimale, che interrompe (tra le altre cose) la visualizzazione della manpage (no /usr/share
), le personalizzazioni a livello di utente (no /root
o /home
) e così via. Questo è intenzionale, in quanto costituisce un incoraggiamento a non rimanere in un sistema di root truccato dalla giuria più del necessario.
A questo punto dovresti anche assicurarti che tutto il software necessario sia installato, in quanto interromperà sicuramente il gestore dei pacchetti. Dai un'occhiata a tutti i passaggi e assicurati di disporre degli eseguibili necessari.
Pivot nella radice
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 fa sì che i montaggi consentano la condivisione delle sottostrutture per impostazione predefinita (come con mount --make-shared
) e ciò causa un pivot_root
errore. Quindi, lo disattiviamo a livello globale con mount --make-rprivate /
. I filesystem di sistema e temporanei vengono spostati all'ingrosso nella nuova radice. Questo è necessario per farlo funzionare affatto; le prese per la comunicazione con systemd, tra le altre cose, vivono /run
e quindi non c'è modo di far chiudere i processi in esecuzione.
Assicurarsi che l'accesso remoto sia sopravvissuto al passaggio all'euro
systemctl restart sshd
systemctl status sshd
Dopo aver riavviato sshd, assicurarsi di poter accedere, aprendo un altro terminale e connettendosi nuovamente alla macchina tramite ssh. Se non ci riesci, risolvi il problema prima di proseguire.
Dopo aver verificato, è possibile riconnettersi, uscire dalla shell attualmente in uso e riconnettersi. Ciò consente al rimanente biforcuto sshd
di uscire e garantisce che quello nuovo non trattiene /oldroot
.
Chiudi tutto ancora usando la vecchia radice
fuser -vm /oldroot
Verrà stampato un elenco di processi ancora presenti nella vecchia directory principale. Sul mio sistema, sembrava così:
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
È necessario gestire ciascuno di questi processi prima di poter smontare /oldroot
. L'approccio della forza bruta è semplicemente kill $PID
per ciascuno, ma questo può spezzare le cose. Per farlo più dolcemente:
systemctl | grep running
Questo crea un elenco di servizi in esecuzione. Dovresti essere in grado di correlarlo con l'elenco dei processi in attesa /oldroot
, quindi emettere systemctl restart
per ciascuno di essi. Alcuni servizi si rifiuteranno di entrare nella radice temporanea e di entrare in uno stato fallito; questi non contano davvero per il momento.
Se l'unità principale che si desidera ridimensionare è un'unità LVM, potrebbe essere necessario riavviare alcuni altri servizi in esecuzione, anche se non vengono visualizzati nell'elenco creato da fuser -vm /oldroot
. Se non riesci a ridimensionare un'unità LVM al punto 7, prova systemctl restart systemd-udevd
.
Alcuni processi non possono essere gestiti in modo semplice systemctl restart
. Per me questi inclusi auditd
(a cui non piace essere ucciso tramite systemctl
, e quindi volevo solo un kill -15
). Questi possono essere trattati individualmente.
L'ultimo processo che troverai, di solito, è systemd
se stesso. Per questo, corri systemctl daemon-reexec
.
Una volta terminato, la tabella dovrebbe apparire così:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
Smonta la vecchia radice
umount /oldroot
A questo punto, è possibile eseguire qualsiasi manipolazione richiesta. La domanda originale aveva bisogno di una semplice resize2fs
invocazione, ma puoi fare quello che vuoi qui; un altro caso d'uso è il trasferimento del filesystem di root da una semplice partizione a LVM / RAID / qualunque cosa.
Riporta indietro la radice
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
Questa è un'inversione semplice del passaggio 4.
Smaltire la radice temporanea
Ripetere i passaggi 5 e 6, ad eccezione dell'uso /tmp/tmproot
al posto di /oldroot
. Poi:
umount /tmp/tmproot
rmdir /tmp/tmproot
Essendo un tmpfs, a questo punto la radice temporanea si dissolve nell'etere, per non essere mai più vista.
Metti le cose al loro posto
Montare nuovamente i filesystem:
mount -a
A questo punto, è necessario anche aggiornare /etc/fstab
e grub.cfg
in conformità con eventuali modifiche apportate durante il passaggio 7.
Riavvia eventuali servizi non riusciti:
systemctl | grep failed
systemctl restart <whatever>
Consenti nuovamente sottotitoli condivisi:
mount --make-rshared /
Avviare le unità di servizio arrestate: è possibile utilizzare questo comando singolo:
systemctl isolate default.target
E hai finito.
Mille grazie a Andrew Wood, che ha elaborato questa evoluzione su RHEL4, e Steve, che mi ha fornito il collegamento con il primo.