वर्चुअल A/B की खास जानकारी

वर्चुअल A/B, Android का मुख्य अपडेट मैकेनिज़्म है. वर्चुअल A/B, लेगसी A/B अपडेट (A/B सिस्टम अपडेट देखें) और नॉन-A/B पर आधारित है. नॉन-A/B को Android 15 में बंद कर दिया गया है, ताकि अपडेट के लिए ज़्यादा जगह न लगे.

वर्चुअल ए/बी में डाइनैमिक पार्टिशन के लिए कोई अतिरिक्त स्लॉट नहीं होता. डाइनैमिक पार्टिशन देखें. इसके बजाय, डेल्टा को स्नैपशॉट में लिखा जाता है. इसके बाद, बूट होने की पुष्टि हो जाने पर, इसे बेस पार्टीशन में मर्ज कर दिया जाता है. वर्चुअल A/B, Android के लिए खास स्नैपशॉट फ़ॉर्मैट का इस्तेमाल करता है. कंप्रेस किए गए स्नैपशॉट के लिए सीओडब्ल्यू फ़ॉर्मैट देखें. इससे स्नैपशॉट को कंप्रेस किया जा सकता है और डिस्क स्पेस का इस्तेमाल कम किया जा सकता है. फ़ुल ओटीए में, कंप्रेस करने पर स्नैपशॉट का साइज़ करीब 45% कम हो जाता है. वहीं, इंक्रीमेंटल ओटीए में स्नैपशॉट का साइज़ करीब 55% कम हो जाता है.

Android 12 में, स्नैपशॉट किए गए पार्टीशन को कंप्रेस करने के लिए, वर्चुअल A/B कंप्रेशन का विकल्प मिलता है. वर्चुअल A/B टेस्टिंग की सुविधा से ये काम किए जा सकते हैं

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

बैकग्राउंड और शब्दावली

इस सेक्शन में, शब्दावली के बारे में बताया गया है. साथ ही, वर्चुअल A/B टेस्टिंग की सुविधा देने वाली टेक्नोलॉजी के बारे में जानकारी दी गई है. OTA इंस्टॉलेशन के दौरान, नए ऑपरेटिंग सिस्टम का डेटा या तो फ़िज़िकल पार्टीशन के लिए नए स्लॉट में लिखा जाता है या Android के लिए खास COW डिवाइस में लिखा जाता है. डिवाइस रीबूट होने के बाद, डाइनैमिक पार्टीशन का डेटा, dm-user और snapuserd डेमॉन का इस्तेमाल करके, डिवाइस के बेस पार्टीशन में वापस मर्ज कर दिया जाता है. यह प्रोसेस पूरी तरह से यूज़रस्पेस में होती है.

डिवाइस-मैपर

डिवाइस-मैपर, Linux का वर्चुअल ब्लॉक लेयर है. इसका इस्तेमाल अक्सर Android में किया जाता है. डाइनैमिक पार्टिशन की मदद से, /system जैसे पार्टिशन, लेयर वाले डिवाइसों का स्टैक होते हैं:

  • स्टैक में सबसे नीचे, फ़िज़िकल सुपर पार्टीशन होता है. उदाहरण के लिए, /dev/block/by-name/super.
  • बीच में dm-linear डिवाइस है. इससे पता चलता है कि सुपर पार्टिशन में मौजूद कौनसे ब्लॉक, दिए गए डाइनैमिक पार्टिशन को बनाते हैं. यह A/B डिवाइस पर /dev/block/mapper/system_[a|b] के तौर पर दिखता है या नॉन-A/B डिवाइस पर /dev/block/mapper/system के तौर पर दिखता है.
  • सबसे ऊपर, वेरिफ़ाइड पार्टिशन के लिए बनाया गया dm-verity डिवाइस होता है. यह डिवाइस पुष्टि करता है कि dm-linear डिवाइस पर ब्लॉक सही तरीके से साइन किए गए हैं. यह /dev/block/mapper/system-verity के तौर पर दिखता है और /system माउंट पॉइंट का सोर्स होता है.

पहली इमेज में दिखाया गया है कि /system माउंट पॉइंट के नीचे मौजूद स्टैक कैसा दिखता है.

सिस्टम के नीचे सेगमेंट स्टैक करना

पहली इमेज. /system माउंट पॉइंट के नीचे स्टैक किया गया

कंप्रेस किए गए स्नैपशॉट

