कैननिकल बूट होने की वजह

Android 9 में, बूटलोडर के बूट होने की वजह के स्पेसिफ़िकेशन में ये बदलाव किए गए हैं.

बूट करने की वजहें

बूटलोडर, खास तौर पर उपलब्ध हार्डवेयर और मेमोरी संसाधनों का इस्तेमाल करके यह पता लगाता है कि डिवाइस को फिर से चालू क्यों किया गया है. इसके बाद, वह इस डिटरमिनेशन के बारे में जानकारी देने के लिए androidboot.bootreason=<reason> को Android कर्नेल कमांड लाइन में लॉन्च करता है. init इसके बाद, इस कमांड लाइन को Android प्रॉपर्टी bootloader_boot_reason_prop (ro.boot.bootreason) में भेजने के लिए, इसका अनुवाद करता है. Android 12 या इसके बाद के वर्शन वाले डिवाइसों के लिए, androidboot.bootreason=<reason> को कमांड लाइन के बजाय, बूटकॉन्फ़िगरेशन में जोड़ा जाता है. इसके लिए, 5.10 या इसके बाद के वर्शन का इस्तेमाल किया जाता है.

बूट होने की वजह से जुड़ी खास बातें

Android के पिछले वर्शन में, बूट होने की वजह बताने के लिए एक फ़ॉर्मैट तय किया गया था. इसमें कोई स्पेस इस्तेमाल नहीं किया जाता था और सभी शब्द छोटे अक्षरों में होते थे. साथ ही, इसमें कुछ ज़रूरी शर्तें शामिल थीं, जैसे कि kernel_panic, watchdog, cold/warm/hard की शिकायत करने के लिए. इस फ़ॉर्मैट में, अन्य यूनीक वजहों के लिए भी अनुमति दी जाती थी. इस ढीली शर्त की वजह से, बूट होने की वजह बताने वाली सैकड़ों कस्टम (और कभी-कभी बेमतलब) स्ट्रिंग का इस्तेमाल होने लगा. इससे, मैनेज करने में मुश्किल स्थिति पैदा हो गई. Android के मौजूदा वर्शन के बाद, बूटलोडर से फ़ाइल किए गए ऐसे कॉन्टेंट की वजह से, जिसे पार्स नहीं किया जा सकता या बेमतलब का कॉन्टेंट होने की वजह से bootloader_boot_reason_prop के लिए नियमों का पालन करने से जुड़ी समस्याएं पैदा हो गई हैं.

Android 9 रिलीज़ होने के बाद, Android टीम को पता चला है कि लेगसी bootloader_boot_reason_prop का इस्तेमाल बहुत ज़्यादा किया जा रहा है. साथ ही, इसे रनटाइम के दौरान फिर से नहीं लिखा जा सकता. इसलिए, बूट होने की वजह की जानकारी में कोई भी सुधार, bootloader के डेवलपर के साथ इंटरैक्शन और मौजूदा सिस्टम में बदलाव करने के बाद ही किया जाना चाहिए. इसके लिए, Android टीम:

  • बूटलोडर डेवलपर से जुड़कर, उन्हें इन कामों के लिए बढ़ावा देना:
    • bootloader_boot_reason_prop के लिए, कैननिकल, पार्स की जा सकने वाली, और पहचानी जा सकने वाली वजहें दें.
    • system/core/bootstat/bootstat.cpp kBootReasonMap सूची में शामिल हों.
  • system_boot_reason_prop (sys.boot.reason) का ऐसा सोर्स जोड़ना जिसे कंट्रोल किया जा सकता है और रनटाइम के दौरान फिर से लिखा जा सकता है. सिस्टम ऐप्लिकेशन का एक सीमित सेट (जैसे, bootstat और init) इस प्रॉपर्टी को फिर से लिख सकता है. हालांकि, सभी ऐप्लिकेशन को इसे पढ़ने के लिए, sepolicy से जुड़े अधिकार दिए जा सकते हैं.
  • उपयोगकर्ताओं को बताएं कि सिस्टम को बूट करने की वजह बताने वाली प्रॉपर्टी system_boot_reason_prop में मौजूद कॉन्टेंट पर भरोसा करने से पहले, वे उपयोगकर्ता डेटा के माउंट होने तक इंतज़ार करें.

