लेगसी ए/बी सिस्टम अपडेट को सीमलेस अपडेट भी कहा जाता है. ये अपडेट यह पक्का करते हैं कि ओवर-द-एयर (ओटीए) अपडेट के दौरान, डिस्क पर बूटिंग सिस्टम काम करता रहे. इस तरीके से, अपडेट के बाद डिवाइस के काम न करने की संभावना कम हो जाती है. इसका मतलब है कि डिवाइस बदलने की ज़रूरत कम पड़ती है. साथ ही, मरम्मत और वारंटी केंद्रों पर डिवाइस को रीफ़्लैश करने की ज़रूरत भी कम पड़ती है. ChromeOS जैसे अन्य कमर्शियल-ग्रेड ऑपरेटिंग सिस्टम भी, A/B अपडेट का इस्तेमाल करते हैं.
A/B सिस्टम अपडेट और उनके काम करने के तरीके के बारे में ज़्यादा जानने के लिए, पार्टिशन चुनना (स्लॉट) लेख पढ़ें.
A/B सिस्टम अपडेट से ये फ़ायदे मिलते हैं:
- सिस्टम के चालू रहने के दौरान, ओटीए अपडेट हो सकते हैं. इससे उपयोगकर्ता को कोई परेशानी नहीं होती. उपयोगकर्ता, ओटीए अपडेट के दौरान अपने डिवाइसों का इस्तेमाल जारी रख सकते हैं. अपडेट के दौरान, डिवाइस के बंद होने का समय सिर्फ़ तब होता है, जब डिवाइस अपडेट किए गए डिस्क पार्टीशन में रीबूट होता है.
- अपडेट के बाद, रीबूट होने में उतना ही समय लगता है जितना सामान्य रीबूट में लगता है.
- अगर ओटीए अपडेट लागू नहीं होता है (उदाहरण के लिए, फ़्लैशिंग की समस्या की वजह से), तो उपयोगकर्ता पर इसका कोई असर नहीं पड़ेगा. उपयोगकर्ता पुराने ओएस का इस्तेमाल जारी रखेगा. साथ ही, क्लाइंट के पास अपडेट को फिर से आज़माने का विकल्प होगा.
- अगर ओटीए अपडेट लागू होने के बाद भी डिवाइस बूट नहीं होता है, तो डिवाइस पुराने पार्टीशन में वापस रीबूट हो जाएगा और इसका इस्तेमाल किया जा सकेगा. क्लाइंट के पास, अपडेट करने की कोशिश फिर से करने का विकल्प होता है.
- किसी भी गड़बड़ी (जैसे कि I/O गड़बड़ियां) का असर सिर्फ़ इस्तेमाल नहीं किए गए पार्टिशन सेट पर पड़ता है. साथ ही, इसे फिर से आज़माया जा सकता है. इस तरह की गड़बड़ियां होने की संभावना भी कम हो जाती है, क्योंकि उपयोगकर्ता अनुभव को बेहतर बनाए रखने के लिए, I/O लोड को जान-बूझकर कम रखा जाता है.
-
अपडेट को A/B डिवाइसों पर स्ट्रीम किया जा सकता है. इससे, पैकेज को इंस्टॉल करने से पहले डाउनलोड करने की ज़रूरत नहीं पड़ती. स्ट्रीमिंग का मतलब है कि अपडेट पैकेज को
/data
या/cache
पर सेव करने के लिए, उपयोगकर्ता के पास ज़रूरत के मुताबिक खाली जगह होना ज़रूरी नहीं है. - कैश मेमोरी के पार्टीशन का इस्तेमाल अब OTA अपडेट पैकेज सेव करने के लिए नहीं किया जाता. इसलिए, यह पक्का करने की ज़रूरत नहीं है कि कैश मेमोरी का पार्टीशन आने वाले समय के अपडेट के लिए काफ़ी बड़ा हो.
- dm-verity इस बात की गारंटी देता है कि डिवाइस पर बिना किसी गड़बड़ी वाली इमेज बूट होगी. अगर किसी डिवाइस में खराब OTA या dm-verity की समस्या की वजह से बूट नहीं हो रहा है, तो डिवाइस को पुरानी इमेज में रीबूट किया जा सकता है. (Android वेरिफ़ाइड बूट के लिए, A/B अपडेट की ज़रूरत नहीं होती.)
A/B सिस्टम अपडेट के बारे में जानकारी
A/B अपडेट के लिए, क्लाइंट और सिस्टम, दोनों में बदलाव करने पड़ते हैं. हालांकि, OTA पैकेज सर्वर में बदलाव करने की ज़रूरत नहीं होनी चाहिए: अपडेट पैकेज अब भी एचटीटीपीएस पर उपलब्ध कराए जाते हैं. Google के OTA इंफ़्रास्ट्रक्चर का इस्तेमाल करने वाले डिवाइसों के लिए, सिस्टम में होने वाले सभी बदलाव AOSP में होते हैं. साथ ही, क्लाइंट कोड Google Play services उपलब्ध कराता है. Google के ओटीए इन्फ़्रास्ट्रक्चर का इस्तेमाल न करने वाले ओईएम, AOSP सिस्टम कोड का फिर से इस्तेमाल कर पाएंगे. हालांकि, उन्हें अपना क्लाइंट उपलब्ध कराना होगा.
अपने क्लाइंट को प्रॉडक्ट सप्लाई करने वाले ओईएम के लिए, क्लाइंट को यह काम करना होगा:
- तय करें कि अपडेट कब करना है. A/B अपडेट बैकग्राउंड में होते हैं. इसलिए, अब इन्हें उपयोगकर्ता शुरू नहीं कर सकते. उपयोगकर्ताओं को परेशानी से बचाने के लिए, हमारा सुझाव है कि डिवाइस के रखरखाव के दौरान अपडेट शेड्यूल किए जाएं. जैसे, रात में और वाई-फ़ाई से कनेक्ट होने पर. हालांकि, आपका क्लाइंट आपकी पसंद के किसी भी अनुमानित तरीके का इस्तेमाल कर सकता है.
- अपने ओटीए पैकेज सर्वर से संपर्क करें और पता लगाएं कि कोई अपडेट उपलब्ध है या नहीं. यह कोड, आपके मौजूदा क्लाइंट कोड जैसा ही होना चाहिए. हालांकि, आपको यह बताना होगा कि डिवाइस पर A/B टेस्टिंग की सुविधा काम करती है. (Google के क्लाइंट में, उपयोगकर्ताओं के लिए अभी जांच करें बटन भी शामिल होता है, ताकि वे नया अपडेट देख सकें.)
-
अगर कोई अपडेट पैकेज उपलब्ध है, तो उसके एचटीटीपीएस यूआरएल के साथ
update_engine
को कॉल करें.update_engine
अपडेट पैकेज को स्ट्रीम करते समय, फ़िलहाल इस्तेमाल नहीं किए जा रहे पार्टीशन पर मौजूद रॉ ब्लॉक को अपडेट करेगा. -
update_engine
नतीजे के कोड के आधार पर, अपने सर्वर को इंस्टॉलेशन के पूरा होने या फ़ेल होने की जानकारी दें. अपडेट लागू होने पर,update_engine
बूटलोडर को अगली बार रीबूट करने पर नए ओएस में बूट करने के लिए कहेगा. अगर नया ओएस बूट नहीं होता है, तो बूटलोडर पुराने ओएस पर वापस आ जाएगा. इसलिए, क्लाइंट को कुछ भी करने की ज़रूरत नहीं है. अगर अपडेट नहीं हो पाता है, तो क्लाइंट को यह तय करना होगा कि उसे कब और कितनी बार फिर से कोशिश करनी है. यह फ़ैसला, गड़बड़ी के कोड के आधार पर लिया जाएगा. उदाहरण के लिए, एक अच्छा क्लाइंट यह पहचान सकता है कि ओटीए का कोई हिस्सा ("डिफ़") काम नहीं कर रहा है. ऐसे में, वह ओटीए का पूरा पैकेज इस्तेमाल करने की कोशिश करेगा.
क्लाइंट के पास ये विकल्प होते हैं:
- उपयोगकर्ता को रीबूट करने के लिए सूचना दिखाएं. अगर आपको ऐसी नीति लागू करनी है जिसमें उपयोगकर्ता को नियमित रूप से अपडेट करने के लिए कहा जाता है, तो इस सूचना को अपने क्लाइंट में जोड़ा जा सकता है. अगर क्लाइंट लोगों को सूचना नहीं देता है, तो लोगों को अगली बार रीबूट करने पर अपडेट मिल जाएगा. (Google के क्लाइंट के पास, हर अपडेट के लिए कॉन्फ़िगर की जा सकने वाली देरी का विकल्प होता है.)
- उपयोगकर्ताओं को एक सूचना दिखाएं. इसमें बताएं कि उन्होंने नए ओएस वर्शन में बूट किया है या उन्हें ऐसा करना था, लेकिन वे पुराने ओएस वर्शन पर वापस आ गए हैं. (Google का क्लाइंट आम तौर पर, इनमें से कोई भी काम नहीं करता.)
सिस्टम के हिसाब से, A/B सिस्टम अपडेट से इन पर असर पड़ता है:
-
पार्टिशन चुनने (स्लॉट),
update_engine
डेमॉन, और बूटलोडर के साथ इंटरैक्शन (इसके बारे में यहां बताया गया है) - बिल्ड प्रोसेस और ओटीए अपडेट पैकेज जनरेट करना. इसके बारे में A/B अपडेट लागू करना में बताया गया है
बंटवारा चुनना (स्लॉट)
A/B सिस्टम अपडेट में, दो सेट के पार्टीशन का इस्तेमाल किया जाता है. इन्हें स्लॉट कहा जाता है. आम तौर पर, ये स्लॉट A और स्लॉट B होते हैं. सिस्टम, current स्लॉट से चलता है. वहीं, सामान्य ऑपरेशन के दौरान, unused स्लॉट में मौजूद पार्टीशन को सिस्टम ऐक्सेस नहीं करता. इस तरीके से, अपडेट के दौरान होने वाली गड़बड़ियों को ठीक किया जा सकता है. इसके लिए, इस्तेमाल न किए गए स्लॉट को फ़ॉलबैक के तौर पर रखा जाता है: अगर अपडेट के दौरान या उसके तुरंत बाद कोई गड़बड़ी होती है, तो सिस्टम पुराने स्लॉट पर वापस आ सकता है और सिस्टम को चालू रख सकता है. इस लक्ष्य को पूरा करने के लिए, मौजूदा स्लॉट में इस्तेमाल किए गए किसी भी पार्टीशन को ओटीए अपडेट के हिस्से के तौर पर अपडेट नहीं किया जाना चाहिए. इसमें वे पार्टीशन भी शामिल हैं जिनकी सिर्फ़ एक कॉपी है.
हर स्लॉट में bootable एट्रिब्यूट होता है. इससे पता चलता है कि स्लॉट में सही सिस्टम है या नहीं, जिससे डिवाइस बूट हो सकता है. सिस्टम चालू होने पर, मौजूदा स्लॉट बूट किया जा सकता है. हालांकि, दूसरे स्लॉट में सिस्टम का पुराना (अब भी सही) वर्शन, नया वर्शन या अमान्य डेटा हो सकता है. मौजूदा स्लॉट कोई भी हो, एक स्लॉट चालू स्लॉट होता है. बूटलोडर, अगले बूट पर इसी स्लॉट से बूट करेगा. इसके अलावा, एक स्लॉट पसंदीदा स्लॉट होता है.
हर स्लॉट में, उपयोगकर्ता स्पेस के ज़रिए सेट किया गया successful एट्रिब्यूट भी होता है. यह सिर्फ़ तब काम का होता है, जब स्लॉट बूट भी किया जा सकता हो. स्लॉट को बूट, रन, और अपडेट किया जा सकता हो. अगर किसी बूट किए जा सकने वाले स्लॉट से बूट करने की कई बार कोशिश करने के बाद भी, उसे 'बूट किया जा सका' के तौर पर मार्क नहीं किया गया है, तो बूटलोडर को उसे 'बूट नहीं किया जा सका' के तौर पर मार्क करना चाहिए. इसमें चालू स्लॉट को बूट किए जा सकने वाले किसी दूसरे स्लॉट पर ले जाना भी शामिल है. आम तौर पर, चालू स्लॉट को उस स्लॉट पर ले जाया जाता है जो नए, चालू स्लॉट में बूट करने की कोशिश से ठीक पहले चल रहा था. इंटरफ़ेस की खास जानकारी
boot_control.h
में दी गई है.
Update Engine Daemon
A/B सिस्टम अपडेट, बैकग्राउंड डेमॉन का इस्तेमाल करते हैं. इसे update_engine
कहा जाता है. यह सिस्टम को नए और अपडेट किए गए वर्शन में बूट करने के लिए तैयार करता है. यह डेमॉन, ये कार्रवाइयां कर सकता है:
- OTA पैकेज में दिए गए निर्देशों के मुताबिक, मौजूदा स्लॉट के A/B पार्टीशन से डेटा पढ़ें और इस्तेमाल नहीं किए गए स्लॉट के A/B पार्टीशन में कोई भी डेटा लिखें.
- पहले से तय किए गए वर्कफ़्लो में
boot_control
इंटरफ़ेस को कॉल करें. - ओटीए पैकेज में दिए गए निर्देशों के मुताबिक, इस्तेमाल नहीं किए गए सभी स्लॉट पार्टीशन लिखने के बाद, नए पार्टीशन से पोस्ट-इंस्टॉल प्रोग्राम चलाएं. (ज़्यादा जानकारी के लिए, इंस्टॉल करने के बाद लेख पढ़ें).
update_engine
डेमॉन, बूट प्रोसेस में शामिल नहीं होता. इसलिए, SELinux की नीतियों और मौजूदा स्लॉट में मौजूद सुविधाओं के ज़रिए, अपडेट के दौरान इसकी गतिविधियों को सीमित किया जाता है. इन नीतियों और सुविधाओं को तब तक अपडेट नहीं किया जा सकता, जब तक सिस्टम नए वर्शन में बूट न हो जाए. सिस्टम को बेहतर बनाए रखने के लिए, अपडेट की प्रोसेस में ये बदलाव नहीं होने चाहिए: पार्टीशन टेबल में बदलाव, मौजूदा स्लॉट में मौजूद पार्टीशन के कॉन्टेंट में बदलाव, और फ़ैक्ट्री रीसेट करने पर वाइप न किए जा सकने वाले नॉन-ए/बी पार्टीशन के कॉन्टेंट में बदलाव.
इंजन के सोर्स को अपडेट करना
update_engine
सोर्स, system/update_engine
में मौजूद है. A/B OTA dexopt फ़ाइलों को installd
और पैकेज मैनेजर के बीच बांटा जाता है:
-
frameworks/native/cmds/installd/
ota* में ये चीज़ें शामिल हैं: पोस्टइंस्टॉल स्क्रिप्ट, chroot के लिए बाइनरी, installd क्लोन जो dex2oat को कॉल करता है, ओटीए के बाद मूव-आर्टफ़ैक्ट स्क्रिप्ट, और मूव स्क्रिप्ट के लिए rc फ़ाइल. -
frameworks/base/services/core/java/com/android/server/pm/OtaDexoptService.java
(plusOtaDexoptShellCommand
) एक पैकेज मैनेजर है. यह ऐप्लिकेशन के लिए dex2oat कमांड तैयार करता है.
काम करने वाले उदाहरण के लिए, /device/google/marlin/device-common.mk
देखें.
इंजन के लॉग अपडेट करना
Android 8.x और इससे पहले के वर्शन के लिए, update_engine
लॉग यहां मिल सकते हैं:
logcat
और गड़बड़ी की रिपोर्ट में. update_engine
लॉग को फ़ाइल सिस्टम में उपलब्ध कराने के लिए, अपने बिल्ड में ये बदलाव करें:
इन बदलावों से, update_engine
के सबसे नए लॉग की कॉपी /data/misc/update_engine_log/update_engine.YEAR-TIME
में सेव हो जाती है. मौजूदा लॉग के अलावा, सबसे हाल के पांच लॉग /data/misc/update_engine_log/
में सेव किए जाते हैं. log ग्रुप आईडी वाले उपयोगकर्ता, फ़ाइल सिस्टम के लॉग ऐक्सेस कर पाएंगे.
बूटलोडर इंटरैक्शन
boot_control
HAL का इस्तेमाल update_engine
करता है. साथ ही, यह अन्य डेमॉन भी कर सकते हैं. इसका इस्तेमाल बूटलोडर को यह निर्देश देने के लिए किया जाता है कि उसे किस डिवाइस से बूट करना है. उदाहरण के तौर पर, यहां कुछ सामान्य स्थितियां और उनसे जुड़ी स्थितियां दी गई हैं:
- सामान्य स्थिति: सिस्टम, मौजूदा स्लॉट से चल रहा है. यह स्लॉट A या B में से कोई भी हो सकता है. अब तक कोई अपडेट लागू नहीं किया गया है. सिस्टम का मौजूदा स्लॉट बूट किया जा सकता है, यह चालू है, और यह ऐक्टिव स्लॉट है.
- अपडेट जारी है: सिस्टम, स्लॉट B से चल रहा है. इसलिए, स्लॉट B बूट किया जा सकने वाला, अपडेट हो चुका, और चालू स्लॉट है. स्लॉट A को बूट नहीं किया जा सकने वाला स्लॉट के तौर पर मार्क किया गया है, क्योंकि स्लॉट A का कॉन्टेंट अपडेट किया जा रहा है, लेकिन यह प्रोसेस अभी पूरी नहीं हुई है. इस स्थिति में रीबूट करने पर, डिवाइस को स्लॉट B से बूट करना जारी रखना चाहिए.
- अपडेट लागू हो गया है, रीबूट होना बाकी है: सिस्टम, स्लॉट B से चल रहा है. स्लॉट B बूट किया जा सकता है और यह काम कर रहा है. हालांकि, स्लॉट A को ऐक्टिव के तौर पर मार्क किया गया था. इसलिए, इसे बूट किया जा सकता है के तौर पर मार्क किया गया है. स्लॉट A को अब तक 'सफल' के तौर पर मार्क नहीं किया गया है. साथ ही, बूटलोडर को स्लॉट A से बूट करने के लिए कुछ बार कोशिश करनी चाहिए.
-
सिस्टम को नए अपडेट के साथ रीबूट किया गया: सिस्टम, पहली बार स्लॉट A से चल रहा है. स्लॉट B अब भी बूट किया जा सकता है और यह काम कर रहा है. वहीं, स्लॉट A को सिर्फ़ बूट किया जा सकता है. यह अब भी चालू है, लेकिन काम नहीं कर रहा है. उपयोगकर्ता स्पेस डेमॉन,
update_verifier
, को कुछ जांचों के बाद स्लॉट A को 'सफल' के तौर पर मार्क करना चाहिए.
स्ट्रीमिंग से जुड़े अपडेट पाने की सुविधा
उपयोगकर्ताओं के डिवाइसों में, अपडेट पैकेज डाउनलोड करने के लिए हमेशा ज़रूरत के मुताबिक स्टोरेज नहीं होता./data
ओईएम और उपयोगकर्ता, दोनों ही /cache
पार्टीशन पर जगह बर्बाद नहीं करना चाहते. इसलिए, कुछ उपयोगकर्ताओं को अपडेट नहीं मिलते, क्योंकि डिवाइस में अपडेट पैकेज को सेव करने के लिए जगह नहीं होती. इस समस्या को हल करने के लिए, Android 8.0 में स्ट्रीमिंग ए/बी अपडेट की सुविधा जोड़ी गई है. इससे डाउनलोड किए गए ब्लॉक सीधे तौर पर B पार्टीशन में लिखे जाते हैं. इसके लिए, ब्लॉक को /data
पर सेव करने की ज़रूरत नहीं होती. स्ट्रीमिंग A/B अपडेट के लिए, कुछ समय के लिए बहुत कम स्टोरेज की ज़रूरत होती है. साथ ही, इसके लिए सिर्फ़ 100 केआईबी मेटाडेटा के लिए स्टोरेज की ज़रूरत होती है.
Android 7.1 में स्ट्रीमिंग अपडेट चालू करने के लिए, इन पैच को चेरीपिक करें:
- प्रॉक्सी रिज़ॉल्यूशन का अनुरोध रद्द करने की अनुमति दें
- प्रॉक्सियों को हल करते समय ट्रांसफ़र बंद करने की समस्या ठीक की गई
- Add unit test for TerminateTransfer between ranges
- RetryTimeoutCallback() को क्लीनअप करें
Android 7.1 और इसके बाद के वर्शन में, A/B अपडेट को स्ट्रीम करने के लिए इन पैच की ज़रूरत होती है. भले ही, Google Mobile Services (GMS) या किसी अन्य अपडेट क्लाइंट का इस्तेमाल किया जा रहा हो.
A/B टेस्ट के अपडेट की अवधि
अपडेट की प्रोसेस तब शुरू होती है, जब डाउनलोड करने के लिए कोई ओटीए पैकेज (कोड में इसे payload कहा जाता है) उपलब्ध होता है. डिवाइस में मौजूद नीतियां, बैटरी लेवल, उपयोगकर्ता की गतिविधि, चार्जिंग की स्थिति या अन्य नीतियों के आधार पर पेलोड डाउनलोड करने और लागू करने में देरी कर सकती हैं. इसके अलावा, अपडेट बैकग्राउंड में होता है. इसलिए, उपयोगकर्ताओं को यह पता नहीं चल पाता कि अपडेट हो रहा है. इन सभी का मतलब है कि अपडेट की प्रोसेस किसी भी समय रुक सकती है. ऐसा नीतियों, अचानक रीबूट होने या उपयोगकर्ता की कार्रवाइयों की वजह से हो सकता है.
इसके अलावा, ओटीए पैकेज में मौजूद मेटाडेटा से पता चलता है कि अपडेट को स्ट्रीम किया जा सकता है. इसी पैकेज का इस्तेमाल, स्ट्रीमिंग के बिना इंस्टॉल करने के लिए भी किया जा सकता है. सर्वर, मेटाडेटा का इस्तेमाल करके क्लाइंट को यह बता सकता है कि वह स्ट्रीमिंग कर रहा है. इससे क्लाइंट, ओटीए को update_engine
को सही तरीके से सौंप देगा. डिवाइस बनाने वाली कंपनियां, अपने सर्वर और क्लाइंट के साथ स्ट्रीमिंग अपडेट की सुविधा चालू कर सकती हैं. इसके लिए, उन्हें यह पक्का करना होगा कि सर्वर यह पहचान ले कि अपडेट स्ट्रीम किया जा रहा है. इसके अलावा, क्लाइंट को स्ट्रीमिंग के लिए update_engine
पर सही कॉल करना होगा. पैकेज के स्ट्रीमिंग वैरिएंट का इस्तेमाल करके, मैन्युफ़ैक्चरर क्लाइंट को फ़्लैग भेज सकते हैं. इससे फ़्रेमवर्क साइड पर स्ट्रीमिंग के तौर पर हैंड ऑफ़ ट्रिगर हो जाता है.
Payload उपलब्ध होने के बाद, अपडेट करने की प्रोसेस इस तरह होती है:
चरण | गतिविधियां |
---|---|
1 |
मौजूदा स्लॉट (या "सोर्स स्लॉट") को markBootSuccessful() के साथ, 'सफल' के तौर पर मार्क किया जाता है. अगर ऐसा पहले से नहीं किया गया है, तो ऐसा किया जाता है.
|
2 |
इस्तेमाल न किए गए स्लॉट (या "टारगेट स्लॉट") को बूट न किया जा सकने वाला स्लॉट के तौर पर मार्क किया जाता है. इसके लिए, setSlotAsUnbootable() फ़ंक्शन को कॉल किया जाता है. अपडेट की शुरुआत में, मौजूदा स्लॉट को हमेशा 'अपडेट हो गया' के तौर पर मार्क किया जाता है. इससे बूटलोडर को ऐसे स्लॉट पर वापस जाने से रोका जा सकता है जिसका इस्तेमाल नहीं किया गया है. इस स्लॉट में जल्द ही अमान्य डेटा होगा. अगर सिस्टम अपडेट लागू करने की स्थिति में पहुंच गया है, तो मौजूदा स्लॉट को 'अपडेट हो गया' के तौर पर मार्क किया जाता है. भले ही, अन्य मुख्य कॉम्पोनेंट काम न कर रहे हों. जैसे, क्रैश लूप में यूज़र इंटरफ़ेस (यूआई). ऐसा इसलिए होता है, क्योंकि इन समस्याओं को ठीक करने के लिए नया सॉफ़्टवेयर पुश किया जा सकता है. अपडेट पेलोड, एक ओपेक ब्लॉब होता है. इसमें नए वर्शन पर अपडेट करने के निर्देश होते हैं. अपडेट पेलोड में यह जानकारी शामिल होती है:
|
3 | पेलोड का मेटाडेटा डाउनलोड किया जाता है. |
4 | मेटाडेटा में तय की गई हर कार्रवाई के लिए, क्रम से यह प्रोसेस होती है: कार्रवाई से जुड़ा डेटा (अगर कोई हो) मेमोरी में डाउनलोड किया जाता है, कार्रवाई लागू की जाती है, और कार्रवाई से जुड़ी मेमोरी को हटा दिया जाता है. |
5 | पूरे पार्टीशन को फिर से पढ़ा जाता है और अनुमानित हैश से उसकी पुष्टि की जाती है. |
6 | इंस्टॉल करने के बाद का चरण (अगर कोई हो) पूरा किया जाता है. किसी भी चरण को पूरा करते समय गड़बड़ी होने पर, अपडेट नहीं हो पाता. इसके बाद, शायद किसी दूसरे पेलोड के साथ अपडेट करने की कोशिश की जाती है. अगर अब तक के सभी चरण पूरे हो गए हैं, तो अपडेट हो जाएगा और आखिरी चरण पूरा हो जाएगा. |
7 |
setActiveBootSlot() को कॉल करके, इस्तेमाल न किए गए स्लॉट को चालू के तौर पर मार्क किया जाता है.
इस्तेमाल नहीं किए गए स्लॉट को चालू के तौर पर मार्क करने का मतलब यह नहीं है कि वह बूट हो जाएगा. अगर बूटलोडर (या सिस्टम) को यह पता चलता है कि बूटिंग की स्थिति सही नहीं है, तो वह चालू स्लॉट को वापस स्विच कर सकता है.
|
8 |
इंस्टॉल करने के बाद (नीचे बताया गया है), "नया अपडेट" वर्शन से प्रोग्राम चलाने का मतलब है कि प्रोग्राम अब भी पुराने वर्शन में चल रहा है. अगर OTA पैकेज में यह तय किया गया है, तो यह चरण ज़रूरी है और प्रोग्राम को एक्ज़िट कोड 0 के साथ वापस आना चाहिए. ऐसा न होने पर, अपडेट नहीं हो पाएगा.
|
9 |
जब सिस्टम नए स्लॉट में बूट हो जाता है और रीबूट के बाद की जांच पूरी कर लेता है, तब मौजूदा स्लॉट (पहले "टारगेट स्लॉट") को markBootSuccessful() कॉल करके, 'सफल' के तौर पर मार्क किया जाता है.
|
इंस्टॉल करने के बाद
हर उस पार्टीशन के लिए जहां इंस्टॉलेशन के बाद का चरण तय किया गया है,
update_engine
नए पार्टीशन को किसी खास जगह पर माउंट करता है और माउंट किए गए पार्टीशन के हिसाब से, OTA में तय किए गए प्रोग्राम को एक्ज़ीक्यूट करता है. उदाहरण के लिए, अगर सिस्टम पार्टीशन में पोस्ट-इंस्टॉल प्रोग्राम को usr/bin/postinstall
के तौर पर तय किया गया है, तो इस्तेमाल नहीं किए गए स्लॉट से इस पार्टीशन को किसी तय जगह (जैसे कि /postinstall_mount
) पर माउंट किया जाएगा. इसके बाद, /postinstall_mount/usr/bin/postinstall
कमांड को लागू किया जाएगा.
इंस्टॉल करने के बाद, पुराने कर्नल को ये काम करने होंगे:
- नए फ़ाइल सिस्टम फ़ॉर्मैट को माउंट करें. फ़ाइल सिस्टम का टाइप तब तक नहीं बदला जा सकता, जब तक कि पुराने कर्नल में इसके लिए सहायता उपलब्ध न हो. इसमें कंप्रेस किए गए फ़ाइल सिस्टम (जैसे, SquashFS) का इस्तेमाल करने पर, कंप्रेस करने के लिए इस्तेमाल किया गया एल्गोरिदम जैसी जानकारी शामिल होती है.
-
नए पार्टीशन के पोस्ट-इंस्टॉल प्रोग्राम के फ़ॉर्मैट के बारे में जानें. अगर एक्ज़ीक्यूटेबल और लिंक करने लायक फ़ॉर्मैट (ईएलएफ़) बाइनरी का इस्तेमाल किया जा रहा है, तो यह पुराने कर्नल के साथ काम करनी चाहिए. उदाहरण के लिए, अगर आर्किटेक्चर को 32-बिट से 64-बिट बिल्ड में बदल दिया गया है, तो 64-बिट का नया प्रोग्राम, 32-बिट के पुराने कर्नल पर काम करना चाहिए. जब तक लोडर (
ld
) को अन्य पाथ इस्तेमाल करने या स्टैटिक बाइनरी बनाने का निर्देश नहीं दिया जाता, तब तक लाइब्रेरी को पुरानी सिस्टम इमेज से लोड किया जाएगा, न कि नई इमेज से.
उदाहरण के लिए, शेल स्क्रिप्ट का इस्तेमाल पोस्ट-इंस्टॉल प्रोग्राम के तौर पर किया जा सकता है. इसे पुराने सिस्टम के शेल बाइनरी से इंटरप्रेट किया जाता है. इसके सबसे ऊपर #!
मार्कर होता है. इसके बाद, ज़्यादा जटिल बाइनरी पोस्ट-इंस्टॉल प्रोग्राम को चलाने के लिए, नए एनवायरमेंट से लाइब्रेरी पाथ सेट अप किए जा सकते हैं. इसके अलावा, इंस्टॉल करने के बाद के चरण को किसी छोटे पार्टीशन से चलाया जा सकता है. इससे मुख्य सिस्टम पार्टीशन में फ़ाइल सिस्टम फ़ॉर्मैट को अपडेट किया जा सकेगा. ऐसा करने से, पुराने वर्शन के साथ काम न करने या स्टेपिंग-स्टोन अपडेट से जुड़ी समस्याएं नहीं होंगी. इससे उपयोगकर्ता, फ़ैक्ट्री इमेज से सीधे तौर पर नए वर्शन पर अपडेट कर पाएंगे.
नया पोस्ट-इंस्टॉल प्रोग्राम, पुराने सिस्टम में तय की गई SELinux नीतियों के हिसाब से काम करता है. इसलिए, इंस्टॉल होने के बाद किए जाने वाले टास्क, किसी डिवाइस पर डिज़ाइन के हिसाब से ज़रूरी टास्क या अन्य बेहतर टास्क करने के लिए सही होते हैं. रीबूट से पहले, एक बार में गड़बड़ियों को ठीक करने के लिए, इंस्टॉल करने के बाद का चरण सही नहीं है. इसके लिए, अप्रत्याशित अनुमतियों की ज़रूरत होती है.
चुना गया पोस्ट-इंस्टॉल प्रोग्राम, postinstall
SELinux कॉन्टेक्स्ट में चलता है. माउंट किए गए नए पार्टीशन में मौजूद सभी फ़ाइलों को postinstall_file
के तौर पर टैग किया जाएगा. भले ही, नए सिस्टम में रीबूट करने के बाद उनके एट्रिब्यूट कुछ भी हों. नए सिस्टम में SELinux एट्रिब्यूट में किए गए बदलावों का असर, इंस्टॉलेशन के बाद के चरण पर नहीं पड़ेगा. अगर पोस्ट-इंस्टॉल प्रोग्राम को अतिरिक्त अनुमतियों की ज़रूरत है, तो उन्हें पोस्ट-इंस्टॉल कॉन्टेक्स्ट में जोड़ना होगा.
रीबूट करने के बाद
रीबूट करने के बाद, update_verifier
dm-verity का इस्तेमाल करके इंटिग्रिटी की जांच शुरू करता है.
यह जांच, ज़ायगोट से पहले शुरू होती है, ताकि Java सेवाओं को ऐसे बदलाव करने से रोका जा सके जिन्हें वापस नहीं किया जा सकता. इससे सुरक्षित रोलबैक को रोका जा सकता है. इस प्रोसेस के दौरान, अगर वेरिफ़ाइड बूट या dm-verity को कोई गड़बड़ी मिलती है, तो बूटलोडर और कर्नल भी रीबूट को ट्रिगर कर सकते हैं. जांच पूरी होने के बाद,
update_verifier
बूट को सफल के तौर पर मार्क करता है.
update_verifier
सिर्फ़ /data/ota_package/care_map.txt
में दिए गए ब्लॉक को पढ़ेगा. AOSP कोड का इस्तेमाल करते समय, /data/ota_package/care_map.txt
को A/B OTA पैकेज में शामिल किया जाता है. Java सिस्टम अपडेट क्लाइंट, जैसे कि GmsCore, care_map.txt
को एक्सट्रैक्ट करता है. साथ ही, डिवाइस को रीबूट करने से पहले ऐक्सेस करने की अनुमति सेट अप करता है. इसके अलावा, सिस्टम के नए वर्शन में बूट होने के बाद, एक्सट्रैक्ट की गई फ़ाइल को मिटा देता है.