Android 12 और इसके बाद के वर्शन में, /data पार्टीशन पर जगह की ज़रूरत ज़्यादा हो सकती है. इसलिए, /data पार्टीशन पर जगह की ज़्यादा ज़रूरत को पूरा करने के लिए, अपने बिल्ड में कंप्रेस किए गए स्नैपशॉट चालू किए जा सकते हैं.

वर्चुअल ए/बी कंप्रेस किए गए स्नैपशॉट, Android 12 और इसके बाद के वर्शन में उपलब्ध इन कॉम्पोनेंट पर आधारित होते हैं:

  • dm-user, FUSE की तरह एक कर्नेल मॉड्यूल है. यह उपयोगकर्ताओं को ब्लॉक डिवाइस लागू करने की अनुमति देता है.
  • snapuserd, यह एक यूज़रस्पेस डेमॉन है. इसका इस्तेमाल, स्नैपशॉट के नए फ़ॉर्मैट को लागू करने के लिए किया जाता है.

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

कंप्रेस किए गए स्नैपशॉट के लिए COW फ़ॉर्मैट

Android 12 और इसके बाद के वर्शन में, कंप्रेस किए गए स्नैपशॉट, Android के लिए खास तौर पर बनाए गए COW फ़ॉर्मैट का इस्तेमाल करते हैं. सीओडब्ल्यू फ़ॉर्मैट में, ओटीए के बारे में मेटाडेटा होता है. साथ ही, इसमें सीओडब्ल्यू ऑपरेशन और नए ऑपरेटिंग सिस्टम का डेटा शामिल होता है. कर्नल स्नैपशॉट फ़ॉर्मैट में सिर्फ़ बदलें ऑपरेशन की अनुमति होती है. जैसे, स्नैपशॉट में ब्लॉक Y के कॉन्टेंट से बेस इमेज में ब्लॉक X को बदलें. वहीं, Android के कंप्रेस किए गए स्नैपशॉट के COW फ़ॉर्मैट में ज़्यादा विकल्प होते हैं. साथ ही, इसमें ये ऑपरेशन किए जा सकते हैं:

  • कॉपी करें: बेस डिवाइस में ब्लॉक X को बेस डिवाइस में ब्लॉक Y से बदल दिया जाना चाहिए.
  • बदलें: बेस डिवाइस में मौजूद ब्लॉक X को स्नैपशॉट में मौजूद ब्लॉक Y के कॉन्टेंट से बदला जाना चाहिए. इनमें से हर ब्लॉक को gz फ़ॉर्मैट में कंप्रेस किया जाता है.
  • शून्य: बेस डिवाइस में X को ब्लॉक करने पर, उसे शून्य से बदल दिया जाना चाहिए.
  • XOR: COW डिवाइस, ब्लॉक X और ब्लॉक Y के बीच XOR कंप्रेस किए गए बाइट सेव करता है. (यह सुविधा, Android 13 और इसके बाद के वर्शन में उपलब्ध है.)

पूरे OTA अपडेट में, सिर्फ़ replace और zero ऑपरेशन शामिल होते हैं. इंक्रीमेंटल ओटीए अपडेट में, कॉपी करने की कार्रवाइयां भी शामिल हो सकती हैं.

डिस्क पर मौजूद पूरे स्नैपशॉट का लेआउट ऐसा दिखता है:

काउ फ़ॉर्मैट

दूसरी इमेज. Android COW फ़ॉर्मैट ऑन डिस्क

dm-user

dm-user कर्नल मॉड्यूल, userspace को डिवाइस-मैपर ब्लॉक डिवाइसों को लागू करने की अनुमति देता है. dm-user टेबल की एंट्री, /dev/dm-user/<control-name> में एक अन्य डिवाइस बनाती है. userspace प्रोसेस, डिवाइस को पोल कर सकती है, ताकि उसे कर्नल से पढ़ने और लिखने के अनुरोध मिल सकें. हर अनुरोध से जुड़ा एक बफ़र होता है. इसका इस्तेमाल, उपयोगकर्ता स्पेस में डेटा भरने (पढ़ने के लिए) या डेटा को आगे बढ़ाने (लिखने के लिए) के लिए किया जाता है.

dm-user कर्नल मॉड्यूल, कर्नल के लिए एक नया यूज़र इंटरफ़ेस उपलब्ध कराता है. यह अपस्ट्रीम kernel.org कोड बेस का हिस्सा नहीं है. ऐसा होने तक, Google के पास Android में dm-user इंटरफ़ेस में बदलाव करने का अधिकार सुरक्षित है.

snapuserd

