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

लेगसी A/B सिस्टम अपडेट, जिन्हें आसान अपडेट भी कहा जाता है, यह पक्का करते हैं कि ओवर-द-एयर (ओटीए) अपडेट के दौरान, डिस्क पर काम करने वाला बूट सिस्टम मौजूद रहे. इस तरीके से, अपडेट के बाद डिवाइस के काम न करने की संभावना कम हो जाती है. इसका मतलब है कि रिपेयर और वारंटी सेंटर में डिवाइस को बदलने और फिर से फ़्लैश करने की संख्या कम हो जाती है. ChromeOS जैसे अन्य व्यावसायिक ग्रेड के ऑपरेटिंग सिस्टम भी A/B अपडेट का इस्तेमाल करते हैं.

A/B सिस्टम के अपडेट और उनके काम करने के तरीके के बारे में ज़्यादा जानने के लिए, पार्टिशन चुनना (स्लॉट) लेख पढ़ें.

A/B सिस्टम अपडेट से ये फ़ायदे मिलते हैं:

  • ओटीए अपडेट, सिस्टम के चालू रहने के दौरान किए जा सकते हैं. ऐसा करने से, उपयोगकर्ता को कोई रुकावट नहीं होती. उपयोगकर्ता, ओटीए के दौरान अपने डिवाइसों का इस्तेमाल करना जारी रख सकते हैं. अपडेट के दौरान, डिवाइस सिर्फ़ तब बंद होता है, जब वह अपडेट किए गए डिस्क पार्टीशन में फिर से चालू होता है.
  • अपडेट के बाद, डिवाइस को रीबूट करने में सामान्य रीबूट से ज़्यादा समय नहीं लगता.
  • अगर ओटीए लागू नहीं होता है (उदाहरण के लिए, खराब फ़्लैश की वजह से), तो उपयोगकर्ता पर इसका कोई असर नहीं पड़ेगा. उपयोगकर्ता पुराने ओएस का इस्तेमाल करता रहेगा और क्लाइंट, अपडेट करने की कोशिश फिर से कर सकता है.
  • अगर ओटीए अपडेट लागू हो जाता है, लेकिन डिवाइस बूट नहीं होता है, तो डिवाइस फिर से पुराने पार्टीशन में रीबूट हो जाएगा और उसका इस्तेमाल किया जा सकेगा. क्लाइंट, अपडेट करने की कोशिश फिर से कर सकता है.
  • किसी भी गड़बड़ी (जैसे कि I/O गड़बड़ियां) का असर सिर्फ़ इस्तेमाल न किए गए पार्टीशन सेट पर पड़ता है. हालांकि, इसे फिर से आज़माया जा सकता है. ऐसी गड़बड़ियों की संभावना भी कम हो जाती है, क्योंकि उपयोगकर्ता अनुभव को खराब होने से बचाने के लिए, I/O लोड को जान-बूझकर कम रखा जाता है.
  • अपडेट को A/B डिवाइसों पर स्ट्रीम किया जा सकता है. इससे, पैकेज को इंस्टॉल करने से पहले उसे डाउनलोड करने की ज़रूरत नहीं पड़ती. स्ट्रीमिंग का मतलब है कि उपयोगकर्ता के पास /data या /cache पर अपडेट पैकेज को स्टोर करने के लिए, ज़रूरत के मुताबिक खाली जगह होना ज़रूरी नहीं है.
  • ओटीए अपडेट पैकेज को स्टोर करने के लिए, अब कैश मेमोरी का इस्तेमाल नहीं किया जाता. इसलिए, यह पक्का करने की ज़रूरत नहीं है कि आने वाले समय में होने वाले अपडेट के लिए, कैश मेमोरी काफ़ी बड़ी हो.
  • dm-verity यह पक्का करता है कि डिवाइस, बिना किसी गड़बड़ी वाली इमेज को बूट करेगा. अगर किसी डिवाइस में, खराब ऑन-लाइन ट्रांसफ़र (ओटीए) या dm-verity की समस्या की वजह से बूट नहीं हो पा रहा है, तो डिवाइस को पुरानी इमेज में रीबूट किया जा सकता है. (Android वेरिफ़ाइड बूट के लिए, A/B अपडेट की ज़रूरत नहीं होती.)

