วิธีย่อขนาดรูทระบบไฟล์โดยไม่ต้องบูต livecd


93

ฉันพบว่าตัวเองต้องการจัดเรียงพาร์ติชันของระบบใหม่เพื่อย้ายข้อมูลก่อนหน้านี้ภายใต้ระบบไฟล์รูทไปยังจุดเมานท์เฉพาะ ไดรฟ์ข้อมูลทั้งหมดอยู่ใน LVM ดังนั้นจึงค่อนข้างง่าย: สร้างไดรฟ์ใหม่ย้ายข้อมูลลงไปลดขนาดระบบไฟล์รูทแล้วติดตั้งไดรฟ์ใหม่ที่จุดที่เหมาะสม

ปัญหาคือขั้นตอนที่ 3 ลดขนาดระบบไฟล์รูท ระบบไฟล์ที่เกี่ยวข้องคือ ext4 ดังนั้นจึงรองรับการปรับขนาดออนไลน์ อย่างไรก็ตามในขณะที่เมานต์ระบบไฟล์สามารถขยายได้เท่านั้น หากต้องการลดขนาดพาร์ติชันให้ถอนการติดตั้งซึ่งแน่นอนว่าไม่สามารถทำได้สำหรับพาร์ติชันรากในการทำงานปกติ

คำตอบรอบ ๆ เว็บดูเหมือนจะหมุนรอบการบูท LiveCD หรือสื่อกู้ภัยอื่น ๆ ทำการลดขนาดจากนั้นบู๊ตกลับสู่ระบบที่ติดตั้ง อย่างไรก็ตามระบบที่มีปัญหานั้นอยู่ในระยะไกลและฉันสามารถเข้าถึงได้ผ่าน SSH เท่านั้น ฉันสามารถรีบู๊ตได้ แต่การบู๊ตดิสก์ช่วยเหลือและไม่สามารถทำการดำเนินการจากคอนโซลได้

ฉันจะยกเลิกการต่อเชื่อมระบบไฟล์รูทขณะที่ยังคงเข้าถึงเชลล์ระยะไกลได้อย่างไร


มีโอกาสใดที่จะเมาท์ระบบไฟล์รูทชั่วคราวบนเซิร์ฟเวอร์อื่นหรือไม่? เช่นหมุน VM อื่นและนำเสนอโวลุ่มดิสก์นี้หรือไม่
สตีฟ

เซิร์ฟเวอร์มีอยู่จริงดังนั้นไม่
Tom Hunt

4
คัดลอก root ไปยัง tmpfs และpivot_rootไปที่นั่น ตัวอย่างที่นี่dreamlayers.blogspot.co.uk/2012/10/running-linux-from-ram.html - มันยุ่งยาก แต่ถ้าคุณมีกล่องทดสอบเพื่อลองใช้
สตีฟ

1
อีกตัวอย่างหนึ่งที่นี่ซึ่งการเข้าถึงระยะไกลผ่าน ssh ถือเป็นivarch.com/blogs/oss/2007/01/…
steve

2
หากรูท LVM เล็กพอที่คุณสามารถโคลนไปยังอีก LVM และสร้างร้านอาหารบูต (เริ่มต้นอุณหภูมิใหม่) ในด้วงที่จะใช้มันแล้วบูตจากมัน (ทำให้มันเป็น "ระบบสด")
Rabin

คำตอบ:


170

ในการแก้ปัญหานี้ให้ข้อมูลที่ให้ไว้ที่http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtmlเป็นการพิจาณา อย่างไรก็ตามคู่มือนั้นมีไว้สำหรับ RHEL รุ่นเก่ามากและข้อมูลต่าง ๆ นั้นล้าสมัยแล้ว

