मैं चेरोट की सभी प्रक्रियाओं को कैसे रोकूं?


16

मेरे पास कई LVM विभाजन हैं, जिनमें से प्रत्येक में एक Ubuntu इंस्टालेशन है। कभी-कभी, मैं apt-get dist-upgradeसबसे हाल के पैकेजों के लिए एक इंस्टॉलेशन को अपडेट करने के लिए एक करना चाहता हूं । मैं चेरोट के साथ ऐसा करता हूं - प्रक्रिया आमतौर पर कुछ इस तरह होती है:

$ sudo mount /dev/local/chroot-0 /mnt/chroot-0
$ sudo chroot /mnt/chroot-0 sh -c 'apt-get update && apt-get dist-upgrade'
$ sudo umount /mnt/chroot-0

[नहीं दिखाया गया: मैं /mnt/chroot-0/{dev,sys,proc}वास्तविक के लिए बाइंड-माउंट के रूप में भी माउंट और अनमाउंट करता हूं /dev, /sysऔर /proc, जैसा कि डिस्ट-अपग्रेड से लगता है कि ये मौजूद हैं]

हालांकि, सटीक में अपग्रेड करने के बाद, यह प्रक्रिया अब काम नहीं करती है - अंतिम umount विफल हो जाएगा क्योंकि /mnt/chroot-0फाइल सिस्टम पर अभी भी खुली फाइलें हैं । lsofपुष्टि करता है कि चेरोट में खुली फाइलों के साथ प्रक्रियाएं हैं। इन प्रक्रियाओं को डिस्ट-अपग्रेड के दौरान शुरू किया गया है, मैं यह मान रहा हूं क्योंकि service postgresql restartपैकेज अपग्रेड होने के बाद चेरोट में कुछ सेवाओं को फिर से शुरू करने की आवश्यकता होती है (जैसे, के माध्यम से )।

इसलिए, मुझे लगता है कि मुझे इस चेरोट के भीतर चल रही सभी सेवाओं को रोकने के लिए ऊपर बताने की आवश्यकता है। क्या मज़बूती से ऐसा करने का एक तरीका है?

मैंने कोशिश की:

cat <<EOF | sudo chroot /mnt/chroot-0 /bin/sh
# stop 'initctl' services 
initctl list | awk '/start\/running/ {print \$1}' | xargs -n1 -r initctl stop
EOF

जहां initctl list सही काम करने के लिए लगता है और केवल उन प्रक्रियाओं को सूचीबद्ध करता है जो इस विशेष रूट में शुरू किए गए हैं। मैंने इसे जोड़ने की कोशिश की है, जैसा कि Tuminoid द्वारा सुझाया गया है:

cat <<EOF | sudo chroot /mnt/chroot-0 /bin/sh
# stop 'service' services
service --status-all 2>/dev/null |
    awk '/^ \[ \+ \]/ { print \$4}' |
    while read s; do service \$s stop; done
EOF

हालाँकि, ये सब कुछ नहीं पकड़ते हैं; ऐसी प्रक्रियाएँ जिन्हें पीआईडी ​​1 के लिए निर्धारित किया गया है और उनका निवारण नहीं किया गया है। मैंने भी कोशिश की है:

sudo chroot /mnt/chroot-0 telinit 0

लेकिन इस मामले में, init अलग-अलग जड़ों के बीच अंतर नहीं करता है और पूरी मशीन को बंद कर देता है।

तो, क्या किसी विशेष चिरोट में सभी प्रक्रियाओं को रोकने के लिए init बताने का कोई तरीका है, ताकि मैं सुरक्षित रूप से फाइलसिस्टम को अनमाउंट कर सकूं? क्या अपस्टार्ट में चिरोट के भीतर SIGTERM / SIGKILL की सभी बाल प्रक्रियाओं (जैसा कि नियमित रूप से बंद होने के दौरान किया जाएगा) में कोई सुविधा नहीं है?


यह आपके वास्तविक प्रश्न का उत्तर नहीं है, लेकिन सहायक हो सकता है: मैं lxc पैकेज को देखने की सलाह देता हूं। lxc शुरू करने और कंटेनरों में सफाई बंद करने के लिए आसान उपकरण प्रदान करता है।
आयन

