Jak zmniejszyć główny system plików bez uruchamiania pliku live


93

Uważam, że muszę zmienić układ partycji systemu, aby przenieść dane wcześniej w głównym systemie plików do dedykowanych punktów montowania. Wszystkie woluminy są w LVM, więc jest to stosunkowo łatwe: utwórz nowe woluminy, przenieś do nich dane, zmniejsz główny system plików, a następnie zamontuj nowe woluminy w odpowiednich punktach.

Problemem jest krok 3, zmniejszanie głównego systemu plików. Dotyczy to systemów plików ext4, dlatego obsługiwana jest zmiana rozmiaru online; jednak po zamontowaniu systemy plików można rozbudowywać. Zmniejszenie partycji wymaga jej odmontowania, co oczywiście nie jest możliwe dla partycji root w normalnej pracy.

Wydaje się, że odpowiedzi w Internecie dotyczą uruchamiania systemu LiveCD lub innego nośnika ratunkowego, wykonywania operacji zmniejszania, a następnie ponownego uruchamiania systemu. Jednak system, o którym mowa, jest zdalny i mam dostęp tylko przez SSH. Mogę zrestartować komputer, ale uruchomienie dysku ratunkowego i wykonywanie operacji z konsoli nie jest możliwe.

Jak mogę odmontować główny system plików, zachowując jednocześnie zdalny dostęp do powłoki?


Czy jest okazja, aby tymczasowo zamontować główny system plików na innym serwerze? np. rozpędzić inną maszynę wirtualną i przedstawić jej ten wolumin dysku?
steve

Serwer jest fizyczny, więc nie.
Tom Hunt

4
Skopiuj root do tmpfs i pivot_roottam. Przykład tutaj dreamlayers.blogspot.co.uk/2012/10/running-linux-from-ram.html - to trudne, ale jeśli masz pole testowe do wypróbowania, warto to rozważyć.
steve

1
Kolejny przykład tutaj, w którym zdalny dostęp za pośrednictwem ssh jest uważany za ivarch.com/blogs/oss/2007/01/…
steve

2
Jeśli główny LVM jest wystarczająco mały, możesz go sklonować do innego LVM i utworzyć boot boot (domyślnie tymczasowo nowy) w grub, aby go użyć, a następnie uruchomić z niego (czyniąc go „żywym systemem”)
Rabin

Odpowiedzi:


169

W rozwiązaniu tego problemu informacje podane na stronie http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtml były kluczowe. Jednak ten przewodnik dotyczy bardzo starej wersji RHEL, a różne informacje były przestarzałe.