คำแนะนำด้านล่างนี้ได้รับการออกแบบมาเพื่อทำงานกับ CentOS 7 แต่พวกเขาควรจะสามารถถ่ายโอนไปยัง distro ใด ๆ ที่รัน systemd ได้อย่างง่ายดาย คำสั่งทั้งหมดถูกเรียกใช้เป็นรูท

  1. ตรวจสอบให้แน่ใจว่าระบบอยู่ในสถานะเสถียร

    ตรวจสอบให้แน่ใจว่าไม่มีใครใช้งานอยู่และไม่มีสิ่งอื่นใดที่สำคัญเกิดขึ้น อาจเป็นความคิดที่ดีที่จะหยุดการให้บริการเช่น httpd หรือ ftpd เพียงเพื่อให้แน่ใจว่าการเชื่อมต่อภายนอกไม่รบกวนสิ่งที่อยู่ตรงกลาง

    systemctl stop httpd
    systemctl stop nfs-server
    # and so on....
    
  2. ถอนติดตั้งระบบไฟล์ที่ไม่ได้ใช้ทั้งหมด

    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...
    
  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/
    

    สิ่งนี้จะสร้างระบบรูทที่น้อยมากซึ่งจะแยกการดู manpage (ไม่/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
    

และคุณทำเสร็จแล้ว

ขอบคุณมากสำหรับ Andrew Wood ผู้ที่ทำงานเกี่ยวกับวิวัฒนาการนี้ใน RHEL4 และสตีฟซึ่งให้ลิงก์แก่ฉันในอดีต


11
คำตอบที่ยอดเยี่ยม มีมนต์ขลังเกือบและชัดเจนและตรงไปตรงมา ใช้กับเดเบียน VPS ได้โดยไม่มีปัญหาใด ๆ ( umount /oldroot/bootแน่นอนต้องมีในขั้นตอนที่ 6) ฉันกำลังเชื่อมโยงคำตอบของคุณกับคำถาม SE อื่น ๆ ที่ไม่มีคำตอบหรือคำตอบเชิงลบ
vaab

3
และได้รับการแก้ไขปัญหาดังที่ระบุไว้ @vaab คุณต้องumount /oldroot/bootก่อนumount /oldroot
ToBeReplaced

3
จุดคือการ unmount และจัดการระบบไฟล์รูทโดยไม่ต้องใช้ฟิสิคัลคอนโซล เท่าที่ฉันรู้ไม่มีทางที่จะเปิดบริการที่อ่านจากพาร์ติชันในขณะที่ unmount พาร์ติชันนั้น หากบริการของคุณไม่ได้สัมผัสรูท FS อาจเป็นไปได้ว่าคุณสามารถเปิดให้ใช้งานได้mount --moveใน tmpfs แต่ไม่รองรับ
Tom Hunt

2
คุณต้องใช้สิ่งอำนวยความสะดวกของระบบปฏิบัติการเพื่อรีสตาร์ท daemon ฉันไม่เคยใช้พุ่งพรวด แต่wiki.ubuntu.com/FoundationsTeam/Specs/ ......แนะนำว่าtelinit uอาจทำสิ่งที่คุณต้องการ
Tom Hunt

3
รอยย่นเพิ่มเติมที่ฉันพบ: / tmp เป็น ramdisk บนระบบของฉันดังนั้นฉันจึงลงเอยด้วย ramdisk ที่ติดตั้งที่/oldroot/tmpซึ่งทำให้ฉันไม่สามารถถอด/oldrootออกได้ แต่ไม่ปรากฏขึ้นfuserหรือlsofออก เอาบิตการจ้องมองที่ systemd การทำงานที่หนึ่งออก ...
คริส Kitching

7

หากคุณแน่ใจว่าคุณกำลังทำอะไรอยู่ - ไม่ใช่การทดลองคุณอาจขอความช่วยเหลือซึ่งเป็นวิธีที่ไม่โต้ตอบและรวดเร็ว

ในระบบที่ใช้เดเบียนนี่คือวิธี

ดูรหัส: 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


เมื่อให้คำตอบดีกว่าให้คำอธิบายว่าทำไมคำตอบของคุณจึงเป็นคำตอบ
Stephen Rauch

1
นี่คือวิธีการเสียง ฉันชอบของฉันที่ให้ฉันทำกิจวัตรที่จำเป็นแบบโต้ตอบ; อย่างไรก็ตามอันนี้น่าจะเร็วกว่า มันอาจเป็นการดีที่จะแก้ไขรายละเอียดเพิ่มเติมในคำตอบของตัวเองหรือพิจารณาแพลตฟอร์มอื่น ๆ (ดูเหมือนว่าวิธีการทั่วไปนี้จะยังคงใช้งานได้กับ dracut หรือ mkinitcpio หรือเครื่องมือสร้าง initramfs สมัยใหม่อื่น ๆ
Tom Hunt

ขออภัย @ stephen-rauch ฉันเพิ่งจะชี้ให้เห็นความคิดที่ไม่ใช่การดำเนินการ
Szépe Viktor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.