इतनी देरी क्यों हो गई? bootloader_boot_reason_prop, डिवाइस के चालू होने के शुरुआती समय में उपलब्ध होता है. हालांकि, Android की सुरक्षा नीति के तहत, ज़रूरत के हिसाब से इसे ब्लॉक किया जाता है. ऐसा इसलिए किया जाता है, क्योंकि यह गलत, समझने में मुश्किल, और गैर-कैनोनिकल जानकारी दिखाता है. ज़्यादातर मामलों में, यह जानकारी सिर्फ़ उन डेवलपर को ऐक्सेस करनी होगी जिन्हें बूट सिस्टम की अच्छी जानकारी है. system_boot_reason_prop के साथ बूट करने की वजह के लिए, बेहतर, पार्स किया जा सकने वाला, और कैननिकल एपीआई को भरोसेमंद तरीके से और सटीक तरीके से सिर्फ़ इसके बाद चुना जा सकता है, जब उपयोगकर्ता डेटा माउंट हो गया हो. खास तौर से:

  • उपयोगकर्ता डेटा को माउंट करने से पहले, system_boot_reason_prop में bootloader_boot_reason_prop की वैल्यू शामिल होगी.
  • उपयोगकर्ता डेटा माउंट होने के बाद, system_boot_reason_prop को नीति का पालन करने या ज़्यादा सटीक जानकारी देने के लिए अपडेट किया जा सकता है.

इस वजह से, Android 9 में बूट होने की वजह को आधिकारिक तौर पर हासिल करने से पहले, समय की अवधि बढ़ाई गई है. इससे, बूट होने के दौरान तुरंत सटीक जानकारी (bootloader_boot_reason_prop के साथ) मिलने की जगह, उपयोगकर्ता डेटा के माउंट होने के बाद ही जानकारी उपलब्ध होगी (system_boot_reason_prop के साथ).

बूटस्टेट लॉजिक, ज़्यादा जानकारी वाले और नियमों के हिसाब से bootloader_boot_reason_prop पर निर्भर करता है. जब वह प्रॉपर्टी, अनुमान लगाने लायक फ़ॉर्मैट का इस्तेमाल करती है, तो इससे कंट्रोल किए गए सभी रीबूट और शटडाउन के मामलों की सटीकता बढ़ जाती है. इससे system_boot_reason_prop की सटीकता और मतलब बेहतर और बड़ा हो जाता है.

डिवाइस के चालू होने की वजह का कैननिकल फ़ॉर्मैट

Android 9 में bootloader_boot_reason_prop के लिए, बूट होने की वजह का कैननिकल फ़ॉर्मैट इस सिंटैक्स का इस्तेमाल करता है:

<reason>,<subreason>,<detail>…

फ़ॉर्मैटिंग के नियम:

  • लोअर केस
  • कोई खाली सेल नहीं (अंडरलाइन का इस्तेमाल करें)
  • प्रिंट किए जा सकने वाले सभी वर्ण
  • कॉमा से अलग किए गए reason, subreason, और एक या इससे ज़्यादा detail इंस्टेंस.
    • ज़रूरी reason, जो सबसे ज़्यादा प्राथमिकता वाली वजह बताता है कि डिवाइस को रीस्टार्ट या बंद क्यों करना पड़ा.
    • ज़रूरी नहीं subreason, जो इस बारे में कम शब्दों में जानकारी देता है कि डिवाइस को रीस्टार्ट या बंद क्यों करना पड़ा (या डिवाइस को रीस्टार्ट या बंद करने वाला कौन था).
    • एक या एक से ज़्यादा वैकल्पिक detail वैल्यू. detail किसी सबसिस्टम पर ले जा सकता है, ताकि यह पता लगाया जा सके कि subreason किस सिस्टम की वजह से हुआ है. एक से ज़्यादा detail वैल्यू तय की जा सकती हैं. आम तौर पर, इन वैल्यू को क्रम के हिसाब से अहमियत दी जानी चाहिए. हालांकि, एक ही तरह की कई detail वैल्यू की रिपोर्ट करना भी स्वीकार किया जाता है.

