Mi ritrovo a dover riorganizzare le partizioni di un sistema per spostare i dati precedentemente sotto il filesystem di root in punti di montaggio dedicati. I volumi sono tutti in LVM, quindi è relativamente facile:creare nuovi volumi, spostarvi i dati, ridurre il filesystem di root, quindi montare i nuovi volumi nei punti appropriati.
Il problema è il passaggio 3, la riduzione del filesystem di root. I filesystem coinvolti sono ext4, quindi è supportato il ridimensionamento online; tuttavia, mentre sono montati, i filesystem possono solo essere cresciuti. Per ridurre la partizione è necessario smontarla, cosa che ovviamente non è possibile per la partizione di root durante il normale funzionamento.
Le risposte sul Web sembrano ruotare attorno all'avvio di un LiveCD o di un altro supporto di ripristino, all'esecuzione dell'operazione di compattazione, quindi al riavvio nel sistema installato. Tuttavia, il sistema in questione è remoto e ho accesso solo tramite SSH. Posso riavviare, ma non è possibile avviare un disco di ripristino ed eseguire operazioni dalla console.
Come posso smontare il filesystem di root mantenendo l'accesso alla shell remota?
Risposta accettata:
Per risolvere questo problema, le informazioni fornite su http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtml sono state fondamentali. Tuttavia, quella guida è per una versione molto vecchia di RHEL e varie informazioni erano obsolete.
Le istruzioni seguenti sono realizzate per funzionare con CentOS 7, ma dovrebbero essere facilmente trasferibili a qualsiasi distribuzione che esegue systemd. Tutti i comandi vengono eseguiti come root.
-
Assicurati che il sistema sia in uno stato stabile
Assicurati che nessun altro lo stia usando e che non stia succedendo nient'altro 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
Questo stamperà una serie di avvisi "Target is busy", per il volume di root stesso e per vari FS temporanei/di sistema. Questi possono essere ignorati per il momento. L'importante è che nessun filesystem su disco rimanga montato, ad eccezione del filesystem di root stesso. Verifica questo:
# mount alone provides the info, but column makes it possible to read mount | column -t
Se vedi dei filesystem su disco ancora montati, allora 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 (nessun
/usr/share
), personalizzazioni a livello di utente (nessun/root
o/home
) e così via. Questo è intenzionale, in quanto costituisce un incoraggiamento a non rimanere in un tale sistema di root truccato dalla giuria più del necessario.A questo punto dovresti anche assicurarti che tutto il software necessario sia installato, poiché sicuramente interromperà anche il gestore di pacchetti. Dai un'occhiata a tutti i passaggi e assicurati di avere gli 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 in modo che i mount consentano la condivisione di sottoalbero per impostazione predefinita (come con
mount --make-shared
), e questo provocapivot_root
fallire. Quindi, lo disattiviamo a livello globale conmount --make-rprivate /
. I filesystem di sistema e temporanei vengono spostati all'ingrosso nella nuova radice. Questo è necessario per farlo funzionare; i socket per la comunicazione con systemd, tra le altre cose, vivono in/run
, quindi non c'è modo di chiuderlo con i processi in esecuzione. -
Assicurati che l'accesso remoto sia sopravvissuto al passaggio
systemctl restart sshd systemctl status sshd
Dopo aver riavviato sshd, assicurati di poter entrare, aprendo un altro terminale e connettendoti nuovamente alla macchina tramite ssh. Se non puoi, risolvi il problema prima di andare avanti.
Dopo aver verificato puoi connetterti di nuovo, esci dalla shell che stai attualmente utilizzando e riconnettiti. Ciò consente il rimanente
sshd
biforcato per uscire e assicura che quello nuovo non contenga/oldroot
. -
Chiudi tutto ancora usando la vecchia radice
fuser -vm /oldroot
Questo stamperà un elenco di processi ancora conservati 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
Devi occuparti di ciascuno di questi processi prima di poter smontare
/oldroot
. L'approccio della forza bruta è semplicementekill $PID
per ciascuno, ma questo può rompere le cose. Per farlo più dolcemente:systemctl | grep running
Questo crea un elenco di servizi in esecuzione. Dovresti essere in grado di correlare questo con l'elenco dei processi che contengono
/oldroot
, quindi emettisystemctl restart
per ciascuno di essi. Alcuni servizi si rifiuteranno di accedere alla radice temporanea ed entreranno in uno stato di errore; questi non contano davvero per il momento.Se l'unità di root che desideri ridimensionare è un'unità LVM, potrebbe essere necessario riavviare anche altri servizi in esecuzione, anche se non vengono visualizzati nell'elenco creato da
fuser -vm /oldroot
. Se non riesci a ridimensionare un'unità LVM nel passaggio 7, provasystemctl restart systemd-udevd
.Alcuni processi non possono essere gestiti tramite il semplice
systemctl restart
. Per me questi includevanoauditd
(che non ama essere ucciso tramitesystemctl
, e quindi volevo solo unkill -15
). Questi possono essere gestiti individualmente.L'ultimo processo che troverai, di solito, è
systemd
si. Per questo, eseguisystemctl daemon-reexec
.Al termine, la tabella dovrebbe apparire così:
USER PID ACCESS COMMAND /oldroot: root kernel mount /oldroot
-
Smonta la vecchia radice
umount /oldroot
A questo punto, puoi eseguire tutte le manipolazioni di cui hai bisogno. La domanda originale richiedeva un semplice
resize2fs
invocazione, ma qui puoi fare quello che vuoi; un altro caso d'uso è il trasferimento del filesystem di root da una semplice partizione a LVM/RAID/qualunque cosa. -
Ruota 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 è una semplice inversione del passaggio 4.
-
Smaltire la radice temporanea
Ripeti i passaggi 5 e 6, tranne per l'utilizzo di
/tmp/tmproot
al posto di/oldroot
. Quindi:umount /tmp/tmproot rmdir /tmp/tmproot
Trattandosi di un tmpfs, a questo punto la radice temporanea si dissolve nell'etere, per non essere più vista.
-
Rimetti le cose al loro posto
Monta di nuovo i filesystem:
mount -a
A questo punto, dovresti anche aggiornare
/etc/fstab
egrub.cfg
in base alle eventuali modifiche apportate durante il passaggio 7.Riavvia tutti i servizi non riusciti:
systemctl | grep failed systemctl restart <whatever>
Consenti nuovamente i sottoalberi condivisi:
mount --make-rshared /
Avvia le unità di servizio interrotte:puoi utilizzare questo singolo comando:
systemctl isolate default.target
E il gioco è fatto.
Correlati:non riesco a installare il centro software su Kali?Mille grazie a Andrew Wood, che ha elaborato questa evoluzione su RHEL4, e Steve, che mi ha fornito il collegamento alla prima.