คำแนะนำด้านล่างนี้ได้รับการออกแบบมาเพื่อทำงานกับ CentOS 7 แต่พวกเขาควรจะสามารถถ่ายโอนไปยัง distro ใด ๆ ที่รัน systemd ได้อย่างง่ายดาย คำสั่งทั้งหมดถูกเรียกใช้เป็นรูท
ตรวจสอบให้แน่ใจว่าระบบอยู่ในสถานะเสถียร
ตรวจสอบให้แน่ใจว่าไม่มีใครใช้งานอยู่และไม่มีสิ่งอื่นใดที่สำคัญเกิดขึ้น อาจเป็นความคิดที่ดีที่จะหยุดการให้บริการเช่น httpd หรือ ftpd เพียงเพื่อให้แน่ใจว่าการเชื่อมต่อภายนอกไม่รบกวนสิ่งที่อยู่ตรงกลาง
systemctl stop httpd
systemctl stop nfs-server
# and so on....
ถอนติดตั้งระบบไฟล์ที่ไม่ได้ใช้ทั้งหมด
umount -a
การดำเนินการนี้จะพิมพ์คำเตือน 'เป้าหมายไม่ว่าง' จำนวนหนึ่งสำหรับโวลุ่มนั้นและสำหรับ FS / ระบบชั่วคราวต่างๆ สิ่งเหล่านี้สามารถถูกเพิกเฉยได้ในขณะนี้ สิ่งสำคัญคือไม่มีการติดตั้งระบบไฟล์บนดิสก์ยกเว้นระบบไฟล์รูท ยืนยันสิ่งนี้:
# 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...
ทำให้รูตชั่วคราว
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/
สิ่งนี้จะสร้างระบบรูทที่น้อยมากซึ่งจะแยกการดู manpage (ไม่/usr/share) การปรับแต่งระดับผู้ใช้ (ไม่ใช่/rootหรือ/home) และอื่น ๆ นี่เป็นความตั้งใจเนื่องจากมันถือว่าเป็นการให้กำลังใจไม่ให้อยู่ในระบบรากของลูกขุนเช่นนี้อีกต่อไปเกินความจำเป็น
ณ จุดนี้คุณควรตรวจสอบให้แน่ใจว่ามีการติดตั้งซอฟต์แวร์ที่จำเป็นทั้งหมดเนื่องจากจะทำให้ตัวจัดการแพคเกจแตกหักได้อย่างมั่นใจ ดูขั้นตอนทั้งหมดและตรวจสอบให้แน่ใจว่าคุณมีไฟล์ปฏิบัติการที่จำเป็น
หมุนเป็นรูท
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และดังนั้นจึงไม่มีวิธีที่จะทำให้กระบวนการทำงานอยู่ใกล้กัน
ตรวจสอบให้แน่ใจว่าการเข้าถึงระยะไกลช่วยให้รอดพ้นจากการเปลี่ยนแปลง
systemctl restart sshd
systemctl status sshd
หลังจากรีสตาร์ท sshd ตรวจสอบให้แน่ใจว่าคุณสามารถเข้าได้โดยเปิดเทอร์มินัลอื่นและเชื่อมต่อกับเครื่องอีกครั้งผ่าน ssh หากคุณไม่สามารถแก้ไขปัญหาได้ก่อนดำเนินการต่อ
เมื่อคุณยืนยันแล้วคุณสามารถเชื่อมต่อได้อีกครั้งให้ออกจากเชลล์ที่คุณใช้อยู่และเชื่อมต่อใหม่ สิ่งนี้จะช่วยให้ส่วนที่เหลือถูกแยกsshdออกและทำให้มั่นใจว่าจะไม่ได้ถือ/oldrootใหม่
ปิดทุกอย่างที่ยังใช้รูทเก่าอยู่
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
ถอนติดตั้งรูทเก่า
umount /oldroot
ณ จุดนี้คุณสามารถดำเนินการสิ่งที่คุณต้องการ คำถามเดิมต้องการการresize2fsร้องของ่ายๆแต่คุณสามารถทำอะไรก็ได้ที่คุณต้องการที่นี่ กรณีการใช้งานอีกกรณีหนึ่งกำลังถ่ายโอนระบบไฟล์รูทจากพาร์ติชันง่าย ๆ ไปยัง LVM / RAID / อะไรก็ตาม
หมุนรูทกลับ
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
กำจัดของรูตชั่วคราว
ทำซ้ำขั้นตอนที่ 5 และ 6 ยกเว้นใช้ในสถานที่ของ/tmp/tmproot /oldrootแล้ว:
umount /tmp/tmproot
rmdir /tmp/tmproot
เนื่องจากเป็น tmpfs ณ จุดนี้รากชั่วคราวจะละลายเป็นอีเธอร์จึงไม่สามารถมองเห็นได้อีก
นำสิ่งต่าง ๆ กลับเข้ามาแทนที่
เมานต์ระบบไฟล์อีกครั้ง:
mount -a
ณ จุดนี้คุณควรอัปเดต/etc/fstabและgrub.cfgสอดคล้องกับการปรับเปลี่ยนใด ๆ ที่คุณทำในระหว่างขั้นตอนที่ 7
เริ่มบริการใด ๆ ที่ล้มเหลว:
systemctl | grep failed
systemctl restart <whatever>
อนุญาตทรีย่อยที่แชร์อีกครั้ง:
mount --make-rshared /
เริ่มหน่วยบริการที่หยุด - คุณสามารถใช้คำสั่งเดียวนี้:
systemctl isolate default.target
ขอบคุณมากสำหรับ Andrew Wood ผู้ที่ทำงานเกี่ยวกับวิวัฒนาการนี้ใน RHEL4 และสตีฟซึ่งให้ลิงก์แก่ฉันในอดีต