Як зменшити кореневу файлову систему без завантаження livecd


93

Мені здається, що потрібно переставити розділи системи, щоб перемістити дані раніше під кореневою файловою системою у спеціальні точки монтування. Усі томи є у LVM, тому це порівняно просто: створюйте нові томи, переміщуйте в них дані, стискайте кореневу файлову систему, а потім монтуйте нові томи у відповідні точки.

Проблема полягає в кроці 3, скорочуючи кореневу файлову систему. Задіяні файлові системи є ext4, тому підтримується зміна розміру в Інтернеті; проте, монтуючись, файлові системи можна вирощувати тільки. Щоб скоротити розділ, потрібно відключити його, що, звичайно, неможливо для кореневого розділу в звичайній роботі.

Відповіді в Інтернеті, схоже, обертаються навколо завантаження LiveCD або інших рятувальних носіїв, виконуючи операцію скорочення, а потім завантажуючи назад у встановлену систему. Однак система, про яку йде мова, віддалена, і я маю доступ лише через SSH. Я можу перезавантажитись, але завантажувати рятувальний диск і робити операції з консолі неможливо.

Як я можу відключити кореневу файлову систему, зберігаючи віддалений доступ до оболонки?


Будь-яка можливість тимчасово змонтувати кореневу файлову систему на іншому сервері? наприклад, спініруйте інший VM і подайте йому цей об'єм диска?
steve

Сервер фізичний, тому ні.
Том Хант

4
Скопіюйте корінь на tmpfs і pivot_rootтуди. Приклад тут dreamlayers.blogspot.co.uk/2012/10/running-linux-from-ram.html - це хитро, але якщо у вас є тестове поле, щоб спробувати його, варто розглянути.
steve

1
Ще один приклад тут, коли віддалений доступ через ssh вважається ivarch.com/blogs/oss/2007/01/…
steve

2
Якщо кореневий LVM є досить малим, ви можете клонувати його до іншого LVM та створити завантажувальний засіб (темп новий за замовчуванням) у grub, щоб використовувати його, а потім завантажитися з нього (зробивши це вашою "живою системою")
Рабін,

Відповіді:


169

Вирішуючи це питання, ключова інформація була надана на веб- сайті http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtml . Однак цей посібник призначений для дуже старої версії RHEL, і різноманітна інформація була застарілою.

Нижче наведені інструкції створені для роботи з CentOS 7, але вони повинні бути легко передаваними у будь-який дистрибутив, який працює з системою. Усі команди виконуються як root.

  1. Переконайтесь, що система знаходиться в стабільному стані

    Переконайтесь, що ніхто більше не використовує його, і нічого іншого важливого не відбувається. Це, мабуть, гарна ідея зупинити надання службових підрозділів, таких як httpd або ftpd, просто для того, щоб зовнішні з'єднання не порушили речі посередині.

    systemctl stop httpd
    systemctl stop nfs-server
    # and so on....
    
  2. Демонтуйте всі невикористані файлові системи

    umount -a
    

    Це надрукує ряд попереджень "Ціль зайнята" для самого кореневого тома та для різних тимчасових / системних ФС. Це на даний момент можна ігнорувати. Важливо те, що жодна дискова файлова система не залишається встановленою, крім кореневої файлової системи. Перевірте це:

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

    Якщо ви бачите, що будь-які дискові файлові системи все ще змонтовані, то все ще працює щось, чого не повинно бути. Перевірте, що він використовує fuser:

    # if necessary:
    yum install psmisc
    # then:
    fuser -vm <mountpoint>
    systemctl stop <whatever>
    umount -a
    # repeat as required...
    
  3. Зробіть тимчасовий корінь

    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/
    

    Це створює дуже мінімальну кореневу систему, яка порушує (серед іншого) перегляд сторінки сторінки (ні /usr/share), налаштування на рівні користувача (немає /rootабо /home) тощо. Це навмисно, оскільки це заохочує не залишатися в такій кореневій системі, яка є присяжними, довше, ніж потрібно.

    На цьому етапі ви також повинні переконатися, що все необхідне програмне забезпечення встановлено, оскільки воно також безперечно зламає менеджер пакунків. Перегляньте всі кроки та переконайтеся, що у вас є необхідні виконувані файли.

  4. Поворот у корінь

    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 викликає кріплення, щоб дозволити спільне використання підрівнів за замовчуванням (як і у випадку mount --make-shared), і це призводить pivot_rootдо збою. Отже, ми все це відключаємо mount --make-rprivate /. Системні та тимчасові файлові системи переміщуються оптом у новий корінь. Це необхідно, щоб він взагалі працював; розетки для спілкування з systemd, серед іншого, живуть /run, і тому немає можливості змусити запущені процеси закрити його.

  5. Переконайтесь, що віддалений доступ пережив перехід

    systemctl restart sshd
    systemctl status sshd
    

    Після перезапуску sshd переконайтеся, що ви можете ввійти, відкривши інший термінал і знову підключившись до машини через ssh. Якщо ви не можете, вирішіть проблему, перш ніж рухатись далі.

    Після того, як ви перевірили, що зможете знову підключитися, вийдіть із оболонки, яку ви зараз використовуєте, та підключіться знову. Це дозволяє sshdвийти з останнього роздвоєного виходу і гарантує, що новий не тримає /oldroot.

  6. Закрийте все, використовуючи старий корінь

    fuser -vm /oldroot
    

    Це дозволить надрукувати список процесів, які все ще містяться в старому кореневому каталозі. У моїй системі це виглядало приблизно так:

                 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
    

    Вам потрібно розібратися з кожним із цих процесів, перш ніж ви зможете їх відключити /oldroot. Підхід грубої сили - просто kill $PIDдля кожного, але це може зламати речі. Щоб зробити це м'якше:

    systemctl | grep running
    

    Це створює список запущених служб. Ви повинні мати можливість співвіднести це з переліком процесів, що проводяться /oldroot, а потім опублікувати systemctl restartдля кожного з них. Деякі служби відмовляться з'являтись у тимчасовому корені та переходять у невдалий стан; на даний момент це насправді не має значення.

    Якщо кореневий диск, для якого потрібно змінити розмір, є LVM-накопичувачем, можливо, вам також знадобиться перезапустити деякі інші запущені служби, навіть якщо вони не відображаються у списку, створеному користувачем fuser -vm /oldroot. Якщо ви виявите, що не можете змінити розмір накопичувача LVM відповідно до кроку 7, спробуйте systemctl restart systemd-udevd.

    Деякі процеси не вдається вирішити за допомогою простих systemctl restart. Для мене вони включали auditd(які не люблять, щоб їх вбивали systemctl, і так просто хотілося kill -15). З ними можна вирішуватись індивідуально.

    Останній процес, який ви зазвичай знайдете, - це systemdсам. Для цього біжіть systemctl daemon-reexec.

    Коли ви закінчите, таблиця повинна виглядати так:

                 USER        PID ACCESS COMMAND
    /oldroot:    root     kernel mount /oldroot
    
  7. Демонтуйте старий корінь

    umount /oldroot
    

    У цей момент ви можете проводити всі необхідні маніпуляції. Первісне запитання потребувало простого resize2fsвиклику, але ви можете робити все, що завгодно; ще один випадок використання - це перенесення кореневої файлової системи з простого розділу в LVM / RAID / будь-що інше.

  8. Поверніть корінь назад

    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
    

    Це прямий зворотний крок 4.

  9. Утилізуйте тимчасовий корінь

    Повторіть кроки 5 та 6, за винятком використання /tmp/tmprootзамість /oldroot. Тоді:

    umount /tmp/tmproot
    rmdir /tmp/tmproot
    

    Оскільки це tmpfs, тимчасовий корінь розчиняється в ефір, і його більше не побачити.

  10. Поставте речі на свої місця

    Знову змонтуйте файлові системи:

    mount -a
    

    На цьому етапі слід також оновити /etc/fstabта grub.cfgвідповідно до будь-яких коригувань, які ви внесли під час кроку 7.

    Перезапустіть всі несправні служби:

    systemctl | grep failed
    systemctl restart <whatever>
    

    Дозволити знову спільні підкреслення:

    mount --make-rshared /
    

    Запустіть блоки зупиненого обслуговування - ви можете використовувати цю єдину команду:

    systemctl isolate default.target
    