Poniższe instrukcje zostały opracowane do pracy z CentOS 7, ale powinny być wystarczająco łatwe do przeniesienia do dowolnej dystrybucji działającej systemd. Wszystkie polecenia są uruchamiane jako root.

  1. Upewnij się, że system jest stabilny

    Upewnij się, że nikt inny go nie używa i nic innego się nie dzieje. Prawdopodobnie dobrym pomysłem jest zatrzymanie jednostek świadczących usługi, takich jak httpd lub ftpd, aby upewnić się, że połączenia zewnętrzne nie zakłócają działania w środku.

    systemctl stop httpd
    systemctl stop nfs-server
    # and so on....
    
  2. Odmontuj wszystkie nieużywane systemy plików

    umount -a
    

    Spowoduje to wydrukowanie wielu ostrzeżeń „Docelowy jest zajęty”, dla samego woluminu głównego i dla różnych tymczasowych / systemowych FS. Można je na razie zignorować. Co ważne, żaden system plików na dysku nie pozostaje podłączony, z wyjątkiem samego systemu plików root. Sprawdź to:

    # mount alone provides the info, but column makes it possible to read
    mount | column -t
    

    Jeśli zauważysz, że jakieś systemy plików na dysku są nadal podłączone, oznacza to, że nadal działa coś, co nie powinno być. Sprawdź, czego używa fuser:

    # if necessary:
    yum install psmisc
    # then:
    fuser -vm <mountpoint>
    systemctl stop <whatever>
    umount -a
    # repeat as required...
    
  3. Zrób tymczasowy root

    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/
    

    Tworzy to bardzo minimalny system root, który psuje (między innymi) przeglądanie strony podręcznika (nie /usr/share), dostosowywanie na poziomie użytkownika (nie /rootlub /home) i tak dalej. Jest to celowe, ponieważ stanowi zachętę do nie pozostawania w tak sfałszowanym systemie korzeniowym dłużej niż to konieczne.

    W tym momencie powinieneś również upewnić się, że całe niezbędne oprogramowanie jest zainstalowane, ponieważ z pewnością spowoduje to również uszkodzenie menedżera pakietów. Przejrzyj wszystkie kroki i upewnij się, że masz niezbędne pliki wykonywalne.

  4. Przenieś się do katalogu głównego

    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 powoduje, że montowania domyślnie zezwalają na współużytkowanie poddrzewa (tak jak w przypadku mount --make-shared), co powoduje pivot_rootniepowodzenie. Dlatego wyłączamy to globalnie za pomocą mount --make-rprivate /. Systemowe i tymczasowe systemy plików są hurtowo przenoszone do nowego katalogu głównego. Jest to konieczne, aby w ogóle działało; gniazda do komunikacji z systemd, między innymi, są w /runnim obecne, więc nie ma sposobu, aby działające procesy je zamknęły .

  5. Upewnij się, że dostęp zdalny przetrwał zmianę

    systemctl restart sshd
    systemctl status sshd
    

    Po zrestartowaniu sshd upewnij się, że możesz się dostać, otwierając inny terminal i ponownie łącząc się z maszyną przez ssh. Jeśli nie możesz, napraw problem przed przejściem dalej.

    Po sprawdzeniu, że możesz się ponownie połączyć, zamknij aktualnie używaną powłokę i połącz się ponownie. Pozwala sshdto wyjść z pozostałych wideł i upewnić się, że nowy nie trzyma /oldroot.

  6. Zamknij wszystko, wciąż używając starego katalogu głównego

    fuser -vm /oldroot
    

    Spowoduje to wydrukowanie listy procesów wciąż trzymających się w starym katalogu głównym. W moim systemie wyglądało to tak:

                 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
    

    Przed odmontowaniem musisz poradzić sobie z każdym z tych procesów /oldroot. Podejście brutalnej siły jest po prostu kill $PIDdla każdego, ale może to popsuć. Aby zrobić to bardziej miękko:

    systemctl | grep running
    

    Spowoduje to utworzenie listy uruchomionych usług. Powinieneś być w stanie skorelować to z listą utrzymywanych procesów /oldroot, a następnie wydawać systemctl restartdla każdego z nich. Niektóre usługi odmawiają pojawienia się w tymczasowym katalogu głównym i przechodzą w stan awarii; nie ma to obecnie znaczenia.

    Jeśli dysk główny, którego rozmiar chcesz zmienić, jest dyskiem LVM, może być również konieczne ponowne uruchomienie niektórych innych uruchomionych usług, nawet jeśli nie są wyświetlane na liście utworzonej przez fuser -vm /oldroot. Jeśli okaże się, że nie można zmienić rozmiaru dysku LVM w kroku 7, spróbuj systemctl restart systemd-udevd.

    Niektórych procesów nie da się rozwiązać za pomocą prostych systemctl restart. Dla mnie to wliczone auditd(które nie lubią być zabijane systemctl, a więc po prostu chciałem kill -15). Można sobie z tym poradzić indywidualnie.

    Ostatnim procesem, który zwykle znajdziesz, jest systemdsam. W tym celu uruchom systemctl daemon-reexec.

    Po zakończeniu tabela powinna wyglądać następująco:

                 USER        PID ACCESS COMMAND
    /oldroot:    root     kernel mount /oldroot
    
  7. Odmontuj stary root

    umount /oldroot
    

    W tym momencie możesz wykonywać dowolne manipulacje, których potrzebujesz. Pierwotne pytanie wymagało prostego resize2fswywołania, ale możesz tutaj zrobić, co chcesz; Innym przypadkiem użycia jest przeniesienie głównego systemu plików z prostej partycji na LVM / RAID / cokolwiek.

  8. Odwróć korzeń z powrotem

    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
    

    Jest to proste odwrócenie kroku 4.

  9. Usuń tymczasowy root

    Powtórz kroki 5 i 6, z wyjątkiem użycia /tmp/tmprootzamiast /oldroot. Następnie:

    umount /tmp/tmproot
    rmdir /tmp/tmproot
    

    Ponieważ jest to tmpfs, w tym momencie tymczasowy korzeń rozpuszcza się w eterze, którego już nigdy nie można zobaczyć.

  10. Odłóż rzeczy na swoje miejsce

    Ponownie podłącz systemy plików:

    mount -a
    

    W tym momencie powinieneś również zaktualizować /etc/fstabi grub.cfgzgodnie z wszelkimi korektami dokonanymi podczas kroku 7.

    Uruchom ponownie wszystkie nieudane usługi:

    systemctl | grep failed
    systemctl restart <whatever>
    

    Zezwól ponownie na wspólne poddrzewa:

    mount --make-rshared /
    

    Uruchom zatrzymane jednostki usługowe - możesz użyć tego pojedynczego polecenia:

    systemctl isolate default.target
    

