वर्चुअल A/B लागू करना

किसी नए डिवाइस पर वर्चुअल A/B लागू करने या लॉन्च किए गए डिवाइस में बदलाव करने के लिए, आपको डिवाइस के हिसाब से कोड में बदलाव करने होंगे.

फ़्लैग बनाना

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

वर्चुअल A/B के साथ लॉन्च होने वाले डिवाइसों के लिए, उन्हें वर्चुअल A/B डिवाइस के बेस कॉन्फ़िगरेशन को इनहेरिट करने के लिए सेट करें:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

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

Android 13 और उसके बाद के वर्शन के लिए, वर्चुअल A/B के साथ संपीड़ित स्नैपशॉट चालू करने के लिए, यह बेस कॉन्फ़िगरेशन इनहेरिट करें:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)

इससे, वर्चुअल A/B के साथ यूज़रस्पेस स्नैपशॉट की सुविधा चालू होती है. साथ ही, इसमें कोई भी कॉम्प्रेस करने का तरीका इस्तेमाल नहीं किया जाता. इसके बाद, कॉम्प्रेस करने के तरीके को, काम करने वाले तरीकों में से किसी एक पर कॉन्फ़िगर किया जा सकता है, जैसे कि zstd और lz4. Android 15 के लिए, डिवाइस की ज़रूरतों के हिसाब से, कॉम्प्रेस करने की सुविधा को और भी पसंद के मुताबिक बनाया जा सकता है. ज़्यादा जानकारी के लिए, कंप्रेस करने की सुविधा को बेहतर बनाना लेख पढ़ें.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Android 12 के लिए, वर्चुअल A/B के साथ कंप्रेस किए गए स्नैपशॉट चालू करने के लिए, यह बुनियादी कॉन्फ़िगरेशन इनहेरिट करें:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

XOR कंप्रेसन

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

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

XOR कंप्रेसन, android_t_baseline.mk से इनहेरिट करने वाले डिवाइसों के लिए डिफ़ॉल्ट रूप से चालू होता है.

Userspace मर्ज करना

वर्चुअल A/B के आधुनिक वर्शन (Android T और उसके बाद के वर्शन) में, स्नैपशॉट मर्ज करने की प्रोसेस पूरी तरह से उपयोगकर्ता स्पेस में होती है. यह बदलाव, snapuserd और dm-user की मदद से किया जाता है. Android 13 और उसके बाद के वर्शन वाले डिवाइसों में, उपयोगकर्ता स्पेस को मर्ज करने की सुविधा डिफ़ॉल्ट रूप से चालू होती है. पुराने डिवाइसों को अपग्रेड करने के लिए, इस प्रॉपर्टी को इनके साथ सेट किया जा सकता है:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

बूट कंट्रोल एचएएल

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

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

fstab में बदलाव

बूट प्रोसेस के लिए, मेटाडेटा पार्टीशन की पूरी सुरक्षा ज़रूरी है. खास तौर पर, ओटीए अपडेट लागू होने के बाद. इसलिए, first_stage_init के इसे माउंट करने से पहले, मेटाडेटा सेक्शन की जांच करनी होगी. यह पक्का करने के लिए कि ऐसा हो, /metadata के लिए एंट्री में check fs_mgr फ़्लैग जोड़ें. यहां एक उदाहरण दिया गया है:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

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

स्नैपशॉट लेने की सुविधा चालू करने के लिए, CONFIG_DM_SNAPSHOT को true पर सेट करें.

F2FS का इस्तेमाल करने वाले डिवाइसों के लिए, फ़ाइल पिन करने की समस्या को ठीक करने के लिए, f2fs: export FS_NOCOW_FL flag to user कर्नेल पैच शामिल करें. f2fs: पिन की गई फ़ाइल को अलाइन करने की सुविधा वाला कर्नेल पैच भी शामिल करें.

वर्चुअल A/B, कर्नेल वर्शन 4.3 में जोड़ी गई सुविधाओं पर निर्भर करता है: snapshot और snapshot-merge टारगेट में ओवरफ़्लो स्टेटस बिट. Android 9 और इसके बाद के वर्शन वाले सभी डिवाइसों में, पहले से ही कर्नेल का वर्शन 4.4 या इसके बाद का होना चाहिए.

कंप्रेस किए गए स्नैपशॉट की सुविधा चालू करने के लिए, कम से कम 4.19 वर्शन का कर्नेल होना चाहिए. CONFIG_DM_USER=m या CONFIG_DM_USER=y पर सेट करें. अगर पहले विकल्प (मॉड्यूल) का इस्तेमाल किया जा रहा है, तो मॉड्यूल को पहले चरण की रैमडिस्क में लोड करना होगा. ऐसा करने के लिए, डिवाइस के Makefile में यह लाइन जोड़ें:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

फ़ास्टबूट टूल में हुए बदलाव

