A/B (बिना किसी रुकावट के) सिस्टम अपडेट

लेगसी ए/बी सिस्टम अपडेट को सीमलेस अपडेट भी कहा जाता है. ये अपडेट यह पक्का करते हैं कि ओवर-द-एयर (ओटीए) अपडेट के दौरान, बूटिंग सिस्टम डिस्क पर बना रहे. इस तरीके से, अपडेट के बाद डिवाइस के काम न करने की संभावना कम हो जाती है. इसका मतलब है कि डिवाइस को बदलने और वारंटी और मरम्मत केंद्रों पर डिवाइस को रीफ़्लैश करने की ज़रूरत कम पड़ती है. 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 के ओटीए इंफ़्रास्ट्रक्चर का इस्तेमाल करने वाले डिवाइसों के लिए, सिस्टम में होने वाले सभी बदलाव 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 एट्रिब्यूट होता है. इससे पता चलता है कि स्लॉट में सही सिस्टम है या नहीं, जिससे डिवाइस बूट हो सकता है. सिस्टम चालू होने पर, मौजूदा स्लॉट बूट किया जा सकता है. हालांकि, दूसरे स्लॉट में सिस्टम का पुराना (अब भी सही) वर्शन, नया वर्शन या अमान्य डेटा हो सकता है. मौजूदा स्लॉट कोई भी हो, एक स्लॉट ऐसा होता है जो चालू स्लॉट होता है. बूटलोडर, अगले बूट पर इसी स्लॉट से बूट करेगा. इसके अलावा, एक स्लॉट पसंदीदा स्लॉट होता है.

हर स्लॉट में, उपयोगकर्ता स्पेस के ज़रिए सेट किया गया सफल एट्रिब्यूट भी होता है. यह एट्रिब्यूट सिर्फ़ तब काम का होता है, जब स्लॉट बूट भी किया जा सकता हो. स्लॉट को बूट, रन, और अपडेट किया जा सकता हो. बूट करने लायक ऐसे स्लॉट को बूट न करने लायक के तौर पर मार्क किया जाना चाहिए जिससे बूट करने की कई बार कोशिश करने के बाद भी बूट नहीं किया जा सका. ऐसा बूटलोडर को करना चाहिए. इसमें चालू स्लॉट को बूट करने लायक किसी दूसरे स्लॉट में बदलना भी शामिल है. आम तौर पर, ऐसा उस स्लॉट में किया जाता है जो नए, चालू स्लॉट में बूट करने की कोशिश से ठीक पहले चल रहा था. इंटरफ़ेस के बारे में ज़्यादा जानकारी, boot_control.h में दी गई है.

इंजन डेमॉन को अपडेट करना

A/B सिस्टम अपडेट, बैकग्राउंड डेमॉन का इस्तेमाल करते हैं. इसे update_engine कहा जाता है. यह सिस्टम को नए और अपडेट किए गए वर्शन में बूट करने के लिए तैयार करता है. यह डेमॉन, ये कार्रवाइयां कर सकता है:

  • OTA पैकेज में दिए गए निर्देशों के मुताबिक, मौजूदा स्लॉट के A/B पार्टीशन से डेटा पढ़ें और इस्तेमाल नहीं किए गए स्लॉट के A/B पार्टीशन में कोई भी डेटा लिखें.
  • पहले से तय किए गए वर्कफ़्लो में boot_control इंटरफ़ेस को कॉल करें.
  • ओटीए पैकेज में दिए गए निर्देशों के मुताबिक, इस्तेमाल नहीं किए गए सभी स्लॉट पार्टीशन लिखने के बाद, नए पार्टीशन से पोस्ट-इंस्टॉल प्रोग्राम चलाएं. (ज़्यादा जानकारी के लिए, इंस्टॉल करने के बाद लेख पढ़ें).

update_engine डेमॉन, बूट प्रोसेस में शामिल नहीं होता. इसलिए, current स्लॉट में मौजूद SELinux नीतियों और सुविधाओं के ज़रिए, अपडेट के दौरान इसकी गतिविधियों को सीमित किया जाता है. इन नीतियों और सुविधाओं को तब तक अपडेट नहीं किया जा सकता, जब तक सिस्टम नए वर्शन में बूट न हो जाए. सिस्टम को बेहतर बनाए रखने के लिए, अपडेट करने की प्रोसेस में, पार्टीशन टेबल, मौजूदा स्लॉट में मौजूद पार्टीशन का कॉन्टेंट या फ़ैक्ट्री रीसेट के दौरान वाइप न किए जा सकने वाले नॉन-ए/बी पार्टीशन के कॉन्टेंट में बदलाव नहीं किया जाना चाहिए.

इंजन के सोर्स को अपडेट करना