bootloader_boot_reason_prop के लिए कोई वैल्यू न डालने पर, इसे अमान्य माना जाता है. ऐसा इसलिए, क्योंकि इससे अन्य एजेंट, बूट होने की वजह को बाद में इंजेक्ट कर सकते हैं.

वजह से जुड़ी ज़रूरी शर्तें

reason (टर्मिनेशन या कॉमा से पहले का पहला स्पैन) के लिए दी गई वैल्यू, नीचे दिए गए सेट में से किसी एक में होनी चाहिए. इसे कोर, स्ट्रॉन्ग, और ब्लंट वजहों में बांटा गया है:

  • kernel set:
    • ''watchdog"
    • "kernel_panic"
  • ज़्यादा सेट:
    • "recovery"
    • "bootloader"
  • ब्लंट सेट:
    • "cold". आम तौर पर, यह बताता है कि मेमोरी के साथ-साथ सभी डिवाइसों को पूरी तरह से रीसेट किया गया है.
    • "hard". आम तौर पर यह बताता है कि हार्डवेयर को रीसेट कर दिया गया है और ramoops में लगातार कॉन्टेंट बना रहना चाहिए.
    • "warm". आम तौर पर, इससे पता चलता है कि मेमोरी और डिवाइसों में कुछ जानकारी सेव रहती है. साथ ही, ramoops (pstore कर्नेल में ड्राइवर देखें) बैकिंग स्टोर में हमेशा मौजूद कॉन्टेंट होता है.
    • "shutdown"
    • "reboot". आम तौर पर इसका मतलब है कि ramoops की स्थिति के बारे में जानकारी नहीं है और हार्डवेयर की स्थिति के बारे में जानकारी नहीं है. यह वैल्यू, cold, hard, और warm वैल्यू के तौर पर काम करती है. इनसे यह पता चलता है कि डिवाइस को कितनी बार रीसेट किया गया है.

बूटलोडर को एक कर्नेल सेट या ब्लंट सेट reason देना होगा. अगर subreason तय किया जा सकता है, तो हमारा सुझाव है कि आप subreason दें. उदाहरण के लिए, पावर बटन को दबाकर रखने पर, डिवाइस को ramoops बैकअप के साथ या उसके बिना भी बूट किया जा सकता है. ऐसे में, डिवाइस को बूट करने की वजह के तौर पर "reboot,longkey" दिखेगा.

कोई भी फ़र्स्ट-स्पैन reason, किसी भी subreason या detail का हिस्सा नहीं हो सकता. हालांकि, उपयोगकर्ता स्पेस से, कर्नेल सेट की वजहें नहीं दी जा सकतीं. इसलिए, "watchdog" का फिर से इस्तेमाल किया जा सकता है. इसके लिए, सोर्स की जानकारी (उदाहरण के लिए, "reboot,watchdog,service_manager_unresponsive" या "reboot,software,watchdog") के साथ, एक साफ़ तौर पर बताई गई वजह दी जा सकती है.

बूट करने से जुड़ी वजहों को समझने के लिए, विशेषज्ञ की इंटरनल जानकारी की ज़रूरत नहीं होनी चाहिए. इसके अलावा, यह भी ज़रूरी नहीं है कि उपयोगकर्ता, जानकारी से जुड़ी रिपोर्ट को आसानी से समझ सके. उदाहरण: "shutdown,vbxd" (खराब), "shutdown,uv" (बेहतर), "shutdown,undervoltage" (प्राथमिकता).

वजह-उपवजह के कॉम्बिनेशन