जवाबों:


16

मुझे कुछ भी भरोसा नहीं है, लेकिन यहाँ एक पागल राज्य रखने के लिए, इसलिए मैं इस काम को करने के लिए init का उपयोग नहीं करता हूं, और न ही मैं वास्तव में यह जानता हूं कि क्या है या माउंट नहीं किया गया है (कुछ पैकेज binfmt_misc जैसे अतिरिक्त फाइल सिस्टम माउंट कर सकते हैं)। तो, प्रक्रिया वध के लिए, मैं उपयोग करता हूं:

PREFIX=/mnt/chroot-0
FOUND=0

for ROOT in /proc/*/root; do
    LINK=$(readlink $ROOT)
    if [ "x$LINK" != "x" ]; then
        if [ "x${LINK:0:${#PREFIX}}" = "x$PREFIX" ]; then
            # this process is in the chroot...
            PID=$(basename $(dirname "$ROOT"))
            kill -9 "$PID"
            FOUND=1
        fi
    fi
done

if [ "x$FOUND" = "x1" ]; then
    # repeat the above, the script I'm cargo-culting this from just re-execs itself
fi

और umounting chroots के लिए, मैं उपयोग करता हूं:

PREFIX=/mnt/chroot-0
COUNT=0

while grep -q "$PREFIX" /proc/mounts; do
    COUNT=$(($COUNT+1))
    if [ $COUNT -ge 20 ]; then
        echo "failed to umount $PREFIX"
        if [ -x /usr/bin/lsof ]; then
            /usr/bin/lsof "$PREFIX"
        fi
        exit 1
    fi
    grep "$PREFIX" /proc/mounts | \
        cut -d\  -f2 | LANG=C sort -r | xargs -r -n 1 umount || sleep 1
done

एक परिशिष्ट के रूप में, मैं इंगित करता हूं कि यह एक init समस्या के रूप में आ रहा है, शायद इसे देखने का गलत तरीका है, जब तक कि आप वास्तव में चिरोट में एक init और एक अलग प्रक्रिया स्थान नहीं है (यानी: LXC कंटेनरों के मामले में) । एक एकल init (चुरोट के बाहर), और एक साझा प्रक्रिया स्थान के साथ, यह अब "init की समस्या" नहीं है, बल्कि आप पर निर्भर करता है कि आप उन प्रक्रियाओं का पता लगा सकते हैं, जो आपत्तिजनक पथ की होती हैं, इसलिए उपरोक्त खरीद चलते हैं।

यह आपके प्रारंभिक पोस्ट से स्पष्ट नहीं है अगर ये पूरी तरह से बूट करने योग्य सिस्टम हैं जो आप सिर्फ बाहरी रूप से अपग्रेड कर रहे हैं (जो कि मैं इसे कैसे पढ़ता हूं), या यदि वे chroots हैं जो आप पैकेज बिल्ड जैसी चीजों के लिए उपयोग करते हैं। यदि यह बाद की बात है, तो आप भी जगह में एक पॉलिसी-आरओडी (जैसे एमके-सॉल्वेंट में गिराए गए) चाहते हैं कि पहली जगह से शुरू होने वाली नौकरियों को मना कर सकते हैं। जाहिर है, यह एक समझदार समाधान नहीं है अगर ये बूट करने योग्य प्रणाली के रूप में अच्छी तरह से हैं।


वे बूट करने योग्य प्रणाली हैं, लेकिन policy-rc.dएक दिलचस्प दृष्टिकोण की तरह दिखता है (मैं चेरोट के साथ बातचीत करने के बाद इसे हटा सकता था)। क्या यह /etc/rc*.d- और /etc/init/*.conf-स्टाइल नौकरियों दोनों को प्रभावित करता है ?
जेरेमी केर

एचएम, जाहिर तौर पर नहीं: बग्सलाउंचपड.नेट
जेरेमी केर

न तो upstart और न ही sysvinit "नीति-rc.d से परामर्श करें", यह इनवोक-rc.d है जो ऐसा करता है, जो कि सभी पोस्टस्टीन स्क्रिप्ट का उपयोग init नौकरियों के साथ बातचीत करने के लिए होता है। व्यवहार में, यह DTRT को लगता है, टूटे हुए पैकेज के मामले में (जो तय किया जाना चाहिए) को छोड़कर। फिर भी, उपरोक्त "पर्ज विथ फायर" स्क्रिप्टिंग काम करती है, चाहे मुद्दा कुछ पिछली नीति को खिसकाने का हो, कोई नीति लागू न होने का, या किसी अन्य प्रकार की एक लंबी-चलने वाली प्रक्रिया को छोड़ दिया जाना (प्रमुख उपयोग-मामला) यहाँ बिल्ड बिल्ड के दौरान बैकग्राउंड की गई चीजें होती हैं या अन्यथा क्रिप्ट से अनपेक्षित)।
अनंत

1
Utpstart के चेरोट सपोर्ट के आसपास काम करने की कोशिश में एक समस्या। मैं काफी निश्चित रूप से मार रहा हूं -9 अगर अपस्टार्ट नौकरी निर्दिष्ट करने से रोक नहीं पाएगा, अगर यह निर्दिष्ट हो गया है। तो तुम सच में अभी भी पूछताछ करने के लिए chroot अंदर से पूछताछ करने की जरूरत है कि क्या चीजें अभी भी चल रही हैं। मुझे लगता है कि यह बहुत दुर्भाग्यपूर्ण है, और हमारे पास इन नौकरियों को खत्म करने के लिए बाहर के रास्ते से कोई रास्ता होना चाहिए। कहा कि मैं देखता हूं कि initctl सूची / awk / grep दृष्टिकोण + तुम्हारा पूरा कहां होना चाहिए।
SpamapS

1
@SpamapS: अच्छी बात है - init नौकरियों को मैन्युअल रूप से मारना वास्तव में उन्हें फिर से शुरू करने का परिणाम है। एक चेरोट-विशिष्ट शटडाउन को परिभाषित करने, परिभाषित नौकरियों को रोकने, और फिर किसी भी बचे हुए पुनरावर्तित प्रक्रिया को मारने के लिए जो कि चेरोट के भीतर एक रूट डायरेक्टरी है, को बताने में बहुत अच्छा होगा।
जेरेमी केर

0

आपने पहले से ही इस समस्या की पहचान कर ली है: कुछ चीजें service ...डिस्ट-अपग्रेड के दौरान चलती हैं और serviceयह अपस्टार्ट का हिस्सा नहीं है, लेकिन इसका हिस्सा है sysvinitservice --status-allसिसविनीट सेवाओं को रोकने के लिए इसी तरह के अजीब जादू को जोड़ें जैसा कि आपने उपस्टार्ट सेवाओं के लिए उपयोग किया था।


3
आह, धन्यवाद। यह लगभग बेहतर है, लेकिन यह सभी सेवाओं को कवर नहीं करता है। मैंने भाग लिया है sudo chroot /mnt/chroot-0 service --list-allऔर sudo chroot /mnt/chroot-0 initctl list, जो दोनों रिपोर्ट करते हैं कि कोई सेवा नहीं चल रही है। हालाँकि, /usr/bin/epmd(erlang-base से) अभी भी चल रहा है।
जेरेमी केर

0

मुझे पता है कि यह सवाल बहुत पुराना है, लेकिन मुझे लगता है कि यह आज भी उतना ही प्रासंगिक है, जितना 2012 में था, और उम्मीद है कि कोई इस कोड को उपयोगी समझेगा। मैंने कुछ ऐसा करने के लिए कोड लिखा था, लेकिन मुझे लगा कि मैं इसे साझा करूंगा।

मेरा कोड अलग है, लेकिन विचार @infinity के बहुत समान हैं (वास्तव में - एकमात्र कारण जो मुझे अब पता है / proc / * / root के बारे में है क्योंकि उसका उत्तर है - धन्यवाद @infinity!)। मैंने कुछ शांत अतिरिक्त कार्यक्षमता भी जोड़ी

#Kills any PID passed to it
#At first it tries nicely with SIGTERM
#After a timeout, it uses SIGKILL
KILL_PID()
{
        PROC_TO_KILL=$1

        #Make sure we have an arg to work with
        if [[ "$PROC_TO_KILL" == "" ]]
        then
                echo "KILL_PID: \$1 cannot be empty"
                return 1
        fi

        #Try to kill it nicely
        kill -0 $PROC_TO_KILL &>/dev/null && kill -15 $PROC_TO_KILL

        #Check every second for 5 seconds to see if $PROC_TO_KILL is dead
        WAIT_TIME=5

        #Do a quick check to see if it's still running
        #It usually takes a second, so this often doesn't help
        kill -0 $PROC_TO_KILL &>/dev/null &&
        for SEC in $(seq 1 $WAIT_TIME)
        do
                sleep 1

                if [[ "$SEC" != $WAIT_TIME ]]
                then
                        #If it's dead, exit
                        kill -0 $PROC_TO_KILL &>/dev/null || break
                else
                        #If time's up, kill it
                        kill -0 $PROC_TO_KILL &>/dev/null && kill -9 $PROC_TO_KILL
                fi
        done
}

अब आप यह सुनिश्चित करने के लिए 2 काम करेंगे कि चिरोट को अनमाउंट किया जा सकता है:

चेरोट में चलने वाली सभी प्रक्रियाओं को मारें:

CHROOT=/mnt/chroot/

#Find processes who's root folder is actually the chroot
for ROOT in $(find /proc/*/root)
do
        #Check where the symlink is pointing to
        LINK=$(readlink -f $ROOT)

        #If it's pointing to the $CHROOT you set above, kill the process
        if echo $LINK | grep -q ${CHROOT%/}
        then
                PID=$(basename $(dirname "$ROOT"))
                KILL_PID $PID
        fi