Android 11 में, fastboot प्रोटोकॉल में ये बदलाव किए गए हैं:

  • getvar snapshot-update-status — वह वैल्यू दिखाता है जो बूट कंट्रोल एचएएल ने बूटलोडर को दी है:
    • अगर स्थिति MERGING है, तो बूटलोडर को merging दिखाना चाहिए.
    • अगर स्थिति SNAPSHOTTED है, तो बूटलोडर को snapshotted दिखाना चाहिए.
    • ऐसा न होने पर, बूटलोडर को none दिखाना चाहिए.
  • snapshot-update merge — मर्ज करने की प्रोसेस पूरी करता है. ज़रूरत पड़ने पर, रिकवरी/fastbootd में बूट करता है. यह निर्देश सिर्फ़ तब मान्य होता है, जब snapshot-update-status की वैल्यू merging हो. साथ ही, यह सिर्फ़ fastbootd में काम करता है.
  • snapshot-update cancel — बूट कंट्रोल HAL के मर्ज स्टेटस को CANCELLED पर सेट करता है. डिवाइस लॉक होने पर, यह निर्देश अमान्य होता है.
  • erase या wipemetadata, userdata या erase या wipe के किसी ऐसे सेगमेंट में, स्नैपशॉट के मर्ज होने का स्टेटस देखना चाहिए जिसमें बूट कंट्रोल एचएएल के लिए मर्ज होने का स्टेटस सेव किया गया हो. अगर स्थिति MERGING या SNAPSHOTTED है, तो डिवाइस को ऑपरेशन रोक देना चाहिए.
  • set_active — चालू स्लॉट को बदलने वाले set_active कमांड को स्नैपशॉट मर्ज करने की स्थिति की जांच करनी चाहिए. अगर स्थिति MERGING है, तो डिवाइस को ऑपरेशन को बंद कर देना चाहिए. स्लॉट को SNAPSHOTTED स्थिति में सुरक्षित तरीके से बदला जा सकता है.

इन बदलावों को इसलिए डिज़ाइन किया गया है, ताकि डिवाइस को गलती से अनबूट न किया जा सके. हालांकि, ये बदलाव ऑटोमेटेड टूल के काम में रुकावट डाल सकते हैं. जब सभी पार्टिशन को फ़्लैश करने के लिए कमांड का इस्तेमाल किया जाता है, जैसे कि fastboot flashall को चलाना, तो हमारा सुझाव है कि आप इस फ़्लो का इस्तेमाल करें:

  1. क्वेरी getvar snapshot-update-status.
  2. अगर merging या snapshotted, तो समस्या snapshot-update cancel.
  3. फ़्लैश करने का तरीका अपनाएं.

स्टोरेज की ज़रूरतों को कम करना

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

ओटीए कंप्रेस करने के एल्गोरिदम

ओटीए पैकेज को परफ़ॉर्मेंस की अलग-अलग मेट्रिक के लिए ट्यून किया जा सकता है. Android, डेटा को कम करने के कई तरीके उपलब्ध कराता है (lz4, zstd, और none). इनमें से किसी एक तरीके का इस्तेमाल करने पर, इंस्टॉल होने में लगने वाला समय, सीओडब्ल्यू के लिए इस्तेमाल होने वाला स्टोरेज, बूट होने में लगने वाला समय, और स्नैपशॉट को मर्ज करने में लगने वाला समय अलग-अलग होता है. कंप्रेस किए गए वर्चुअल एबी के लिए, डिफ़ॉल्ट रूप से lz4 compression method विकल्प चालू होता है.

वीडियो को कंप्रेस करने की सुविधा को बेहतर बनाना

कंप्रेसन एल्गोरिदम को दो तरीकों से पसंद के मुताबिक बनाया जा सकता है: (कंप्रेसन लेवल) (स्पीड की कीमत पर हासिल किया गया कंप्रेसन) और (कंप्रेसन फ़ैक्टर) (ज़्यादा से ज़्यादा कंप्रेस की जा सकने वाली विंडो का साइज़). कंप्रेस करने का लेवल, zstd जैसे कुछ एल्गोरिदम के लिए उपलब्ध होता है. साथ ही, लेवल बदलने पर, तेज़ी और कंप्रेस करने के अनुपात के बीच समझौता करना पड़ता है. कंप्रेस करने की क्षमता से पता चलता है कि ओटीए के ज़रिए इंस्टॉल करने के दौरान, ज़्यादा से ज़्यादा कितनी विंडो कंप्रेस की जा सकती है. डिफ़ॉल्ट रूप से, यह 64k पर सेट होता है. हालांकि, इसे बदला जा सकता है. इसके लिए, आपको बिल्ड पैरामीटर PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR को पसंद के मुताबिक बनाना होगा. इस्तेमाल किए जा सकने वाले कमप्रेशन फ़ैक्टर: 4k, 8k, 16k, 32k, 64k, 128k, और 256k.

PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Pixel 8 Pro पर इंक्रीमेंटल ओटीए अपडेट

पोस्ट-इंस्टॉल फ़ेज़ के बिना इंस्टॉल होने में लगने वाला समय COW स्पेस का इस्तेमाल ओटीए के बाद बूट होने में लगने वाला समय स्नैपशॉट मर्ज करने में लगने वाला समय
lz4 18 मिनट 15 सेकंड 2.5 जीबी 32.7 सेकंड 98.6 सेकंड
zstd 24 मिनट 49 सेकंड 2.05 जीबी 36.3 सेकंड 133.2 सेकंड
कोई नहीं 16 मिनट 42 सेकंड 4.76 जीबी 28.7 सेकंड 76.6 सेकंड

Pixel 8 Pro पर ओटीए (Over-The-Air) अपडेट

पोस्ट-इंस्टॉल फ़ेज़ के बिना इंस्टॉल होने में लगने वाला समय COW स्पेस का इस्तेमाल ओटीए के बाद बूट होने में लगने वाला समय स्नैपशॉट मर्ज करने में लगने वाला समय
lz4 15 मिनट 11 सेकंड 4.16 जीबी 17.6 सेकंड 82.2 सेकंड
zstd 16 मिनट 19 सेकंड 3.46 जीबी 21.0 सेकंड 106.3 सेकंड
कोई नहीं 13 मिनट 33 सेकंड 6.39 जीबी 18.5 सेकंड 92.5 सेकंड