A/B सिस्टम अपडेट के बारे में जानकारी

A/B अपडेट के लिए, क्लाइंट और सिस्टम, दोनों में बदलाव करने की ज़रूरत होती है. हालांकि, ओटीए पैकेज सर्वर में बदलाव करने की ज़रूरत नहीं है: अपडेट पैकेज अब भी एचटीटीपीएस पर उपलब्ध कराए जाते हैं. Google के ओटीए इंफ़्रास्ट्रक्चर का इस्तेमाल करने वाले डिवाइसों के लिए, सिस्टम में हुए सभी बदलाव AOSP में होते हैं. साथ ही, क्लाइंट कोड को Google Play services उपलब्ध कराता है. Google के ओटीए इन्फ़्रास्ट्रक्चर का इस्तेमाल न करने वाले OEM, AOSP सिस्टम कोड का फिर से इस्तेमाल कर सकते हैं. हालांकि, उन्हें अपना क्लाइंट उपलब्ध कराना होगा.

अपने क्लाइंट को सप्लाई करने वाले OEM को ये काम करने होंगे:

  • तय करें कि आपको अपडेट कब लेना है. A/B अपडेट, बैकग्राउंड में होते हैं. इसलिए, अब इन्हें उपयोगकर्ता शुरू नहीं करता. हमारा सुझाव है कि उपयोगकर्ताओं को परेशानी न हो, इसके लिए अपडेट को डिवाइस के इस्तेमाल न होने पर शेड्यूल करें. जैसे, रात भर और वाई-फ़ाई पर. हालांकि, आपका क्लाइंट आपकी पसंद के हिसाब से किसी भी हेयुरिस्टिक्स का इस्तेमाल कर सकता है.
  • ओटीए पैकेज सर्वर से संपर्क करें और देखें कि कोई अपडेट उपलब्ध है या नहीं. यह कोड, आपके मौजूदा क्लाइंट कोड से काफ़ी हद तक मिलता-जुलता होना चाहिए. हालांकि, आपको यह सिग्नल देना होगा कि डिवाइस पर A/B टेस्टिंग की सुविधा काम करती है. (Google के क्लाइंट में, उपयोगकर्ताओं के लिए सबसे नया अपडेट देखने के लिए, अभी देखें बटन भी शामिल होता है.)
  • अपने अपडेट पैकेज के एचटीटीपीएस यूआरएल के साथ update_engine को कॉल करें. ऐसा तब करें, जब कोई यूआरएल उपलब्ध हो. update_engine, अपडेट पैकेज को स्ट्रीम करते समय, फ़िलहाल इस्तेमाल में न होने वाले पार्टीशन पर रॉ ब्लॉक अपडेट करेगा.
  • update_engine नतीजे के कोड के आधार पर, अपने सर्वर को इंस्टॉलेशन के कामयाब होने या न होने की जानकारी दें. अगर अपडेट लागू हो जाता है, तो update_engine, बूटलोडर को अगली बार रीबूट करने पर, नए ओएस में बूट करने के लिए कहेगा. अगर नया ओएस बूट नहीं होता है, तो बूटलोडर पुराने ओएस पर स्विच कर जाएगा. इसलिए, क्लाइंट को कुछ करने की ज़रूरत नहीं है. अगर अपडेट नहीं हो पाता है, तो क्लाइंट को गड़बड़ी के कोड के आधार पर यह तय करना होगा कि उसे दोबारा कब और फिर से कोशिश करनी है. उदाहरण के लिए, एक अच्छा क्लाइंट यह पहचान सकता है कि कुछ हिस्से वाला ("diff") ओटीए पैकेज काम नहीं कर रहा है और इसके बजाय पूरा ओटीए पैकेज आज़मा सकता है.

इसके अलावा, क्लाइंट ये काम भी कर सकता है:

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

सिस्टम के लिए, A/B सिस्टम अपडेट से इन पर असर पड़ता है:

  • पार्टीशन चुनना (स्लॉट), update_engine डेमन, और बूटलोडर के साथ इंटरैक्शन के बारे में जानकारी (यहां दी गई है)
  • बिल्ड प्रोसेस और ओटीए अपडेट पैकेज जनरेशन (इसके बारे में A/B अपडेट लागू करना में बताया गया है)