snapuserd userspace कॉम्पोनेंट, dm-user में वर्चुअल A/B कंप्रेशन लागू करता है. Snapuserd, उपयोगकर्ताओं के लिए उपलब्ध एक डेमॉन है. यह Android COW डिवाइसों पर डेटा लिखने और पढ़ने का काम करता है. स्नैपशॉट में सभी I/O इस सेवा के ज़रिए होने चाहिए. OTA इंस्टॉलेशन के दौरान, snapuserd (कंप्रेशन के साथ) स्नैपशॉट में नया ऑपरेटिंग सिस्टम डेटा लिखता है. मेटाडेटा को पार्स करने और नए ब्लॉक डेटा को अनपैक करने का काम भी यहीं किया जाता है.

XOR कंप्रेशन

Android 13 और उसके बाद के वर्शन के साथ लॉन्च किए गए डिवाइसों के लिए, XOR कंप्रेशन की सुविधा डिफ़ॉल्ट रूप से चालू होती है. इससे यूज़रस्पेस स्नैपशॉट, पुराने और नए ब्लॉक के बीच XOR कंप्रेस किए गए बाइट सेव कर पाते हैं. जब वर्चुअल A/B अपडेट में किसी ब्लॉक के कुछ ही बाइट बदले जाते हैं, तो XOR कंप्रेशन स्टोरेज स्कीम, डिफ़ॉल्ट स्टोरेज स्कीम की तुलना में कम जगह इस्तेमाल करती है. ऐसा इसलिए होता है, क्योंकि स्नैपशॉट में पूरे 4K बाइट सेव नहीं होते. स्नैपशॉट के साइज़ में यह कमी इसलिए आई है, क्योंकि XOR डेटा में कई शून्य होते हैं. साथ ही, इसे रॉ ब्लॉक डेटा की तुलना में कंप्रेस करना आसान होता है. Pixel डिवाइसों पर, XOR कंप्रेशन की मदद से स्नैपशॉट के साइज़ को 25% से 40% तक कम किया जा सकता है.

Android 13 और इसके बाद के वर्शन पर अपग्रेड किए जा रहे डिवाइसों के लिए, XOR कंप्रेशन चालू होना चाहिए. ज़्यादा जानकारी के लिए, XOR कंप्रेशन देखें.

स्नैपशॉट मर्ज करना

Android 13 और इसके बाद के वर्शन के साथ लॉन्च किए गए डिवाइसों के लिए, वर्चुअल A/B कंप्रेशन में स्नैपशॉट और स्नैपशॉट मर्ज करने की प्रोसेस, snapuserd userspace कॉम्पोनेंट से की जाती है. Android 13 और उसके बाद के वर्शन पर अपग्रेड करने वाले डिवाइसों के लिए, यह सुविधा चालू होनी चाहिए. ज़्यादा जानकारी के लिए, Userspace merge लेख पढ़ें.

वर्चुअल ए/बी कंप्रेशन प्रोसेस के बारे में यहां बताया गया है:

  1. फ़्रेमवर्क, dm-verity डिवाइस से /system पार्टीशन को माउंट करता है. यह dm-user डिवाइस के ऊपर स्टैक किया जाता है. इसका मतलब है कि रूट फ़ाइल सिस्टम से हर I/O को dm-user पर रूट किया जाता है.
  2. dm-user, I/O को userspace snapuserd डेमॉन पर भेजता है. यह डेमॉन, I/O अनुरोध को हैंडल करता है.
  3. मर्ज करने की प्रोसेस पूरी होने के बाद, फ़्रेमवर्क dm-verity dm-linear (system_base) के ऊपर छोटा हो जाता है और dm-user हट जाता है.

वर्चुअल A/B कंप्रेस करने की प्रोसेस

तीसरी इमेज. वर्चुअल A/B कंप्रेस करने की प्रोसेस

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

Init transitions

कंप्रेस किए गए स्नैपशॉट के साथ बूट करते समय, पहले चरण की शुरुआत में snapuserd को पार्टिशन माउंट करने के लिए शुरू करना होगा. इससे यह समस्या होती है: जब sepolicy को लोड किया जाता है और लागू किया जाता है, तो snapuserd को गलत कॉन्टेक्स्ट में रखा जाता है. साथ ही, इसके पढ़ने के अनुरोध पूरे नहीं होते हैं. ऐसा SELinux की वजह से होता है.