done

चेरोट के बाहर चल रही सभी प्रक्रियाओं को मार सकते हैं, लेकिन इसके साथ हस्तक्षेप कर रहे हैं (उदाहरण के लिए: यदि आपका चुरोट / mnt / चेरोट है और dd / mnt / chroot / testfile को लिख रहा है, / mt / चेरोट अनमाउंट करने में विफल रहेगा)

CHROOT=/mnt/chroot/

#Get a list of PIDs that are using $CHROOT for anything
PID_LIST=$(sudo lsof +D $CHROOT 2>/dev/null | tail -n+2 | tr -s ' ' | cut -d ' ' -f 2 | sort -nu)

#Kill all PIDs holding up unmounting $CHROOT
for PID in $PID_LIST
do
        KILL_PID $PID
done

नोट: सभी कोड को रूट के रूप में चलाएँ

इसके अलावा, एक कम जटिल संस्करण के लिए, साथ KILL_PID की जगह या तो kill -SIGTERMयाkill -SIGKILL


0

jchroot : अधिक अलगाव के साथ एक चुरोट

आपके आदेश को निष्पादित किए जाने के बाद, इस आदेश के निष्पादन द्वारा शुरू की गई किसी भी प्रक्रिया को मार दिया जाएगा, किसी भी आईपीसी को मुक्त कर दिया जाएगा, किसी भी माउंट बिंदु को अनमाउंट किया जाएगा। सब साफ!

schroot अभी तक ऐसा करने में सक्षम नहीं है, लेकिन यह योजनाबद्ध है

मैंने इसे OpenVZ VPS में सफलतापूर्वक परीक्षण किया है, जो docker या lxc का उपयोग नहीं कर सकता है।

कृपया विवरण के लिए लेखक का ब्लॉग पढ़ें:

https://vincent.bernat.im/en/blog/2011-jchroot-isolation.html


-1

schroot: इसमें सत्र प्रबंधन की सुविधा है। जब आप सत्र को रोकते हैं तो इसकी सभी प्रक्रियाएं मार दी जाती हैं।

https://github.com/dnschneid/crouton/blob/master/host-bin/unmount-chroot : यह स्क्रिप्ट सभी वर्ण प्रक्रिया को मार देती है और सभी आरोहित उपकरणों को खोल देती है।


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