एक livecd को बूट किए बिना रूट फाइल सिस्टम को कैसे सिकोड़ें


93

मैं खुद को सिस्टम के विभाजन को पूर्व फाइल सिस्टम के तहत डेटा को स्थानांतरित करने के लिए समर्पित माउंट बिंदुओं में स्थानांतरित करने की आवश्यकता महसूस करता हूं। वॉल्यूम सभी LVM में हैं, इसलिए यह अपेक्षाकृत आसान है: नए वॉल्यूम बनाएं, उनमें डेटा ले जाएं, रूट फाइल सिस्टम को सिकोड़ें, फिर नए बिंदुओं को उचित बिंदुओं पर माउंट करें।

मुद्दा चरण 3 है, रूट फाइलसिस्टम को सिकोड़ना। शामिल फाइलसिस्टम ext4 हैं, इसलिए ऑनलाइन आकार बदलने का समर्थन किया जाता है; हालाँकि, माउंट किए जाने के दौरान, फ़ाइल सिस्टम केवल विकसित किए जा सकते हैं। विभाजन को सिकोड़ने के लिए इसे अनमाउंट करना आवश्यक है, जो सामान्य ऑपरेशन में रूट विभाजन के लिए निश्चित रूप से संभव नहीं है।

वेब के चारों ओर उत्तर एक LiveCD या अन्य बचाव मीडिया को बूट करने के लिए घूमते हुए लगते हैं, सिकुड़न ऑपरेशन करते हैं, फिर वापस स्थापित सिस्टम में बूट करते हैं। हालाँकि, विचाराधीन प्रणाली दूरस्थ है, और मेरी पहुंच केवल SSH के माध्यम से है। मैं रिबूट कर सकता हूं, लेकिन बचाव डिस्क को बूट करना और कंसोल से संचालन करना संभव नहीं है।

रिमोट शेल एक्सेस को बनाए रखते हुए मैं रूट फाइल सिस्टम को कैसे अनमाउंट कर सकता हूं?


किसी अलग सर्वर पर रूट फाइल सिस्टम को अस्थायी रूप से माउंट करने का कोई अवसर? उदाहरण के लिए एक और वीएम को स्पिन करें और इस डिस्क की मात्रा को इसमें प्रस्तुत करें?
स्टीव

सर्वर भौतिक है, इसलिए नहीं।
टॉम हंट

4
रूट को tmpfs और pivot_rootवहां पर कॉपी करें । यहाँ एक उदाहरण dreamlayers.blogspot.co.uk/2012/10/running-linux-from-ram.html - यह मुश्किल है लेकिन अगर आपके पास इस पर प्रयास करने के लिए एक परीक्षण बॉक्स है, तो विचार करने योग्य है।
स्टीव

1
एक अन्य उदाहरण हैं, जहां ssh के माध्यम से रिमोट का उपयोग माना जाता है ivarch.com/blogs/oss/2007/01/...
स्टीव

2
यदि रूट LVM काफी छोटा है, तो आप इसे दूसरे LVM पर क्लोन कर सकते हैं और इसका उपयोग करने के लिए ग्रब में बूट eatery (अस्थायी नया डिफ़ॉल्ट) बना सकते हैं, और फिर इससे बूट कर सकते हैं (इसे आपका "लाइव सिस्टम" बना सकते हैं)
Rabin

जवाबों:


169

इस समस्या को हल करने में, http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtml पर दी गई जानकारी निर्णायक थी। हालांकि, वह गाइड आरएचईएल के बहुत पुराने संस्करण के लिए है, और विभिन्न जानकारी अप्रचलित थी।

नीचे दिए गए निर्देशों को CentOS 7 के साथ काम करने के लिए तैयार किया गया है, लेकिन उन्हें सिस्टम को चलाने वाले किसी भी डिस्ट्रो के लिए आसानी से पर्याप्त हस्तांतरणीय होना चाहिए। सभी कमांड रूट के रूप में चलाए जाते हैं।

  1. सुनिश्चित करें कि प्रणाली एक स्थिर स्थिति में है

    सुनिश्चित करें कि कोई और इसका उपयोग नहीं कर रहा है और कुछ भी महत्वपूर्ण नहीं चल रहा है। शायद यह एक अच्छा विचार है कि httpd या ftpd जैसी सेवा प्रदान करने वाली इकाइयों को रोकना, बस यह सुनिश्चित करने के लिए कि बाहरी कनेक्शन बीच में चीजों को बाधित न करें।

    systemctl stop httpd
    systemctl stop nfs-server
    # and so on....
    
  2. सभी अप्रयुक्त फाइल सिस्टम को अनमाउंट करें

    umount -a
    

    यह कई 'प्रिंट में व्यस्त है' चेतावनियों को रूट वॉल्यूम के लिए और विभिन्न अस्थायी / सिस्टम FSs के लिए प्रिंट करेगा। इन्हें फिलहाल नजरअंदाज किया जा सकता है। यह महत्वपूर्ण है कि रूट फाइलसिस्टम को छोड़कर कोई भी ऑन-डिस्क फ़ाइल सिस्टम माउंट न हो। इसे सत्यापित करें:

    # 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 /। सिस्टम और अस्थायी फाइल सिस्टम को नए रूट में थोक में ले जाया जाता है। यह काम करने के लिए आवश्यक है; सिस्टमड के साथ संचार के लिए सॉकेट, अन्य चीजों के साथ, में रहते हैं /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। यदि आप पाते हैं कि आप चरण 7 के तहत LVM ड्राइव का आकार बदलने में असमर्थ हैं, तो प्रयास करें 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. अस्थायी जड़ का निपटान

    के /tmp/tmprootस्थान पर उपयोग को छोड़कर चरण 5 और 6 को दोहराएं /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
    