इस समस्या को ठीक करने के लिए, snapuserd init के साथ-साथ इस तरह से ट्रांज़िशन करता है:

  1. पहले चरण में, init ramdisk से snapuserd लॉन्च करता है. साथ ही, खुले हुए फ़ाइल-डिसक्रिप्टर को एनवायरमेंट वैरिएबल में सेव करता है.
  2. पहले चरण में init, रूट फ़ाइल सिस्टम को सिस्टम पार्टीशन पर स्विच करता है. इसके बाद, init की सिस्टम कॉपी को एक्ज़ीक्यूट करता है.
  3. सिस्टम कॉपी init, कंबाइंड sepolicy को स्ट्रिंग में पढ़ती है.
  4. Init, ext4 फ़ाइल सिस्टम वाले सभी पेजों पर mlock() को चालू करता है. इसके बाद, यह स्नैपशॉट डिवाइसों के लिए सभी डिवाइस-मैपर टेबल बंद कर देता है और snapuserd को बंद कर देता है. इसके बाद, पार्टिशन से डेटा नहीं पढ़ा जा सकता, क्योंकि ऐसा करने से डेडलॉक हो जाता है.
  5. snapuserd की ramdisk कॉपी के लिए ओपन डिस्क्रिप्टर का इस्तेमाल करने पर, init सही SELinux कॉन्टेक्स्ट के साथ डेमॉन को फिर से लॉन्च करता है. स्नैपशॉट डिवाइसों के लिए, डिवाइस-मैपर टेबल फिर से चालू की जाती हैं.
  6. Init munlockall() को शुरू करता है. अब IO को फिर से शुरू किया जा सकता है.

स्टोरेज का इस्तेमाल

यहां दी गई टेबल में, Pixel के ओएस और ओटीए के साइज़ का इस्तेमाल करके, ओटीए के अलग-अलग तरीकों के लिए इस्तेमाल की गई जगह की तुलना की गई है.

साइज़ का असर नॉन-ए/बी A/B वर्चुअल A/B वर्चुअल A/B (कंप्रेस किया गया)
ओरिजनल फ़ैक्ट्री इमेज 4.5 जीबी सुपर (3.8 जीबी इमेज + 700 एमबी रिज़र्व)1 9 जीबी सुपर (3.8 जीबी + 700 एमबी रिज़र्व, दो स्लॉट के लिए) 4.5 जीबी सुपर (3.8 जीबी इमेज + 700 एमबी रिज़र्व) 4.5 जीबी सुपर (3.8 जीबी इमेज + 700 एमबी रिज़र्व)
अन्य स्टैटिक पार्टिशन /cache कोई नहीं कोई नहीं कोई नहीं
ओटीए के दौरान अतिरिक्त स्टोरेज (ओटीए लागू होने के बाद, स्टोरेज वापस मिल जाता है) /data पर 1.4 जीबी 0 3.8 जीबी2 on /data /data पर 2.1GB2
ओटीए अपडेट के लिए ज़रूरी कुल स्टोरेज 5.9 जीबी3 (सुपर और डेटा) 9 जीबी (सुपर) 8.3 जीबी3 (सुपर और डेटा) 6.6 जीबी3 (सुपर और डेटा)

1यह Pixel मैपिंग के आधार पर तय किया गया लेआउट दिखाता है.

2मान लेता है कि नई सिस्टम इमेज का साइज़, ओरिजनल इमेज के साइज़ के बराबर है.

3रीबूट होने तक स्पेस की ज़रूरत होती है.

Android 11 वर्चुअल A/B

Android 11 के वर्चुअल A/B ने कर्नल सीओडब्ल्यू फ़ॉर्मैट का इस्तेमाल करके, डाइनैमिक पार्टिशन में लिखा. हालांकि, बाद में इसे बंद कर दिया गया, क्योंकि कर्नल सीओडब्ल्यू फ़ॉर्मैट में कंप्रेस करने की सुविधा नहीं होती.

Android 12 वर्चुअल A/B

Android 12 में, कंप्रेस करने की सुविधा उपलब्ध है. यह सुविधा, Android के लिए खास तौर पर बनाए गए COW फ़ॉर्मैट में उपलब्ध है. Virtual A/B के इस वर्शन के लिए, Android के हिसाब से बनाए गए COW को Kernel COW फ़ॉर्मैट में अनुवादित करना ज़रूरी था. बाद में, इसे Android 13 में बदल दिया गया. इससे कर्नल सीओडब्ल्यू फ़ॉर्मैट पर निर्भरता खत्म हो गई. साथ ही, dm-snapshot भी खत्म हो गया.

वर्चुअल A/B लागू करने या कंप्रेस किए गए स्नैपशॉट की सुविधाओं का इस्तेमाल करने के लिए, वर्चुअल A/B लागू करना लेख पढ़ें