І ви закінчили.

Велика подяка Ендрю Вуду, який розробив цю еволюцію на RHEL4, і Стіву, який надав мені посилання на колишню.


11
Дивовижна відповідь. Майже чарівний, і дуже чіткий і прямолінійний. Використовували його з debian VPS без жодних проблем (просто треба було, umount /oldroot/bootзвичайно, на 6-му етапі). Я пов'язую вашу відповідь з іншими питаннями SE, на які не було відповіді чи негативної відповіді.
vaab

3
І вирішено, питання було таким, як вказано @vaab; ви повинні umount /oldroot/bootперед собоюumount /oldroot
ToBeReplaceced

3
Справа в тому, щоб відключити та керувати кореневою файловою системою, не потребуючи фізичної консолі. Наскільки я знаю, немає можливості тримати відкриту службу, яка читає з розділу, під час демонтажу цього розділу. Якщо ваша служба не торкається кореневого FS, можливо, ви можете тримати її відкритою, використовуючи mount --movetmpfs, але це не підтримується.
Том Хант

2
Щоб перезапустити демон init, потрібно використовувати засоби ОС. Я ніколи не використовував швидкого запуску , але wiki.ubuntu.com/FoundationsTeam/Specs/… пропонує telinit uзробити те, що ви хочете.
Том Хант

3
Додаткова складкою я зіткнувся: / TMP є віртуальним диском на моїй системі, так що я закінчив з псевдодіском змонтованого на /oldroot/tmp, що завадило мені Демонтується /oldroot, але не з'являється в fuserабо lsofвиході. Трохи дивився на systemd, щоб вирішити цю
проблему

7

Якщо ви впевнені, що робите - таким чином, не експериментуючи, ви можете зачепитися за initrd, що є неінтерактивним та швидким способом.

На базі системи Debian ось як.

Дивіться код: https://github.com/szepeviktor/debian-server-tools/blob/master/debian-resizefs.sh

Є ще один приклад: https://github.com/szepeviktor/debian-server-tools/blob/master/debian-convert-ext3-ext4.sh


Коли ви даєте відповідь, бажано дати пояснення щодо того, ЧОМУ ваша відповідь .
Стівен Рауч

1
Це обгрунтований підхід. Мені подобається, що я дозволяв мені робити необхідні маніпуляції інтерактивно; однак це, мабуть, швидше. Можливо, було б добре відредагувати ще деякі деталі у самій відповіді або розглянути інші платформи (схоже, цей загальний підхід все ще працюватиме з dracut або mkinitcpio або будь-яким іншим невиразно сучасним генератором initramfs).
Том Хант

Вибачте @ stephen-rauch, я просто вказував ідею, а не виконання.
Szépe Viktor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.