पार्टीशन चुनना (स्लॉट)

A/B सिस्टम अपडेट, पार्टिशन के दो सेट का इस्तेमाल करते हैं. इन्हें आम तौर पर स्लॉट (स्लॉट A और स्लॉट B) कहा जाता है. सिस्टम, मौजूदा स्लॉट से चलता है. साथ ही, सामान्य ऑपरेशन के दौरान, इस्तेमाल नहीं किए गए स्लॉट में मौजूद सेगमेंट को, चल रहे सिस्टम से ऐक्सेस नहीं किया जाता. इस तरीके से, अपडेट में गड़बड़ी होने की संभावना कम हो जाती है. ऐसा इसलिए होता है, क्योंकि इस्तेमाल न किए गए स्लॉट को फ़ॉलबैक के तौर पर रखा जाता है: अगर अपडेट के दौरान या उसके तुरंत बाद कोई गड़बड़ी होती है, तो सिस्टम पुराने स्लॉट पर वापस आ सकता है और काम करना जारी रख सकता है. इस लक्ष्य को हासिल करने के लिए, ओटीए अपडेट के हिस्से के तौर पर, मौजूदा स्लॉट का इस्तेमाल करने वाले किसी भी पार्टीशन को अपडेट नहीं किया जाना चाहिए. इसमें वे पार्टीशन भी शामिल हैं जिनकी सिर्फ़ एक कॉपी है.

हर स्लॉट में bootable एट्रिब्यूट होता है. इससे पता चलता है कि स्लॉट में सही सिस्टम है या नहीं, जिससे डिवाइस को बूट किया जा सकता है. सिस्टम चालू होने पर, मौजूदा स्लॉट से बूट किया जा सकता है. हालांकि, दूसरे स्लॉट में सिस्टम का पुराना (अब भी सही) वर्शन, नया वर्शन या अमान्य डेटा हो सकता है. मौजूदा स्लॉट चाहे जो भी हो, एक स्लॉट चालू स्लॉट होता है. अगली बार बूट करने पर, बूटलोडर इसी स्लॉट से बूट होगा. इसके अलावा, एक स्लॉट पसंदीदा स्लॉट होता है.

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

Update engine daemon

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

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

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

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

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

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

बूटलोडर इंटरैक्शन

boot_control HAL का इस्तेमाल update_engine (और शायद अन्य डेमन) करता है, ताकि बूटलोडर को यह निर्देश दिया जा सके कि उसे किससे बूट करना है. सामान्य उदाहरणों और उनसे जुड़ी स्थितियों में ये शामिल हैं:

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

स्ट्रीमिंग से जुड़े अपडेट के लिए सहायता

उपयोगकर्ता के डिवाइसों में, अपडेट पैकेज डाउनलोड करने के लिए /data में हमेशा ज़रूरत के मुताबिक स्टोरेज नहीं होता. OEM और उपयोगकर्ता, दोनों ही /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 अपडेट की अवधि

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

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

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

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

अपडेट पेलोड एक ऐसा ब्लॉब होता है जिसमें नए वर्शन पर अपडेट करने के निर्देश होते हैं. अपडेट पेलोड में ये चीज़ें शामिल हैं:
  • मेटाडेटा. अपडेट पेलोड का एक छोटा हिस्सा, मेटाडेटा होता है. इसमें टारगेट स्लॉट पर नए वर्शन को बनाने और उसकी पुष्टि करने के लिए, कार्रवाइयों की सूची होती है. उदाहरण के लिए, कोई ऑपरेशन किसी ब्लॉक को डिकंप्रेस कर सकता है और उसे टारगेट पार्टिशन के कुछ ब्लॉक में लिख सकता है. इसके अलावा, वह किसी सोर्स पार्टिशन से पढ़कर, बाइनरी पैच लागू कर सकता है और टारगेट पार्टिशन के कुछ ब्लॉक में लिख सकता है.
  • अतिरिक्त डेटा. इन उदाहरणों में, अपडेट पेलोड के ज़्यादातर हिस्से के तौर पर, ऑपरेशन से जुड़े अतिरिक्त डेटा में कंप्रेस किया गया ब्लॉब या बाइनरी पैच शामिल होता है.
