Ubuntu VPS पर सही kernel बूट कैसे सेट करें
Ubuntu क्लाउड इमेज में GRUB_DEFAULT काम क्यों नहीं करता है। अपनी बूट प्रविष्टियों को सही तरीके से कैसे पढ़ें और rescue console में फंसे बिना सही kernel को कैसे पिन करें।
क्या निर्धारित करता है कि आपका VPS कौन सा kernel बूट करेगा
आपका VPS अगली बार कौन सा kernel बूट करेगा, यह एक जनरेट की गई फाइल /boot/grub/grub.cfg द्वारा तय होता है। आप उस फाइल को कभी एडिट नहीं करते हैं। आप उसके इनपुट को एडिट करते हैं और उसे फिर से जनरेट करते हैं। Ubuntu क्लाउड इमेज पर, उन इनपुट में से एक इमेज वेंडर की तरफ से आता है, और यह मेनू चयन को अप्रासंगिक बना सकता है। यही कारण है कि रेंट पर लिए गए सर्वर पर GRUB_DEFAULT=1 के बाद update-grub चलाने से कुछ नहीं बदलता, जबकि लैपटॉप इंस्टॉलेशन पर यही दो स्टेप्स काम करते हैं।
इस क्रम में काम करें। पुष्टि करें कि kernel चुनने का अधिकार आपके पास है। हर इनपुट फाइल को पढ़ें, जिसमें वेंडर द्वारा जोड़ी गई फाइलें भी शामिल हैं। जनरेट किए गए आउटपुट को पढ़ें और गिनें कि उसमें वास्तव में कितनी प्रविष्टियाँ (entries) हैं। उसके बाद ही पिनिंग (pinning) की विधि चुनें। जिस मशीन को आप केवल SSH के माध्यम से एक्सेस कर सकते हैं, उस पर इसे गलत करने का मतलब है कि आपको rescue console की आवश्यकता पड़ेगी, इसलिए सबसे सुरक्षित उत्तर इस पेज के अंत में दिए गए हैं और वे अक्सर सही होते हैं।
सबसे पहले जांचें कि क्या kernel आपका है जिसे पिन किया जा सकता है
uname -r
systemd-detect-virt
ls -1 /boot/vmlinuz-*systemd-detect-virt यदि kvm, qemu या xen प्रिंट होता है, तो इसका अर्थ है कि आप अपना स्वयं का kernel चला रहे हैं और नीचे दी गई सभी बातें आप पर लागू होती हैं। lxc या openvz प्रिंट होने का अर्थ है कि आपका सर्वर host के kernel को साझा करता है, इसलिए आपके पास अपना कोई bootloader नहीं है और पिन करने के लिए कुछ भी नहीं है। उस स्थिति में uname -r एक ऐसा version दिखाता है जो /boot/vmlinuz-* में बिल्कुल भी नहीं होता, क्योंकि चल रहा kernel host का है और आपकी डिस्क पर कोई भी सेटिंग इसे बदल नहीं सकती।
ls -1 /boot/vmlinuz-* उन kernels की वास्तविक सूची है जिन्हें आप चुन सकते हैं। यदि इसमें केवल एक लाइन है, तो पिछला kernel पहले ही डिलीट हो चुका है, और कोई भी bootloader सेटिंग उसे वापस नहीं ला सकती। ऐसा आमतौर पर autoremove के दौरान होता है, जिसे किसी महत्वपूर्ण सर्वर पर Ubuntu पर पुराने kernels को हटाने से पहले समझना आवश्यक है।
जिस फाइल को आप एडिट करते हैं, वह GRUB द्वारा पढ़ी जाने वाली फाइल नहीं है
/etc/default/grub में साधारण shell variable assignments होते हैं। यह एक इनपुट है। /boot/grub/grub.cfg आउटपुट है, और यह # DO NOT EDIT THIS FILE और उसके कारण के साथ शुरू होता है। जब भी कोई kernel package इंस्टॉल या रिमूव किया जाता है, तो आप आउटपुट में जो कुछ भी लिखते हैं वह मिट जाता है, क्योंकि वे package scripts इसे फिर से जनरेट करती हैं।
cat /usr/sbin/update-grubupdate-grub एक wrapper है। यह grub-mkconfig -o /boot/grub/grub.cfg को चलाता है, जो variables को पढ़ता है, /etc/grub.d/ में मौजूद हर script को रन करता है, और परिणाम लिखता है। दो कमांड, एक दिशा: इनपुट अंदर जाते हैं, grub.cfg बाहर आता है।
आपकी सेटिंग को क्या ओवरराइड करता है: /etc/default/grub.d
grep -rn '^[^#]' /etc/default/grub /etc/default/grub.d/दूसरा पाथ वह हिस्सा है जिसे लोग अक्सर अनदेखा कर देते हैं। grub-mkconfig पहले /etc/default/grub को सोर्स करता है, और उसके बाद /etc/default/grub.d/ में मौजूद हर *.cfg फाइल को ग्लोब ऑर्डर (glob order) में प्रोसेस करता है। इसे करने वाले कोड को पढ़ें:
grep -n 'default/grub' /usr/sbin/grub-mkconfigसोर्सिंग (sourcing) एक साधारण शेल प्रक्रिया है, इसलिए जो असाइनमेंट अंत में होता है, वही प्रभावी रहता है। Ubuntu क्लाउड इमेजेस उस डायरेक्टरी में फाइलें शिप करती हैं, और वे आपकी फाइल पढ़े जाने के बाद टाइमआउट और कर्नल कमांड लाइन जैसी चीजों को सेट कर देती हैं। आपका GRUB_TIMEOUT=10 जो /etc/default/grub में है, उसे एक वेंडर फाइल द्वारा तुरंत ओवरराइट कर दिया जाता है जो इसे 0 पर सेट कर देती है। ऊपर दिया गया grep कमांड आपकी इमेज पर मौजूद सटीक असाइनमेंट्स को प्रिंट करता है, इसलिए इस वाक्य पर भरोसा करने के बजाय उन्हें पढ़ें।
इसका व्यावहारिक नियम यह है: अपनी सेटिंग्स को किसी ऐसी फाइल में रखें जो अंत में सॉर्ट होती हो, जैसे कि /etc/default/grub.d/99-local.cfg, न कि /etc/default/grub को एडिट करें। इससे इमेज के साथ आने वाली कोई भी चीज आपके बाद ओवरराइड नहीं कर पाएगी।
GRUB_FORCE_PARTUUID मेनू चयन को अप्रासंगिक क्यों बनाता है
grep -rn GRUB_FORCE_PARTUUID /etc/default/grub /etc/default/grub.d/
grep -n GRUB_FORCE_PARTUUID /etc/grub.d/10_linux
sudo grep -n 'root=PARTUUID' /boot/grub/grub.cfgGRUB_FORCE_PARTUUID जनरेटर को यह निर्देश देता है कि वह बूट होते समय filesystem UUID खोजने के बजाय, kernel command line पर सीधे root=PARTUUID=... के रूप में लिखे गए partition UUID द्वारा root filesystem को ढूंढे। इमेज वेंडर इसे इसलिए सेट करता है ताकि एक ही डिस्क इमेज उस हार्डवेयर पर भी विश्वसनीय रूप से बूट हो सके जिस पर उसे नहीं बनाया गया था। दूसरा grep आपको वह कोड दिखाता है जो /etc/grub.d/10_linux में वेरिएबल पर कार्य करता है। वह स्क्रिप्ट आपकी अपनी डिस्क पर है, और वही यह तय करती है कि आपकी इमेज क्या करती है।
यहाँ परिणाम महत्वपूर्ण है: उस पथ पर जनरेटर इंस्टॉल किए गए kernels की पूरी सूची के बजाय एक सीधा बूट एंट्री लिखता है। गणना करें कि अंत में आपके पास क्या बचा है।
sudo grep -cE '^\s*(menuentry|submenu) ' /boot/grub/grub.cfg
sudo grep -nE '^\s*(menuentry|submenu) ' /boot/grub/grub.cfgयदि संख्या 1 है, तो चुनने के लिए कोई दूसरी एंट्री नहीं है, इसलिए GRUB_DEFAULT=1 ऐसी एंट्री का नाम लेता है जो मौजूद ही नहीं है। GRUB इसे हल (resolve) नहीं कर सकता, इसलिए यह पहली एंट्री को बूट करता है, जो कि वही नया kernel है जिससे आप बचना चाह रहे थे। grub-set-default भी मदद नहीं करता, क्योंकि डिफ़ॉल्ट वह हिस्सा नहीं है जो खराब है। जिस मेनू से आप चयन करने का प्रयास कर रहे हैं, वह कभी जनरेट ही नहीं हुआ था।
पूर्ण मेनू वापस पाने के लिए, वेंडर फ़ाइल को हटा दें और उसे लागू करने से पहले परिणाम का पूर्वावलोकन (preview) करें। बिना -o के grub-mkconfig मानक आउटपुट (standard output) पर लिखता है और डिस्क पर किसी चीज़ को नहीं छूता है।
sudo grub-mkconfig 2>/dev/null | grep -cE '^\s*(menuentry|submenu) '
sudo mkdir -p /root/grub-backup
sudo mv /etc/default/grub.d/<the file your grep named> /root/grub-backup/
sudo grub-mkconfig 2>/dev/null | grep -cE '^\s*(menuentry|submenu) 'यदि संख्या 1 से बढ़कर कई हो जाती है, तो इसका मतलब है कि forcing हटने के बाद एंट्रीज़ दिखाई देने लगी हैं। अभी तक कुछ भी लिखा नहीं गया है। यदि दूसरी संख्या सही नहीं दिखती है तो फ़ाइल को वापस रख दें, क्योंकि forced PARTUUID ही वह तरीका है जिससे आपके प्रदाता की इमेज अपने root filesystem को लोकेट करती है, और इसे हटाने से मशीन search path पर चली जाती है। update-grub को वास्तव में चलाने से पहले एक snapshot लें।
यदि आपका एकमात्र लक्ष्य एक खराब kernel से बचना है, तो यहीं रुक जाएं और नीचे दिए गए सुरक्षित विकल्पों का उपयोग करें। एक सिंगल अपग्रेड से बचने के लिए रिमोट सर्वर पर बूट मेनू को फिर से बनाना उस समस्या से कहीं अधिक जोखिम भरा है।
एंट्री नंबरों को पिन करना गलत क्यों है
GRUB_DEFAULT एक नंबर, एक शीर्षक या एक आइडेंटिफायर स्वीकार करता है। नंबर 0 से शुरू होकर टॉप-लेवल एंट्रीज की गिनती करते हैं। एक नेस्टेड एंट्री > को विभाजक (separator) के रूप में उपयोग करती है, इसलिए GRUB_DEFAULT="1>2" का अर्थ है इंडेक्स 1 वाले सबमेनू के अंदर इंडेक्स 2 वाली एंट्री।
इंडेक्स बदलते रहते हैं। 10_linux कर्नेल को सबसे नए से पुराने के क्रम में सूचीबद्ध करता है, इसलिए एक नया कर्नेल इंस्टॉल करने पर सभी पुरानी एंट्रीज एक स्थान नीचे खिसक जाती हैं, और कर्नेल हटाने पर वे ऊपर आ जाती हैं। आपकी सावधानीपूर्वक सेट की गई 1>2 उसके बाद भी रिजॉल्व होती है। अब यह एक अलग कर्नेल को दर्शाती है। कोई एरर नहीं आता, कोई चेतावनी नहीं मिलती, और आपको इसका पता रीबूट के बाद चलता है।
आइडेंटिफायर नहीं बदलते, क्योंकि प्रत्येक में कर्नेल वर्जन शामिल होता है। अपना आइडेंटिफायर यहाँ देखें:
sudo awk -F"'" '/menuentry_id_option/ {print $2, "==>", $4}' /boot/grub/grub.cfgआउटपुट की पहली कुछ लाइनों को अनदेखा करें, जो हेडर में परिभाषित वेरिएबल हैं। उसके बाद, बाईं ओर वह शीर्षक है जिसे यूजर देखता है और दाईं ओर वह आइडेंटिफायर है जिसे आप टूल्स को पास करते हैं। सबमेनू के अंदर की किसी एंट्री के लिए, सबमेनू आइडेंटिफायर और एंट्री आइडेंटिफायर को > के साथ उसी क्रम में जोड़ें, जैसा कि न्यूमेरिक फॉर्म में किया जाता है।
grub-reboot के साथ पिछले kernel को एक बार बूट करें
Remote server पर एक बार के लिए चयन करना सबसे सही तरीका है, क्योंकि यह अपने आप वापस सामान्य हो जाता है। grub-reboot, next_entry को /boot/grub/grubenv में लिखता है। GRUB इस variable को पढ़ता है, इसे clear करता है, और किसी भी चीज़ को बूट करने से पहले clear की गई value को save कर लेता है। इसलिए यदि kernel panic करता है, तो अगले बूट पर उसे दोबारा retry नहीं किया जाता। आपको एक प्रयास मिलता है, और उसके बाद मशीन अपने आप अपने सामान्य default पर लौट आती है।
सबसे पहले पुष्टि करें कि आपकी generated config उस variable को पढ़ती है या नहीं:
sudo grep -n -B2 -A5 'next_entry' /boot/grub/grub.cfgआपको एक load_env लाइन और एक ऐसा block चाहिए जो next_entry से default को set करता हो। यदि grep कुछ भी print नहीं करता है, तो आपकी image बूट के समय कभी भी grubenv को नहीं पढ़ती है। इसलिए shell पर grub-reboot को स्वीकार तो कर लिया जाएगा, लेकिन bootloader द्वारा उसे ignore कर दिया जाएगा। यह वही forced direct boot path है जो पिछले section में दूसरी जगह दिखाई दिया था।
sudo grub-reboot '<the identifier you copied>'
sudo grub-editenv listgrub-editenv list को अब एक next_entry= लाइन print करनी चाहिए जिसमें वही जानकारी हो जो आपने pass की थी। ब्राउज़र टैब में अपने provider का console खोलें, फिर reboot करें और परिणाम की जाँच करें।
sudo rebootuname -runame -r द्वारा पुराने version की रिपोर्ट करने का मतलब है कि pin काम कर गया। नए version की रिपोर्ट करने का मतलब है कि या तो identifier resolve नहीं हुआ या grubenv को पढ़ा नहीं जा रहा है। दोनों ही स्थितियों में मशीन चालू हो जाती है, जो कि one-shot form का उपयोग करने का मुख्य उद्देश्य है।
GRUB_DEFAULT=saved के साथ चयन को स्थायी बनाएँ
GRUB_DEFAULT=saved यह सुनिश्चित करता है कि डिफ़ॉल्ट मान saved_entry से grubenv में लिया जाए, और आप इस मान को grub-set-default के साथ सेट करते हैं। यह kernel install के बाद भी बना रहता है, क्योंकि update-grub केवल grub.cfg को फिर से लिखता है और grubenv को कभी नहीं बदलता है।
echo 'GRUB_DEFAULT=saved' | sudo tee /etc/default/grub.d/99-local.cfg
sudo update-grub
sudo grub-set-default '<the identifier you copied>'
sudo grub-editenv list
sudo grep -n 'set default' /boot/grub/grub.cfgअंतिम कमांड को set default="${saved_entry}" प्रिंट करना चाहिए। यदि यह set default="0" प्रिंट करता है, तो आपकी फ़ाइल के बाद लोड हुई किसी चीज़ ने GRUB_DEFAULT को वापस एक literal मान पर सेट कर दिया है। इसलिए /etc/default/grub.d/ को फिर से सूचीबद्ध करें और जाँचें कि 99-local.cfg वास्तव में अंत में है या नहीं।
GRUB_SAVEDEFAULT=true एक अलग सेटिंग है और इसे इस सेटिंग के साथ भ्रमित करना आसान है। यह जो कुछ भी आपने अभी बूट किया है उसे नए डिफ़ॉल्ट के रूप में सहेजता है, इसलिए डिफ़ॉल्ट अंतिम सफल बूट का अनुसरण करता है। सर्वर पर इसका मतलब है कि एक unattended reboot चुपचाप आपके पिन को बदल सकता है। इसे तब तक बंद रखें जब तक कि आप यही न चाहते हों।
identifier द्वारा पिन करना अभी भी एक स्थिति में विफल हो सकता है। यदि आप उस kernel को हटा देते हैं जिसका नाम इसमें है, तो identifier resolve होना बंद हो जाएगा, जिससे आप वापस पहली प्रविष्टि (entry) पर आ जाएंगे। इसलिए पैकेज को hold पर रखें, या उस kernel को autoremove से बाहर रखें।
Provider console पर मेनू प्राप्त करना
इंटरैक्टिव रूप से चयन करने के लिए स्क्रीन पर मेनू का होना आवश्यक है, और क्लाउड इमेजेज इसे छिपा देती हैं। इन्हें उस फाइल में डालें जो सबसे अंत में सॉर्ट होती है, फिर sudo update-grub चलाएं।
GRUB_TIMEOUT=10
GRUB_TIMEOUT_STYLE=menu
GRUB_RECORDFAIL_TIMEOUT=10GRUB_TIMEOUT_STYLE=hidden को GRUB_TIMEOUT=0 के साथ उपयोग करने पर कुछ भी दिखाई नहीं देता है, इसलिए कंसोल देखने वाले व्यक्ति को लगता है कि कर्नल मैसेज तुरंत शुरू हो गए हैं और बूटलोडर को छोड़ दिया गया है। GRUB_RECORDFAIL_TIMEOUT वह अलग टाइमआउट है जिसका उपयोग उस बूट के बाद किया जाता है जो पूरा नहीं हुआ था, और क्लाउड इमेजेज इसे भी 0 पर सेट कर देती हैं, यही कारण है कि जो सर्वर बूट होने में विफल रहा है वह भी रुकता नहीं है और आपका इंतजार नहीं करता है।
यदि आपका प्रोवाइडर ग्राफिकल कंसोल के बजाय सीरियल कंसोल देता है और आपको फिर भी कुछ दिखाई नहीं देता है, तो GRUB उस टर्मिनल पर लिख रहा है जिसे आप देख नहीं सकते हैं। दोनों लाइनों को एक साथ जोड़ें, क्योंकि पहली लाइन आउटपुट का चयन करती है और दूसरी पोर्ट को कॉन्फ़िगर करती है:
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"अब से हर बूट में दस सेकंड जुड़ जाएंगे। जब आपका काम पूरा हो जाए, तो टाइमआउट को वापस 0 पर सेट कर दें।
बूटलोडर को एडिट करने से बेहतर विकल्प
SSH के माध्यम से एक्सेस किए जाने वाले सर्वर पर बूटलोडर इनपुट बदलना इस पेज का सबसे जोखिम भरा विकल्प है। इसके सस्ते और आसान समाधान मौजूद हैं, जो आमतौर पर वास्तविक समस्या को हल कर देते हैं।
कर्नेल पैकेज को होल्ड (Hold) करें। यदि आपका लक्ष्य "मुझे नया कर्नेल न दें" है, तो यह बात बूटलोडर के बजाय पैकेज मैनेजर को बताएं।
apt list --installed 2>/dev/null | grep -E '^linux-(image|headers|generic|virtual|kvm|aws|azure|gcp|oracle)'
sudo apt-mark hold linux-image-virtual linux-headers-virtual
apt-mark showholdपहले कमांड द्वारा प्रिंट किए गए नामों का ही उपयोग करें, क्योंकि क्लाउड इमेजेस आमतौर पर generic के बजाय virtual या kvm फ्लेवर इंस्टॉल करती हैं। एक होल्ड किया गया पैकेज apt upgrade द्वारा छोड़ दिया जाता है, जो इसे The following packages have been kept back: के साथ सूचित करता है, और यह Ubuntu पर unattended upgrades द्वारा भी छोड़ दिया जाता है। इसकी कीमत चुकानी पड़ती है: एक होल्ड किया गया कर्नेल सुरक्षा अपडेट प्राप्त करना बंद कर देता है, इसलिए इसे एक निश्चित समय के लिए पॉज़ (pause) के रूप में देखें और sudo apt-mark unhold के साथ इसे रिलीज़ करें। यदि आप कर्नेल अपडेट से इसलिए बच रहे हैं क्योंकि रीबूट से डाउनटाइम होता है, न कि इसलिए कि कोई कर्नेल खराब है, तो VPS पर live kernel patching इसका बेहतर समाधान है।
अपग्रेड से पहले स्नैपशॉट लें। एक स्नैपशॉट मिनटों में सिस्टम को रिस्टोर कर देता है, जिसमें कंसोल पर टाइपिंग की आवश्यकता नहीं होती और बूटलोडर में अधूरे बदलाव का कोई जोखिम नहीं रहता। स्नैपशॉट लें, अपग्रेड करें, रीबूट करें और सत्यापित करें। यदि नया कर्नेल सही ढंग से काम नहीं करता है, तो रोलबैक करें; बूट पाथ बिल्कुल वैसा ही रहेगा जैसा पहले था।
यदि सर्वर पहले से डाउन है, तो कंसोल या रेस्क्यू इमेज का उपयोग करें। एक बार जब सर्वर बूट नहीं होता है, तो बूटलोडर कॉन्फ़िगरेशन उसे ठीक करने की जगह नहीं है। उस रिकवरी पाथ की अपनी प्रक्रिया है: कर्नेल अपडेट के बाद VPS बूट न होने पर क्या करें।
क्या खराब होता है और आपको क्या संदेश दिखाई देगा
/boot/grub/grub.cfg में किया गया आपका बदलाव गायब हो गया है। एक kernel package install या remove किया गया था, उसकी maintainer script ने update-grub चलाया और file को inputs से फिर से generate किया गया। # DO NOT EDIT THIS FILE header में दो input locations के नाम दिए गए हैं। उन्हें edit करें।
grub-editenv: error: environment block too small। /boot/grub/grubenv गायब है या अधूरा है। इसे sudo grub-editenv /boot/grub/grubenv create के साथ फिर से बनाएँ, फिर अपना मान (value) दोबारा सेट करें और sudo grub-editenv list के साथ पुष्टि करें।
एक pinned kernel VFS: Unable to mount root fs on unknown-block(0,0) के साथ panic करता है। जिस entry को आपने pin किया था, वह ऐसे kernel या initrd की ओर इशारा करती है जो अब disk पर नहीं है। ऐसा आमतौर पर तब होता है जब package को remove कर दिया गया हो लेकिन identifier grubenv में बना रहा हो। रिकवरी के लिए एक working entry के साथ console boot करें, फिर stale मान को हटा दें।
Reboot के बाद uname -r नहीं बदला, जबकि आपको उम्मीद थी कि यह बदल जाएगा। क्रम में तीन चीजों की जाँच करें: क्या grub-editenv list अभी भी आपका मान दिखा रहा है या वह consume हो चुका है; क्या आपके द्वारा सेट किया गया identifier वर्तमान grub.cfg में दिखाई देता है; क्या grub.cfg में set default line मौजूद है जो आपके द्वारा सेट की गई variable को पढ़ती है। इन तीनों में से कोई एक कारण हमेशा स्थिति को स्पष्ट करता है।
Crash के बाद menu अपने आप दिखाई दिया। GRUB एक failed boot को grubenv में recordfail=1 के रूप में record करता है। यह अगले boot पर menu को force करता है ताकि कोई व्यक्ति हस्तक्षेप कर सके। जब machine ठीक हो जाए, तो इसे sudo grub-editenv /boot/grub/grubenv unset recordfail के साथ clear करें।
केवल एक वाक्य याद रखने योग्य है: जिस file को आप edit करते हैं, वह वह file नहीं है जिसे GRUB पढ़ता है। cloud image पर इन दोनों के बीच का अंतर ही भ्रम का मुख्य कारण है। सबसे पहले generated config को पढ़ें। इस page पर लिया गया हर निर्णय इस बात पर आधारित है कि वह वास्तव में क्या कहती है।
FAQ
GRUB_DEFAULT=1 बदलने पर भी मेरा VPS उस kernel से boot क्यों नहीं होता जिसे मैंने चुना है?
क्योंकि Ubuntu cloud image पर जनरेट की गई /boot/grub/grub.cfg में अक्सर केवल एक ही boot entry होती है, इसलिए index 1 का कोई अस्तित्व नहीं होता और GRUB वापस पहली entry पर चला जाता है। इसे sudo grep -cE '^\s*(menuentry|submenu) ' /boot/grub/grub.cfg के साथ confirm करें। उत्तर में 1 की संख्या ही मिलेगी। इसका कारण GRUB_FORCE_PARTUUID है, जिसे image vendor ने /etc/default/grub.d/ के अंतर्गत एक file में set किया है, जो installed kernels की पूरी सूची बनाने के बजाय generator को सीधे boot path पर डाल देता है। grep -rn GRUB_FORCE_PARTUUID /etc/default/grub /etc/default/grub.d/ के साथ उस file को ढूँढें।
मैं केवल एक बार के लिए पिछले kernel से boot कैसे करूँ?
अपने grub.cfg से copy किए गए identifier के साथ sudo grub-reboot '<identifier>' चलाएँ, और फिर provider console को पहले से open रखकर reboot करें। GRUB boot करने से पहले next_entry को clear कर देता है, इसलिए यह विकल्प केवल एक ही प्रयास पर लागू होता है और यदि kernel panic करता है, तो उसे दोबारा retry नहीं किया जाता। sudo grub-editenv list के साथ पुष्टि करें कि value सही जगह पहुँच गई है। इस पर भरोसा करने से पहले sudo grep -n next_entry /boot/grub/grub.cfg चलाएँ, क्योंकि जिस image की config कभी grubenv load नहीं करती, वह बिना किसी error के इस command को ignore कर देगी।
क्या मुझे entry number के आधार पर pin करना चाहिए या identifier के आधार पर?
Identifier के आधार पर। Entry numbers उस सूची में स्थान होते हैं जिसे 10_linux सबसे नए kernel को पहले रखकर फिर से बनाता है, इसलिए किसी भी kernel को install या remove करने पर वे बदल जाते हैं, और एक पुराना 1>2 अभी भी एक वास्तविक लेकिन गलत entry पर resolve होता रहेगा, जिसके बारे में आपको कोई चेतावनी नहीं मिलेगी। Identifiers में kernel version होता है, इसलिए वे या तो आपके द्वारा चुने गए kernel से मेल खाते हैं या resolve होने में विफल हो जाते हैं। उन्हें sudo grep -n menuentry_id_option /boot/grub/grub.cfg के साथ list करें और प्रत्येक entry line पर आने वाली quoted string को copy करें।
क्या bootloader बदलने की तुलना में kernel package को hold करना अधिक सुरक्षित है?
सामान्य लक्ष्य के लिए, हाँ। sudo apt-mark hold linux-image-virtual linux-headers-virtual किसी नए kernel को आने से पूरी तरह रोक देता है, इसलिए boot path कभी नहीं बदलता और ऐसी console से कुछ भी गलत होने की संभावना नहीं रहती जो शायद आपके पास न हो। पहले apt list --installed के साथ अपने box पर installed flavour names की जाँच करें, और apt-mark showhold के साथ hold की पुष्टि करें। इसका नुकसान यह है कि hold किए गए kernel को कोई security fix नहीं मिलता, इसलिए hold करने से पहले यह तय कर लें कि आप sudo apt-mark unhold कब चलाएंगे।