बिना डाइनैमिक पार्टीशन के A/B डिवाइसों के लिए OTA

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

इस पेज पर बताया गया है कि डाइनैमिक पार्टिशन के बिना लॉन्च हुए A/B डिवाइसों के लिए अपडेट के दौरान, ओटीए क्लाइंट, डाइनैमिक पार्टिशन का साइज़ कैसे बदलते हैं. साथ ही, यह भी बताया गया है कि ओटीए क्लाइंट, Android 10 पर कैसे अपग्रेड करते हैं.

बैकग्राउंड

डाइनैमिक पार्टीशन के साथ काम करने के लिए, A/B डिवाइस को अपडेट करने के दौरान, डिवाइस पर मौजूद GUID पार्टीशन टेबल (GPT) को सुरक्षित रखा जाता है. इसलिए, डिवाइस पर कोई super पार्टीशन नहीं होता. मेटाडेटा को system_a और system_b में सेव किया जाता है. हालांकि, BOARD_SUPER_PARTITION_METADATA_DEVICE को बदलकर इसे अपनी पसंद के मुताबिक बनाया जा सकता है.

हर ब्लॉक डिवाइस में दो मेटाडेटा स्लॉट होते हैं. हर ब्लॉक डिवाइस में सिर्फ़ एक मेटाडेटा स्लॉट का इस्तेमाल किया जाता है. उदाहरण के लिए, system_a पर मौजूद मेटाडेटा 0 और system_b पर मेटाडेटा 1, A और B स्लॉट के हिसाब से है. रनटाइम के दौरान, इससे कोई फ़र्क़ नहीं पड़ता कि कौनसा स्लॉट अपडेट किया जा रहा है.

इस पेज में, मेटाडेटा स्लॉट को मेटाडेटा S (सोर्स) और मेटाडेटा T (टारगेट) कहा जाता है. इसी तरह, पार्टिशन को system_s, vendor_t वगैरह के तौर पर जाना जाता है.

बिल्ड सिस्टम कॉन्फ़िगरेशन के बारे में ज़्यादा जानने के लिए, डिवाइसों को अपग्रेड करना लेख पढ़ें.

नए डिवाइसों के लिए, बोर्ड के कॉन्फ़िगरेशन में हुए बदलाव देखें. इससे आपको यह जानने में मदद मिलेगी कि अपडेट ग्रुप में, पार्टीशन किस तरह शामिल होते हैं.

किसी डिवाइस पर मेटाडेटा का उदाहरण:

  • फ़िज़िकल ब्लॉक डिवाइस system_a
    • मेटाडेटा 0
      • ग्रुप foo_a
        • लॉजिकल (डाइनैमिक) पार्टीशन system_a
        • लॉजिकल (डाइनैमिक) पार्टीशन product_services_a
        • Foo ने अपडेट किए गए अन्य पार्टीशन
      • ग्रुप bar_a
        • लॉजिकल (डाइनैमिक) पार्टीशन vendor_a
        • लॉजिकल (डाइनैमिक) पार्टीशन product_a
        • Bar की मदद से अपडेट किए गए अन्य पार्टीशन
    • मेटाडेटा 1 (इस्तेमाल नहीं किया गया)
  • फ़िज़िकल ब्लॉक डिवाइस system_b
    • मेटाडेटा 0 (इस्तेमाल नहीं किया गया)
    • मेटाडेटा 1
      • ग्रुप foo_b
        • लॉजिकल (डाइनैमिक) पार्टीशन system_b
        • लॉजिकल (डाइनैमिक) पार्टीशन product_services_b
        • Foo ने अपडेट किए गए अन्य पार्टीशन
      • ग्रुप bar_b
        • लॉजिकल (डाइनैमिक) पार्टीशन vendor_b
        • लॉजिकल (डाइनैमिक) पार्टीशन product_b
        • अन्य पार्टिशन बार से अपडेट किए गए

अपने डिवाइस पर मेटाडेटा को डंप करने के लिए, system/extras/partition_tools में मौजूद lpdump टूल का इस्तेमाल किया जा सकता है. उदाहरण के लिए:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

किसी अपडेट को फिर से फ़िट करना

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