Android, reason-subreason के ऐसे कॉम्बिनेशन का सेट बनाकर रखता है जिन्हें सामान्य इस्तेमाल में ज़्यादा इस्तेमाल नहीं किया जाना चाहिए. हालांकि, अगर कॉम्बिनेशन से जुड़ी स्थिति के बारे में सटीक जानकारी मिलती है, तो हर मामले के हिसाब से इनका इस्तेमाल किया जा सकता है. रिज़र्व किए गए कॉम्बिनेशन के उदाहरण:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (thermald से)
  • "shutdown,battery"
  • "shutdown,battery,thermal" (BatteryStatsService से)
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

ज़्यादा जानकारी के लिए, system/core/bootstat/bootstat.cpp में kBootReasonMap और Android के सोर्स डेटा स्टोर करने की जगह में इससे जुड़ा Git चेंजलॉग इतिहास देखें.

डिवाइस के बूट होने की वजहों की रिपोर्ट करना

बूट होने की सभी वजहें, बूटलोडर से या कैननिकल बूट होने की वजह में रिकॉर्ड की गई होनी चाहिए. इन्हें system/core/bootstat/bootstat.cpp के kBootReasonMap सेक्शन में रिकॉर्ड किया जाना चाहिए. kBootReasonMap सूची में, नीतियों का पालन न करने और नीतियों का पालन करने से जुड़ी वजहें शामिल होती हैं. बूटलोडर डेवलपर को यहां सिर्फ़ नई वजहें रजिस्टर करनी चाहिए, जो नीति के मुताबिक हों. साथ ही, नीति का पालन न करने की वजहें तब तक रजिस्टर नहीं करनी चाहिए, जब तक कि प्रॉडक्ट पहले से ही शिप न हो गया हो और उसमें बदलाव न किया जा सके.

हमारा सुझाव है कि आप system/core/bootstat/bootstat.cpp में, मौजूदा और नीतियों का पालन करने वाली एंट्री का इस्तेमाल करें. साथ ही, नीतियों का पालन न करने वाली स्ट्रिंग का इस्तेमाल करने से पहले, सावधानी बरतें. दिशा-निर्देश के मुताबिक, यह:

  • ठीक है, ताकि bootloader से "kernel_panic" की शिकायत की जा सके. ऐसा इसलिए, क्योंकि bootstat, kernel_panic signatures के लिए ramoops की जांच कर सकता है, ताकि सब-वजह को कैननिकल system_boot_reason_prop में बेहतर बनाया जा सके.
  • kBootReasonMap में, नीतियों का पालन न करने वाली स्ट्रिंग की शिकायत करना ठीक नहीं है. जैसे, bootloader से "panic"). ऐसा करने पर, reason को बेहतर बनाने की सुविधा काम नहीं करेगी.

उदाहरण के लिए, अगर kBootReasonMap में "wdog_bark" है, तो bootloader डेवलपर को:

  • इसे "watchdog,bark" में बदलें और सूची में kBootReasonMap में जोड़ें.
  • देखें कि टेक्नोलॉजी के बारे में जानकारी न रखने वाले लोगों के लिए, "bark" का क्या मतलब है. साथ ही, यह भी तय करें कि क्या कोई ऐसा subreason उपलब्ध है जो ज़्यादा काम का हो.

बूट करने की वजह के मुताबिक होने की पुष्टि करना

फ़िलहाल, Android ऐसा कोई चालू CTS टेस्ट उपलब्ध नहीं कराता है जो बूटलोडर से मिलने वाली सभी संभावित वजहों को सटीक तरीके से ट्रिगर या जांच कर सके. हालांकि, पार्टनर अब भी काम करने की जांच करने के लिए, पैसिव टेस्ट चला सकते हैं.

इसलिए, बूटलोडर से जुड़ी शर्तों का पालन करने के लिए, बूटलोडर डेवलपर को ऊपर बताए गए नियमों और दिशा-निर्देशों का पालन करना होगा. हम ऐसे डेवलपर से अनुरोध करते हैं कि वे AOSP (खास तौर पर system/core/bootstat/bootstat.cpp) में योगदान दें. साथ ही, इस फ़ोरम का इस्तेमाल, बूट होने से जुड़ी समस्याओं के बारे में चर्चा करने के लिए करें.