update_engine सोर्स, system/update_engine में मौजूद है. A/B OTA dexopt फ़ाइलों को installd और पैकेज मैनेजर के बीच बांटा जाता है:

  • frameworks/native/cmds/installd/ota* में ये चीज़ें शामिल हैं: पोस्टइंस्टॉल स्क्रिप्ट, chroot के लिए बाइनरी, installd क्लोन जो dex2oat को कॉल करता है, पोस्ट-ओटीए move-artifacts स्क्रिप्ट, और move स्क्रिप्ट के लिए rc फ़ाइल.
  • frameworks/base/services/core/java/com/android/server/pm/OtaDexoptService.java (plus OtaDexoptShellCommand) एक पैकेज मैनेजर है. यह ऐप्लिकेशन के लिए 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 में स्ट्रीमिंग A/B अपडेट की सुविधा जोड़ी गई है. इससे डाउनलोड किए जा रहे ब्लॉक सीधे तौर पर B पार्टीशन में लिखे जाते हैं. इसके लिए, ब्लॉक को /data पर सेव करने की ज़रूरत नहीं होती. स्ट्रीमिंग A/B अपडेट के लिए, कुछ समय के लिए बहुत कम स्टोरेज की ज़रूरत होती है. साथ ही, इसके लिए सिर्फ़ 100 केआईबी मेटाडेटा के लिए स्टोरेज की ज़रूरत होती है.

Android 7.1 में स्ट्रीमिंग अपडेट चालू करने के लिए, इन पैच को चेरीपिक करें:

Android 7.1 और इसके बाद के वर्शन में, A/B अपडेट की स्ट्रीमिंग की सुविधा के लिए इन पैच की ज़रूरत होती है. भले ही, Google Mobile Services (GMS) का इस्तेमाल किया जा रहा हो या कोई अन्य अपडेट क्लाइंट.

A/B अपडेट की अवधि

अपडेट की प्रोसेस तब शुरू होती है, जब डाउनलोड करने के लिए कोई ओटीए पैकेज (कोड में जिसे payload कहा जाता है) उपलब्ध होता है. डिवाइस में मौजूद नीतियां, बैटरी लेवल, उपयोगकर्ता गतिविधि, चार्जिंग की स्थिति या अन्य नीतियों के आधार पर, पेलोड डाउनलोड करने और उसे लागू करने में देरी कर सकती हैं. इसके अलावा, अपडेट बैकग्राउंड में होता है. इसलिए, उपयोगकर्ताओं को यह पता नहीं चल पाता कि अपडेट हो रहा है. इन सभी का मतलब है कि अपडेट की प्रोसेस में किसी भी समय रुकावट आ सकती है. ऐसा नीतियों, अचानक रीबूट होने या उपयोगकर्ता की कार्रवाइयों की वजह से हो सकता है.

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

Payload उपलब्ध होने के बाद, अपडेट करने की प्रोसेस इस तरह होती है:

चरण गतिविधियां
1 मौजूदा स्लॉट (या "सोर्स स्लॉट") को markBootSuccessful() के साथ, 'सफल' के तौर पर मार्क किया जाता है. अगर ऐसा पहले से नहीं किया गया है, तो ऐसा किया जाता है.
2 इस्तेमाल न किए गए स्लॉट (या "टारगेट स्लॉट") को बूट न किया जा सकने वाला स्लॉट के तौर पर मार्क किया जाता है. इसके लिए, setSlotAsUnbootable() फ़ंक्शन को कॉल किया जाता है. अपडेट की शुरुआत में, मौजूदा स्लॉट को हमेशा 'अपडेट हो गया' के तौर पर मार्क किया जाता है. इससे बूटलोडर को ऐसे स्लॉट पर वापस जाने से रोका जा सकता है जिसका इस्तेमाल नहीं किया गया है. इस स्लॉट में जल्द ही अमान्य डेटा होगा. अगर सिस्टम अपडेट लागू करने की स्थिति में पहुंच गया है, तो मौजूदा स्लॉट को 'अपडेट हो गया' के तौर पर मार्क किया जाता है. भले ही, अन्य मुख्य कॉम्पोनेंट काम न कर रहे हों. जैसे, क्रैश लूप में यूज़र इंटरफ़ेस (यूआई). ऐसा इसलिए, क्योंकि इन समस्याओं को ठीक करने के लिए नया सॉफ़्टवेयर पुश किया जा सकता है.

अपडेट पेलोड, एक ओपेक ब्लॉब होता है. इसमें नए वर्शन पर अपडेट करने के निर्देश होते हैं. अपडेट पेलोड में यह जानकारी शामिल होती है:
  • मेटाडेटा. अपडेट पेलोड का अपेक्षाकृत छोटा हिस्सा, मेटाडेटा होता है. इसमें टारगेट स्लॉट पर नया वर्शन बनाने और उसकी पुष्टि करने के लिए, कार्रवाइयों की सूची होती है. उदाहरण के लिए, कोई ऑपरेशन किसी खास ब्लॉब को डीकंप्रेस कर सकता है और उसे टारगेट पार्टीशन के कुछ ब्लॉक में लिख सकता है. इसके अलावा, वह सोर्स पार्टीशन से पढ़ सकता है, बाइनरी पैच लागू कर सकता है, और उसे टारगेट पार्टीशन के कुछ ब्लॉक में लिख सकता है.
  • अतिरिक्त डेटा. अपडेट पेलोड के ज़्यादातर हिस्से के तौर पर, कार्रवाइयों से जुड़ा अतिरिक्त डेटा इन उदाहरणों में कंप्रेस किया गया blob या बाइनरी पैच होता है.
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 पैकेज में शामिल किया जाता है. GmsCore जैसे Java सिस्टम अपडेट क्लाइंट, care_map.txt को एक्सट्रैक्ट करता है. साथ ही, डिवाइस को रीबूट करने से पहले ऐक्सेस करने की अनुमति सेट अप करता है. इसके अलावा, सिस्टम के नए वर्शन में बूट होने के बाद, एक्सट्रैक्ट की गई फ़ाइल को मिटा देता है.