Instruksi di bawah ini dibuat untuk bekerja dengan CentOS 7, tetapi mereka harus cukup mudah ditransfer ke distro yang menjalankan systemd. Semua perintah dijalankan sebagai root.
Pastikan sistem dalam kondisi stabil
Pastikan tidak ada orang lain yang menggunakannya dan tidak ada hal lain yang penting sedang terjadi. Mungkin ide yang bagus untuk menghentikan unit penyedia layanan seperti httpd atau ftpd, hanya untuk memastikan koneksi eksternal tidak mengganggu hal-hal di tengah.
systemctl stop httpd
systemctl stop nfs-server
# and so on....
Lepas semua sistem file yang tidak digunakan
umount -a
Ini akan mencetak sejumlah peringatan 'Target is busy', untuk volume root itu sendiri dan untuk berbagai FS sementara / sistem. Ini dapat diabaikan untuk saat ini. Yang penting adalah bahwa tidak ada sistem file pada disk yang tetap terpasang, kecuali sistem file root itu sendiri. Verifikasikan ini:
# mount alone provides the info, but column makes it possible to read
mount | column -t
Jika Anda melihat sistem file pada disk masih terpasang, maka sesuatu masih berjalan yang seharusnya tidak. Periksa apa yang digunakan fuser
:
# if necessary:
yum install psmisc
# then:
fuser -vm <mountpoint>
systemctl stop <whatever>
umount -a
# repeat as required...
Buat root sementara
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/
Ini menciptakan sistem root yang sangat minimal, yang memecah (antara lain) melihat halaman manual (tidak /usr/share
), kustomisasi tingkat pengguna (tidak /root
atau /home
) dan sebagainya. Ini disengaja, karena merupakan dorongan untuk tidak tinggal di sistem root seperti juri lebih lama dari yang diperlukan.
Pada titik ini, Anda juga harus memastikan bahwa semua perangkat lunak yang diperlukan telah diinstal, karena itu juga akan menghancurkan manajer paket. Lihatlah semua langkah, dan pastikan Anda memiliki executable yang diperlukan.
Putar ke root
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 menyebabkan mount untuk memungkinkan berbagi subtree secara default (seperti dengan mount --make-shared
), dan ini menyebabkan pivot_root
gagal. Karenanya, kami mematikannya secara global mount --make-rprivate /
. Sistem dan sistem file sementara dipindahkan secara grosir ke root baru. Ini diperlukan untuk membuatnya berfungsi sama sekali; soket untuk komunikasi dengan systemd, antara lain, tinggal di /run
dalamnya, dan dengan demikian tidak ada cara untuk membuat proses yang berjalan menutupnya.
Pastikan akses jarak jauh selamat dari pergantian tersebut
systemctl restart sshd
systemctl status sshd
Setelah memulai kembali sshd, pastikan Anda dapat masuk, dengan membuka terminal lain dan menghubungkan ke mesin lagi melalui ssh. Jika tidak bisa, perbaiki masalah sebelum melanjutkan.
Setelah memverifikasi, Anda dapat terhubung lagi, keluar dari shell yang saat ini Anda gunakan dan sambungkan kembali. Ini memungkinkan garpu yang tersisa sshd
untuk keluar dan memastikan yang baru tidak tertahan /oldroot
.
Tutup semuanya masih menggunakan root yang lama
fuser -vm /oldroot
Ini akan mencetak daftar proses yang masih berpegang pada direktori root yang lama. Di sistem saya, tampilannya seperti ini:
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
Anda harus berurusan dengan masing-masing dari proses ini sebelum Anda dapat meng-unmount /oldroot
. Pendekatan brute-force hanya kill $PID
untuk masing-masing, tetapi ini dapat merusak banyak hal. Untuk melakukannya dengan lebih lembut:
systemctl | grep running
Ini membuat daftar layanan yang berjalan. Anda harus dapat menghubungkan ini dengan daftar proses yang ada /oldroot
, kemudian mengeluarkan systemctl restart
untuk masing-masing proses. Beberapa layanan akan menolak untuk muncul di root sementara dan memasuki kondisi gagal; ini tidak terlalu penting untuk saat ini.
Jika root drive yang ingin Anda ubah ukurannya adalah drive LVM, Anda mungkin juga perlu me-restart beberapa layanan lain yang berjalan, bahkan jika mereka tidak muncul dalam daftar yang dibuat oleh fuser -vm /oldroot
. Jika ternyata Anda tidak dapat mengubah ukuran drive LVM pada Langkah 7, coba systemctl restart systemd-udevd
.
Beberapa proses tidak dapat ditangani dengan sederhana systemctl restart
. Bagi saya ini termasuk auditd
(yang tidak suka dibunuh via systemctl
, dan hanya ingin a kill -15
). Ini dapat ditangani secara individual.
Proses terakhir yang Anda temukan, biasanya, adalah systemd
dirinya sendiri. Untuk ini, jalankan systemctl daemon-reexec
.
Setelah selesai, tabel akan terlihat seperti ini:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
Lepas root yang lama
umount /oldroot
Pada titik ini, Anda dapat melakukan manipulasi apa pun yang Anda butuhkan. Pertanyaan aslinya membutuhkan resize2fs
doa sederhana , tetapi Anda dapat melakukan apa pun yang Anda inginkan di sini; satu use case lainnya adalah mentransfer filesystem root dari partisi sederhana ke LVM / RAID / apa pun.
Putar kembali root
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
Ini adalah pembalikan langsung dari langkah 4.
Buang akar sementara
Ulangi langkah 5 dan 6, kecuali menggunakan /tmp/tmproot
di tempat /oldroot
. Kemudian:
umount /tmp/tmproot
rmdir /tmp/tmproot
Karena ini adalah tmpfs, pada titik ini root sementara larut ke dalam eter, tidak pernah terlihat lagi.
Kembalikan semuanya ke tempatnya masing-masing
Pasang kembali sistem file:
mount -a
Pada titik ini, Anda juga harus memperbarui /etc/fstab
dan grub.cfg
sesuai dengan penyesuaian yang Anda buat selama langkah 7.
Mulai ulang layanan yang gagal:
systemctl | grep failed
systemctl restart <whatever>
Izinkan sub pohon yang dibagikan lagi:
mount --make-rshared /
Mulai unit layanan yang dihentikan - Anda dapat menggunakan perintah tunggal ini:
systemctl isolate default.target
Dan kamu sudah selesai.
Terima kasih banyak kepada Andrew Wood, yang telah mengerjakan evolusi ini di RHEL4, dan steve, yang memberi saya tautan ke yang sebelumnya.