और आपने कल लिया।

एंड्रयू वुड के लिए बहुत धन्यवाद, जिन्होंने आरएचईएल 4 पर इस विकास को काम किया, और स्टीव, जिन्होंने मुझे पूर्व के लिए लिंक प्रदान किया।


11
बहुत बढ़िया जवाब। लगभग जादुई, और बहुत स्पष्ट और सीधा। इसे किसी भी मुद्दे के बिना डेबियन वीपीएस के साथ इस्तेमाल किया (बस umount /oldroot/bootनिश्चित रूप से, स्टेज 6 पर था)। मैं आपके उत्तर को अन्य SE प्रश्नों से जोड़ रहा हूँ जिनमें कोई उत्तर या नकारात्मक उत्तर नहीं था।
vaab

3
और हल किया गया, जैसा कि संकेत दिया गया था @्वाब इंगित किया गया था; आप umount /oldroot/bootसे पहले आप चाहिएumount /oldroot
ToBeReplaced

3
एक भौतिक कंसोल की आवश्यकता के बिना रूट फाइल सिस्टम को अनमाउंट और हेरफेर करने के लिए बिंदु है। जहां तक ​​मुझे पता है, उस विभाजन को खोलते समय एक सेवा को खोलने का कोई तरीका नहीं है जो विभाजन से पढ़ता है। यदि आपकी सेवा रूट FS को स्पर्श नहीं करती है, तो संभव है कि आप इसे mount --movetmpfs का उपयोग करके खोल सकते हैं , लेकिन यह असमर्थित है।
टॉम हंट

2
Init डेमॉन को पुनः आरंभ करने के लिए आपको OS सुविधाओं का उपयोग करना होगा। मैंने कभी अपस्टार्ट का उपयोग नहीं किया है, लेकिन wiki.ubuntu.com/FoundationsTeam/Specs/… से पता चलता है कि telinit uआप जो चाहते हैं वह कर सकते हैं।
टॉम हंट

3
मैं एक अतिरिक्त शिकन में भाग गया: / tmp मेरे सिस्टम पर एक रैमडिस्क है, इसलिए मैंने एक रैमडिस्क को माउंट किया /oldroot/tmp, जो मुझे अनमाउंट करने से रोकता है /oldroot, लेकिन आउटपुट fuserया शो नहीं करता है lsof। काम करने के लिए सिस्टमड में थोड़ा घूर लिया कि एक बाहर ...
क्रिस Kitching

7

यदि आप सुनिश्चित हैं कि आप क्या कर रहे हैं - इस प्रकार प्रयोग नहीं कर रहे हैं, तो आप initrd में हुक कर सकते हैं जो कि गैर-संवादात्मक और तेज़ तरीका है।

एक डेबियन आधारित प्रणाली पर यहाँ है।

कोड देखें: 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
यह एक ध्वनि दृष्टिकोण है। मुझे इंटरेक्टिव रूप से आवश्यक जोड़तोड़ करने के लिए मेरा पसंद है; हालाँकि, यह शायद तेज है। उत्तर में कुछ और विवरणों को संपादित करना, या अन्य प्लेटफार्मों पर विचार करना अच्छा हो सकता है (ऐसा लगता है कि यह सामान्य दृष्टिकोण अभी भी ड्रैकुट या मिन्किट्सीपियो या किसी अन्य अस्पष्ट आधुनिक इनट्रामर्फ जनरेटर के साथ काम करेगा)।
टॉम हंट

क्षमा करें @ स्टीफन-आरयूच मैं सिर्फ इस विचार को क्रियान्वित नहीं कर रहा था।
20
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.