ओटीए जनरेटर, super.img फ़ाइल बनाता है. इसमें सभी डाइनैमिक पार्टिशन का कॉन्टेंट होता है. इसके बाद, इमेज को कई इमेज में बांट दिया जाता है. ये इमेज, सिस्टम, वेंडर वगैरह से जुड़े फ़िज़िकल ब्लॉक डिवाइसों के साइज़ से मेल खाती हैं. इन इमेज के नाम super_system.img, super_vendor.img वगैरह हैं. ओटीए क्लाइंट, इमेज को लॉजिकल (डाइनैमिक) पार्टिशन के बजाय, फ़िज़िकल पार्टिशन पर लागू करता है.

OTA क्लाइंट, डाइनैमिक पार्टीशन को मैप करने का तरीका नहीं जानता. इसलिए, अपडेट पैकेज जनरेट होने पर, इन पार्टीशन के लिए इंस्टॉल के बाद के सभी चरण अपने-आप बंद हो जाते हैं. ज़्यादा जानकारी के लिए, पोस्ट-इंस्टॉलेशन कॉन्फ़िगर करना देखें.

इसे अपडेट करने का तरीका, Android 9 की तरह ही है.

अपडेट से पहले:

ro.boot.dynamic_partitions=
ro.boot.dynamic_partitions_retrofit=

अपडेट करने के बाद:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

रिफ़ोर्ट के बाद होने वाले अपडेट

रिफ़िट अपडेट के बाद, ओटीए क्लाइंट को डाइनैमिक पार्टिशन के साथ काम करने के लिए अपडेट किया जाता है. सोर्स पार्टिशन के एक्सटेंट, टारगेट किए गए फ़िज़िकल पार्टिशन में कभी भी नहीं होते.

सामान्य अपडेट पैकेज का इस्तेमाल करके अपडेट फ़्लो

  1. super पार्टीशन का मेटाडेटा शुरू करें.
    1. मेटाडेटा S (सोर्स मेटाडेटा) से नया मेटाडेटा M बनाएं. उदाहरण के लिए, अगर मेटाडेटा S, ब्लॉक किए गए डिवाइसों के तौर पर [system_s, vendor_s, product_s] का इस्तेमाल करता है, तो नया मेटाडेटा M, ब्लॉक किए गए डिवाइसों के तौर पर [system_t, vendor_t, product_t] का इस्तेमाल करता है. M में सभी ग्रुप और पार्टीशन खारिज कर दिए जाते हैं.
    2. अपडेट किए गए मेनिफ़ेस्ट में dynamic_partition_metadata फ़ील्ड के हिसाब से टारगेट ग्रुप और पार्टिशन जोड़ें. हर पार्टीशन का साइज़, new_partition_info में देखा जा सकता है.
    3. मेटाडेटा T में M लिखें.
    4. डिवाइस मैपर पर जोड़े गए पार्टीशन को, लिखने के लिए उपलब्ध के तौर पर मैप करें.
  2. ब्लॉक किए गए डिवाइसों पर अपडेट लागू करें.
    1. अगर ज़रूरी हो, तो डिवाइस मैपर पर सोर्स पार्टिशन को सिर्फ़ पढ़ने के लिए मैप करें. साइडलोड करने के लिए, यह ज़रूरी है, क्योंकि अपडेट से पहले, सोर्स पार्टीशन मैप नहीं किए जाते.
    2. टारगेट स्लॉट पर, सभी ब्लॉक किए गए डिवाइसों पर पूरा या डेल्टा अपडेट लागू करें.
    3. पोस्ट-इंस्टॉल स्क्रिप्ट को चलाने के लिए, पार्टिशन को माउंट करें और फिर पार्टिशन को सेटअप करें.
  3. टारगेट किए गए पार्टीशन को अनमैप करें.

रेट्रोफ़िट अपडेट पैकेज का इस्तेमाल करके फ़्लो अपडेट करें

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

उदाहरण के लिए, मान लें कि:

  • स्लॉट A चालू स्लॉट है.
  • system_a में स्लॉट 0 पर सक्रिय मेटाडेटा मौजूद है.
  • system_a, vendor_a, और product_a का इस्तेमाल, ब्लॉक किए गए डिवाइसों के तौर पर किया जाता है.