3 पेलोड का मेटाडेटा डाउनलोड हो जाता है.
4 मेटाडेटा में बताए गए हर ऑपरेशन के लिए, उससे जुड़ा डेटा (अगर कोई है) को क्रम से मेमोरी में डाउनलोड किया जाता है, ऑपरेशन लागू किया जाता है, और उससे जुड़ी मेमोरी को खारिज कर दिया जाता है.
5 पूरे पार्टीशन को फिर से पढ़ा जाता है और उम्मीद के मुताबिक हैश की पुष्टि की जाती है.
6 इंस्टॉल के बाद की प्रोसेस (अगर कोई हो) को चलाया जाता है. किसी भी चरण को पूरा करने के दौरान गड़बड़ी होने पर, अपडेट पूरा नहीं होता. इसके बाद, किसी दूसरे पेलोड के साथ फिर से कोशिश की जाती है. अगर अब तक सभी चरण पूरे हो गए हैं, तो अपडेट हो जाता है और आखिरी चरण पूरा हो जाता है.
7 setActiveBootSlot() को कॉल करके, इस्तेमाल न किए गए स्लॉट को चालू के तौर पर मार्क किया जाता है. इस्तेमाल न किए गए स्लॉट को 'चालू है' के तौर पर मार्क करने का मतलब यह नहीं है कि वह बूट हो जाएगा. अगर बूटलोडर (या खुद सिस्टम) को पता चलता है कि फ़्लैश फ़ाइल ठीक से इंस्टॉल नहीं हुई है, तो वह चालू स्लॉट को वापस स्विच कर सकता है.
8 इंस्टॉल के बाद (इसके बारे में नीचे बताया गया है), "नए अपडेट" वर्शन से प्रोग्राम चलाया जाता है, जबकि वह पुराने वर्शन में चल रहा होता है. अगर यह चरण, ओटीए पैकेज में बताया गया है, तो यह चरण ज़रूरी है. साथ ही, प्रोग्राम को बाहर निकलने का कोड 0 देना होगा. ऐसा न करने पर, अपडेट पूरा नहीं होगा.
9 सिस्टम के नए स्लॉट में पूरी तरह से बूट होने और रीबूट के बाद की जांच पूरी करने के बाद, मौजूदा स्लॉट (पहले "टारगेट स्लॉट") को markBootSuccessful() को कॉल करके, "सफल" के तौर पर मार्क किया जाता है.

इंस्टॉल करने के बाद

हर उस पार्टीशन के लिए जहां इंस्टॉल के बाद का चरण तय किया गया है, update_engine नए पार्टीशन को किसी खास जगह पर माउंट करता है और माउंट किए गए पार्टीशन के हिसाब से, ओटीए में बताए गए प्रोग्राम को चलाता है. उदाहरण के लिए, अगर सिस्टम के partition में, इंस्टॉल के बाद चलने वाले प्रोग्राम को usr/bin/postinstall के तौर पर तय किया गया है, तो इस्तेमाल न किए गए स्लॉट से यह partition, किसी तय जगह (जैसे कि /postinstall_mount) पर माउंट किया जाएगा और /postinstall_mount/usr/bin/postinstall कमांड को लागू किया जाएगा.