I jesteś skończony.

Wielkie podziękowania dla Andrew Wooda, który opracował tę ewolucję na RHEL4, i Steve'a, który dostarczył mi link do tego pierwszego.


11
Świetna odpowiedź. Prawie magiczne, bardzo jasne i proste. Użyłem go z VPS Debiana bez żadnych problemów (musiałem umount /oldroot/bootoczywiście na etapie 6). Łączę twoją odpowiedź z innymi pytaniami SE, na które nie udzielono odpowiedzi lub odpowiedzi przeczącej.
vaab

3
I rozwiązany problem był taki, jak wskazał @vaab; musisz umount /oldroot/bootprzed sobąumount /oldroot
ToBeReplaced

3
Chodzi o odmontowanie i manipulowanie głównym systemem plików bez potrzeby korzystania z fizycznej konsoli. O ile mi wiadomo, nie ma sposobu na utrzymanie otwartej usługi, która czyta z partycji podczas odmontowywania tej partycji. Jeśli twoja usługa nie dotyka głównego systemu FS, możliwe, że możesz pozostawić ją otwartą przy użyciu mount --movetmpfs, ale to nie jest obsługiwane.
Tom Hunt

2
Musisz użyć funkcji systemu operacyjnego, aby zrestartować demona init. Nigdy nie korzystałem z upstart, ale wiki.ubuntu.com/FoundationsTeam/Specs/... sugeruje, że telinit umoże zrobić to, co chcesz.
Tom Hunt

3
Dodatkowy zmarszczek, na które wpadłem: / tmp to ramdysk w moim systemie, więc skończyłem z ramdyskiem zamontowanym na /oldroot/tmp, który uniemożliwił mi odmontowanie /oldroot, ale nie pojawia się fuserani nie jest lsofwyświetlany. Trochę wpatrywałem się w systemd, żeby to wypracować ...
Chris Kitching

7

Jeśli jesteś pewien, co robisz - a więc nie eksperymentujesz, możesz podłączyć się do initrd, który jest nieinteraktywnym i szybkim sposobem.

W systemie opartym na Debianie jest tutaj jak.

Zobacz kod: https://github.com/szepeviktor/debian-server-tools/blob/master/debian-resizefs.sh

Istnieje inny przykład: https://github.com/szepeviktor/debian-server-tools/blob/master/debian-convert-ext3-ext4.sh


Udzielając odpowiedzi, lepiej jest wyjaśnić, DLACZEGO twoja odpowiedź jest jedna.
Stephen Rauch

1
To rozsądne podejście. Lubię moją za to, że pozwalam mi wykonywać niezbędne manipulacje interaktywnie; jednak ten jest prawdopodobnie szybszy. Dobrze byłoby edytować więcej szczegółów w samej odpowiedzi lub rozważyć inne platformy (wydaje się, że to ogólne podejście nadal działałoby z dracutem, mkinitcpio lub innym niejasnym generatorem initramfs).
Tom Hunt

Przepraszam @ stephen-rauch Właśnie wskazałem pomysł, a nie wykonanie.
Szépe Viktor
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.