जब OTA क्लाइंट को रिफ़िट अपडेट पैकेज मिलता है, तो यह फ़िज़िकल system_b पर super_system.img, फ़िज़िकल vendor_b पर super_vendor.img, और फ़िज़िकल product_b पर super_product.img लागू होता है. फ़िज़िकल ब्लॉक डिवाइस system_b में सही मेटाडेटा होता है, ताकि बूट के समय लॉजिकल system_b, vendor_b, और product_b को मैप किया जा सके.

अपडेट पैकेज जनरेट करना

इंक्रीमेंटल ओटीए

रीफ़िट डिवाइसों के लिए इंक्रीमेंटल ओटीए जनरेट करते समय, अपडेट इस बात पर निर्भर करते हैं कि बेस बिल्ड में PRODUCT_USE_DYNAMIC_PARTITIONS और PRODUCT_RETROFIT_DYNAMIC_PARTITIONS तय किए गए हैं या नहीं.

  • अगर बुनियादी बिल्ड में वैरिएबल तय नहीं किए गए हैं, तो इसे फिर से अपडेट करना होगा. अपडेट पैकेज में, अलग-अलग हिस्सों में बांटी गई super.img फ़ाइल शामिल होती है. साथ ही, इंस्टॉल के बाद की प्रोसेस को बंद कर दिया जाता है.
  • अगर बेस बिल्ड में वैरिएबल तय किए गए हैं, तो यह डाइनैमिक पार्टिशन वाले सामान्य अपडेट जैसा ही है. अपडेट पैकेज में, लॉजिकल (डाइनैमिक) पार्टीशन की इमेज होती हैं. इंस्टॉल के बाद की प्रोसेस को चालू किया जा सकता है.

फ़ुल ओटीए

रीट्रॉफ़िट डिवाइसों के लिए, दो फ़ुल ओटीए पैकेज जनरेट किए जाते हैं.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip में हमेशा स्प्लिट super.img होता है. साथ ही, अपडेट को फिर से इंस्टॉल करने के लिए, इंस्टॉल के बाद का चरण बंद कर दिया जाता है.
    • इसे ota_from_target_files स्क्रिप्ट में एक अतिरिक्त आर्ग्युमेंट --retrofit_dynamic_partitions के साथ जनरेट किया जाता है.
    • इसे सभी बिल्ड पर लागू किया जा सकता है.
  • $(PRODUCT)-ota-$(TAG).zip में आने वाले अपडेट के लिए, तर्क के हिसाब से सही इमेज शामिल हैं.
    • इसे सिर्फ़ उन बिल्ड पर लागू करें जिनमें डाइनैमिक पार्टिशन चालू हों. इसे लागू करने के बारे में जानकारी नीचे दी गई है.

पुराने बिल्ड पर नॉन-रेट्रोफ़िट अपडेट को अस्वीकार करना

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

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

device/device_name/dynamic_partitions/check_dynamic_partitions

#!/system/bin/sh
DP_PROPERTY_NAME="ro.boot.dynamic_partitions"
DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit"

DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME})
DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME})

if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then
    echo "Error: applied non-retrofit update on build without dynamic" \
         "partitions."
    echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}"
    echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}"
    exit 1
fi

device/device_name/dynamic_partitions/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= check_dynamic_partitions
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := check_dynamic_partitions
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

device/device_name/device.mk

PRODUCT_PACKAGES += check_dynamic_partitions

# OPTIONAL=false so that the error in check_dynamic_partitions will be
# propagated to OTA client.
AB_OTA_POSTINSTALL_CONFIG += \
    RUN_POSTINSTALL_product=true \
    POSTINSTALL_PATH_product=bin/check_dynamic_partitions \
    FILESYSTEM_TYPE_product=ext4 \
    POSTINSTALL_OPTIONAL_product=false \

जब किसी डिवाइस पर सामान्य OTA पैकेज लागू किया जाता है और उस पर डाइनैमिक पार्टीशन की सुविधा चालू नहीं होती, तो OTA क्लाइंट, check_dynamic_partitions को इंस्टॉल के बाद के चरण के तौर पर चलाता है और अपडेट को अस्वीकार कर देता है.