Zjistil jsem, že potřebuji změnit uspořádání systémových oddílů, aby se data dříve pod kořenovým souborovým systémem přesunula do vyhrazených přípojných bodů. Všechny svazky jsou v LVM, takže je to relativně snadné:vytvořte nové svazky, přesuňte do nich data, zmenšete kořenový souborový systém a poté připojte nové svazky na vhodná místa.
Problémem je krok 3, zmenšení kořenového souborového systému. Zapojené souborové systémy jsou ext4, takže je podporována online změna velikosti; avšak při připojení lze souborové systémy pouze rozšiřovat. Zmenšení oddílu vyžaduje jeho odpojení, což samozřejmě není možné pro kořenový oddíl v normálním provozu.
Zdá se, že odpovědi na webu se točí kolem zavedení LiveCD nebo jiného záchranného média, provedení operace zmenšení a následného zavedení zpět do nainstalovaného systému. Dotyčný systém je však vzdálený a já mám přístup pouze přes SSH. Mohu restartovat, ale zavedení záchranného disku a provádění operací z konzoly není možné.
Jak mohu odpojit kořenový souborový systém při zachování vzdáleného přístupu k shellu?
Přijatá odpověď:
Při řešení tohoto problému byly klíčové informace uvedené na http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtml. Tato příručka je však pro velmi starou verzi RHEL a různé informace byly zastaralé.
Níže uvedené pokyny jsou vytvořeny pro práci s CentOS 7, ale měly by být snadno přenositelné do jakékoli distribuce, která běží systemd. Všechny příkazy jsou spouštěny jako root.
-
Ujistěte se, že je systém ve stabilním stavu
Ujistěte se, že jej nepoužívá nikdo jiný a že se neděje nic jiného důležitého. Pravděpodobně je dobré zastavit jednotky poskytující služby, jako je httpd nebo ftpd, jen aby se zajistilo, že externí připojení nenaruší věci uprostřed.
systemctl stop httpd systemctl stop nfs-server # and so on....
-
Odpojte všechny nepoužívané souborové systémy
umount -a
Tím se vytiskne řada varování „Cíl je zaneprázdněn“ pro samotný kořenový svazek a pro různé dočasné/systémové FS. Ty lze prozatím ignorovat. Důležité je, že nezůstávají připojené žádné souborové systémy na disku, kromě samotného kořenového souborového systému. Ověřte toto:
# mount alone provides the info, but column makes it possible to read mount | column -t
Pokud vidíte, že jsou nějaké souborové systémy na disku stále připojeny, pak stále běží něco, co by nemělo být. Zkontrolujte, co to je, pomocí
fuser
:# if necessary: yum install psmisc # then: fuser -vm <mountpoint> systemctl stop <whatever> umount -a # repeat as required...
-
Vytvořte dočasný kořen
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/
To vytváří velmi minimální kořenový systém, který narušuje (mimo jiné) prohlížení manuálové stránky (žádné
/usr/share
), přizpůsobení na úrovni uživatele (bez/root
nebo/home
) a tak dále. Je to záměrné, protože to představuje povzbuzení, abyste nezůstávali v takto porotou zmanipulovaném kořenovém systému déle, než je nutné.V tomto okamžiku byste se měli také ujistit, že je nainstalován veškerý potřebný software, protože to také jistě naruší správce balíčků. Prohlédněte si všechny kroky a ujistěte se, že máte potřebné spustitelné soubory.
-
Otočte do kořenového adresáře
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 způsobí, že připojení ve výchozím nastavení umožňují sdílení podstromu (jako u
mount --make-shared
), a to způsobípivot_root
neuspět. Proto to globálně vypneme pomocímount --make-rprivate /
. Systémové a dočasné souborové systémy jsou hromadně přesunuty do nového kořenového adresáře. To je nutné, aby to vůbec fungovalo; zásuvky pro komunikaci se systemd mimo jiné žijí v/run
, a tak neexistuje způsob, jak to běžící procesy zavřít. -
Zajistěte, aby vzdálený přístup přežil přechod
systemctl restart sshd systemctl status sshd
Po restartování sshd se ujistěte, že se můžete dostat dovnitř otevřením jiného terminálu a opětovným připojením k počítači přes ssh. Pokud nemůžete, opravte problém, než budete pokračovat.
Jakmile ověříte, že se můžete znovu připojit, opusťte shell, který právě používáte, a znovu se připojte. To umožňuje zbývající rozvětvený
sshd
ukončit a zajistit, aby nový neobsahoval/oldroot
. -
Zavřete vše, co stále používá starý kořen
fuser -vm /oldroot
Tím se vytiskne seznam procesů, které stále zůstávají ve starém kořenovém adresáři. V mém systému to vypadalo takto:
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
Než budete moci odpojit
/oldroot
, musíte se vypořádat s každým z těchto procesů . Přístup hrubou silou je jednodušekill $PID
pro každého, ale to může věci rozbít. Chcete-li to provést jemněji:systemctl | grep running
Tím se vytvoří seznam spuštěných služeb. Měli byste to dát do souvislosti se seznamem procesů obsahujících
/oldroot
, poté proveďtesystemctl restart
pro každého z nich. Některé služby se odmítnou objevit v dočasném kořenovém adresáři a přejdou do stavu selhání; na tom v tuto chvíli opravdu nezáleží.Pokud je kořenový disk, jehož velikost chcete změnit, disk LVM, možná budete muset restartovat také některé další spuštěné služby, i když se nezobrazují v seznamu vytvořeném
fuser -vm /oldroot
. Pokud zjistíte, že podle kroku 7 nemůžete změnit velikost disku LVM, zkustesystemctl restart systemd-udevd
.Některé procesy nelze vyřešit pomocí jednoduchého
systemctl restart
. Pro mě to zahrnovaloauditd
(který nemá rád, když je zabit přessystemctl
, a tak jsem chtěl jenkill -15
). Lze je řešit individuálně.Poslední proces, který obvykle najdete, je
systemd
sám. Za tímto účelem spusťtesystemctl daemon-reexec
.Až budete hotovi, tabulka by měla vypadat takto:
USER PID ACCESS COMMAND /oldroot: root kernel mount /oldroot
-
Odpojte starý kořen
umount /oldroot
V tomto okamžiku můžete provádět jakékoli požadované manipulace. Původní otázka potřebovala jednoduchý
resize2fs
vyvolání, ale zde si můžete dělat, co chcete; dalším případem použití je přenos kořenového souborového systému z jednoduchého oddílu do LVM/RAID/cokoli. -
Otočte kořen zpět
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
Toto je přímé obrácení kroku 4.
-
Zlikvidujte dočasný kořen
Opakujte kroky 5 a 6, kromě použití
/tmp/tmproot
místo/oldroot
. Potom:umount /tmp/tmproot rmdir /tmp/tmproot
Protože je to tmpfs, v tomto okamžiku se dočasný kořen rozpustí v éteru a už ho nikdy neuvidíme.
-
Vraťte věci na jejich místa
Znovu připojte souborové systémy:
mount -a
V tomto okamžiku byste také měli aktualizovat
/etc/fstab
agrub.cfg
v souladu se všemi úpravami, které jste provedli v kroku 7.Restartujte všechny neúspěšné služby:
systemctl | grep failed systemctl restart <whatever>
Znovu povolit sdílené podstromy:
mount --make-rshared /
Spusťte zastavené servisní jednotky – můžete použít tento jediný příkaz:
systemctl isolate default.target
A máte hotovo.
Související:Nemohu nainstalovat softwarové centrum na Kali?Mnohokrát děkuji Andrew Woodovi, který vypracoval tento vývoj na RHEL4, a steve, který mi poskytl odkaz na první.