इंस्टॉल के बाद, पुराने कर्नेल को ये काम करने होंगे:

  • नया फ़ाइल सिस्टम फ़ॉर्मैट माउंट करें. फ़ाइल सिस्टम का टाइप तब तक नहीं बदला जा सकता, जब तक कि पुराने कर्नेल में इसके लिए सहायता उपलब्ध न हो. इसमें, संपीड़ित फ़ाइल सिस्टम (जैसे, SquashFS) का इस्तेमाल करने पर, इस्तेमाल किए गए कंप्रेसन एल्गोरिदम जैसी जानकारी शामिल होती है.
  • नए पार्टीशन के इंस्टॉल के बाद के प्रोग्राम फ़ॉर्मैट को समझना. अगर किसी Executable and Linkable Format (ELF) बाइनरी का इस्तेमाल किया जा रहा है, तो यह पुराने कर्नेल के साथ काम करना चाहिए. उदाहरण के लिए, अगर आर्किटेक्चर को 32- से 64-बिट वाले बिल्ड पर स्विच किया गया है, तो 64-बिट का नया प्रोग्राम, पुराने 32-बिट कर्नेल पर चल सकता है. जब तक लोडर (ld) को अन्य पाथ का इस्तेमाल करने या स्टैटिक बाइनरी बनाने का निर्देश नहीं दिया जाता, तब तक लाइब्रेरी नई सिस्टम इमेज से नहीं, बल्कि पुरानी सिस्टम इमेज से लोड की जाएंगी.

उदाहरण के लिए, किसी शेल स्क्रिप्ट का इस्तेमाल, इंस्टॉल के बाद चलने वाले प्रोग्राम के तौर पर किया जा सकता है. यह प्रोग्राम, पुराने सिस्टम के शेल बाइनरी के ज़रिए, सबसे ऊपर #! मार्कर के साथ काम करता है. इसके बाद, इंस्टॉल के बाद चलने वाले ज़्यादा जटिल बाइनरी प्रोग्राम को चलाने के लिए, नए एनवायरमेंट से लाइब्रेरी पाथ सेट अप किए जा सकते हैं. इसके अलावा, इंस्टॉल के बाद की प्रोसेस को किसी छोटे से अलग से बने partition से भी चलाया जा सकता है. इससे मुख्य सिस्टम partition में फ़ाइल सिस्टम फ़ॉर्मैट को अपडेट किया जा सकता है. ऐसा करने पर, पुराने सिस्टम के साथ काम करने से जुड़ी समस्याएं या अपडेट के दौरान आने वाली समस्याएं नहीं आती हैं. इससे, उपयोगकर्ताओं को फ़ैक्ट्री इमेज से सीधे नए वर्शन पर अपडेट करने की सुविधा मिलती है.

इंस्टॉल के बाद चलने वाले नए प्रोग्राम पर, पुराने सिस्टम में तय की गई SELinux नीतियां लागू होती हैं. इसलिए, इंस्टॉल के बाद का चरण, किसी डिवाइस पर डिज़ाइन के हिसाब से ज़रूरी टास्क या सबसे बेहतर तरीके से किए जाने वाले अन्य टास्क को पूरा करने के लिए सही है. इंस्टॉल के बाद का चरण, रीबूट से पहले गड़बड़ी को ठीक करने के लिए काम का नहीं है. ऐसा तब होता है, जब गड़बड़ी को ठीक करने के लिए अचानक अनुमतियों की ज़रूरत पड़ती है.

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

रीबूट करने के बाद

रीबूट करने के बाद, update_verifier dm-verity का इस्तेमाल करके इंटिग्रिटी जांच को ट्रिगर करता है. यह जांच, zygote से पहले शुरू होती है, ताकि Java सेवाएं ऐसे बदलाव न कर सकें जिन्हें वापस नहीं लाया जा सकता और जो सुरक्षित तरीके से रोलबैक को रोक सकते हैं. इस प्रोसेस के दौरान, बूटलोडर और कर्नेल भी रीबूट को ट्रिगर कर सकते हैं. ऐसा तब होता है, जब वेरिफ़ाइड बूट या dm-verity को किसी गड़बड़ी का पता चलता है. जांच पूरी होने के बाद, update_verifier बूट होने की पुष्टि करता है.

update_verifier सिर्फ़ /data/ota_package/care_map.txt में दिए गए ब्लॉक को पढ़ेगा. यह ब्लॉक, AOSP कोड का इस्तेमाल करते समय A/B OTA पैकेज में शामिल होता है. GmsCore जैसे Java सिस्टम अपडेट क्लाइंट, care_map.txt को निकालता है. साथ ही, डिवाइस को रीबूट करने से पहले, ऐक्सेस की अनुमति सेट अप करता है. इसके बाद, सिस्टम के नए वर्शन में बूट होने के बाद, निकाली गई फ़ाइल को मिटा देता है.