نظرة عامة على اختبارات A/B الافتراضية

ميزة "التحديث الثنائي الظاهري" هي آلية التحديث الرئيسية في Android. تستند ميزة "الاختبار الافتراضي من النوع A/B" إلى تحديثات "الاختبار من النوع A/B" القديمة (اطّلِع على تحديثات نظام "الاختبار من النوع A/B") والتحديثات غير المتعلّقة بميزة "الاختبار من النوع A/B" التي تم إيقافها نهائيًا في الإصدار 15 لتقليل مساحة التخزين التي تشغلها التحديثات.

لا تتوفّر في الواقع مساحة إضافية للشرائح الديناميكية في اختبار A/B الافتراضي، راجِع الشريحة الديناميكية. بدلاً من ذلك، تتم كتابة الفرق في لقطة احتياطية، ثم دمجه في القسم الأساسي بعد تأكيد نجاح عملية التشغيل. يستخدم اختبار A/B الافتراضي تنسيق لقطة شاشة خاصًا بنظام التشغيل Android. اطّلِع على تنسيق COW لللقطات المضغوطة الذي يتيح ضغط اللقطات والحدّ من استخدام مساحة القرص. في عملية التحديث التلقائي الكامل، يتم تقليل حجم اللقطة بنسبة ‎45% تقريبًا من خلال الضغط، ويتم تقليل حجم اللقطة في عملية التحديث التلقائي المتزايد بنسبة ‎55% تقريبًا.

يوفّر نظام التشغيل Android 12 خيار ضغط A/B الافتراضي لضغط الأقسام التي تم أخذ لقطات لها. يوفّر اختبار A/B الافتراضي ما يلي:

  • تكون تحديثات A/B الافتراضية سلسة (يتم التحديث بالكامل في الخلفية أثناء تشغيل الجهاز) مثل تحديثات A/B. تعمل التحديثات الافتراضية لميزة "أ/ب" على تقليل الوقت الذي يكون فيه الجهاز غير متصل بالإنترنت وغير قابل للاستخدام.
  • يمكن إلغاء التعديلات على اختبار أ/ب الافتراضي. إذا تعذّر تشغيل نظام التشغيل الجديد، تتم تلقائيًا إعادة الأجهزة إلى الإصدار السابق.
  • تستخدِم تحديثات A/B الافتراضية أقل مساحة إضافية من خلال تكرار القسمَين الوحيدَين اللذَين يستخدمهما مشغِّل الإقلاع. يتم التقاط لقطة للقِسمات الأخرى القابلة للتعديل.

الخلفية والمصطلحات

يحدّد هذا القسم المصطلحات ويصف التكنولوجيا التي توفّر اختبار A/B الافتراضي. أثناء عملية التثبيت عبر الهواء، يتم إما كتابة بيانات نظام التشغيل الجديد في الفتحة الجديدة للأقسام المادية أو في جهاز COW المخصّص لنظام التشغيل Android. بعد إعادة تشغيل الجهاز، تتم دمج بيانات القسم الديناميكي مرة أخرى في الجهاز الأساسي من خلال استخدام برنامج dm-user وبرنامج snapuserd الخدمي. تتم هذه العملية بالكامل في مساحة المستخدم.

Device-mapper

أداة Device-mapper هي طبقة كتل افتراضية في Linux تُستخدَم غالبًا في Android. باستخدام الأقسام الديناميكية، تكون الأقسام مثل /system عبارة عن حزمة من الأجهزة المتعدّدة الطبقات:

  • في أسفل الحزمة، يتوفّر القسم super (على سبيل المثال، /dev/block/by-name/super).
  • في المنتصف، يظهر جهاز dm-linear يحدِّد الكتل في super partition التي تشكّل القسم الديناميكي المحدَّد. يظهر هذا الرمز على النحو التالي: /dev/block/mapper/system_[a|b] على جهاز A/B أو /dev/block/mapper/system على جهاز غير A/B.
  • في أعلى الصفحة، يظهر جهاز dm-verity تم إنشاؤه للأقسام التي تم التحقّق منها. يتحقق هذا الجهاز من صحة توقيع الحِزم على جهاز dm-linear. يظهر باسم /dev/block/mapper/system-verity وهو مصدر نقطة التثبيت /system.

يعرض الشكل 1 شكل الحزمة ضمن نقطة الربط /system.

تجميع الأقسام تحت
النظام

الشكل 1: تجميع تحت نقطة تثبيت ‎ /system

اللقطات المضغوطة

في Android 12 والإصدارات الأحدث، يمكنك تفعيل لقطات البيانات المضغوطة في الإصدار المُنشئ الخاص بك لتلبية متطلبات المساحة العالية في القسم /data، وذلك لأنّ متطلبات المساحة في القسم /data قد تكون عالية.

يتم إنشاء النُسخ المصغّرة الافتراضية من ميزة "اختبار A/B" استنادًا إلى المكوّنات التالية التي تتوفّر في الإصدار 12 من Android والإصدارات الأحدث:

  • dm-user، وهي وحدة نواة مشابهة لـ FUSE تسمح لمساحة المستخدم بتنفيذ أجهزة التخزين.
  • snapuserd، وهو خادم في مساحة المستخدم لتنفيذ تنسيق جديد لللقطات.

تتيح هذه المكوّنات ميزة الضغط. في الأقسام التالية، يتم تقديم التغييرات الأخرى اللازمة التي تم إجراؤها لتطبيق إمكانات اللقطات المضغوطة: تنسيق COW للّقطات المضغوطة، dm-user، وsnapuserd.

تنسيق COW للقطات المضغوطة

في Android 12 والإصدارات الأحدث، تستخدم اللقطات المضغوطة تنسيق COW خاصًا بنظام Android. يحتوي تنسيق COW على بيانات وصفية عن التحديث عبر الهواء ويضم ملفًا مؤقتًا منفصلاً يحتوي على عمليات COW وبيانات نظام التشغيل الجديدة. مقارنةً بتنسيق لقطات kernel التي لا تسمح إلا بعمليات الاستبدال (استبدال الكتلة X في الصورة الأساسية بمحتوى الكتلة Y في اللقطة)، فإنّ تنسيق COW للّقطات المضغوطة في Android أكثر تعبيرًا ويتيح العمليات التالية:

  • النسخ: يجب استبدال الكتلة X في الجهاز الأساسي بالكتلة Y في الجهاز الأساسي.
  • الاستبدال: يجب استبدال القسم X في الجهاز الأساسي بمحتوى القسم Y في اللقطة. يتم ضغط كل كتلة من هذه الكتل بتنسيق gz.
  • صفر: يجب استبدال مجموعة X في الجهاز الأساسي بمجموعة من الأصفار.
  • XOR: يخزّن جهاز COW وحدات البايت المضغوطة باستخدام XOR بين المربّع X ومربّع Y. (تتوفّر هذه الميزة في Android 13 والإصدارات الأحدث).

تتألف التحديثات الكاملة عبر شبكة غير سلكيّة (OTA) من عمليتَي استبدال وصفر فقط. يمكن أن تتضمّن التحديثات المتزايدة عبر الهواء أيضًا عمليات نسخ.

يظهر تنسيق اللقطة الكاملة على القرص على النحو التالي:

تنسيق البقرة

الشكل 2: تنسيق COW في Android على القرص

dm-user

تتيح وحدة kernel dm-user لنظام التشغيل userspace تنفيذ وحدات devmapped block devices. يؤدي إدخال جدول dm-user إلى إنشاء جهاز من النوع "غير محدّد" ضمن /dev/dm-user/<control-name>. يمكن لعملية userspace إجراء استطلاع للجهاز لتلقّي طلبات القراءة والكتابة من النواة. يحتوي كل طلب على ملف دوار مرتبط به في مساحة المستخدم لتعبئته (للقراءة) أو نشره (للكتابة).

توفّر وحدة kernel dm-user واجهة جديدة تظهر للمستخدمين في kernel وليست جزءًا من قاعدة رموز kernel.org الأساسية. وحتى ذلك الحين، تحتفظ Google بحق تعديل واجهة dm-user في Android.

snapuserd

ينفِّذ مكوّن مساحة المستخدم snapuserd في dm-user ميزة ضغط اختبار A/B الافتراضية. ‫Snapuserd هو برنامج تابع لمساحة المستخدم مسؤول عن كتابة وقراءة أجهزة Android التي تتضمّن ذاكرة تخزين قابلة للقراءة والكتابة. يجب أن تمرّ جميع عمليات الإدخال/الإخراج إلى اللقطة من خلال هذه الخدمة. أثناء تثبيت التحديثات من خلال الهواء، يتم كتابة بيانات نظام التشغيل الجديدة في اللقطة بواسطة snapuserd (مع الضغط). ويتم أيضًا هنا تحليل البيانات الوصفية وفك ترميز بيانات المجموعات الجديدة.

ضغط XOR

بالنسبة إلى الأجهزة التي تعمل بالإصدار 13 من نظام التشغيل Android والإصدارات الأحدث، تتيح ميزة ملف تعريف الارتباط التي تكون مفعّلة تلقائيًا تخزين ملف تعريف الارتباط في مساحة المستخدم لحفظ وحدات البايت المضغوطة بترميز XOR بين الكتل القديمة والكتل الجديدة. عندما يتم تغيير بضعة بايت فقط في كتلة في تحديث "الاختبار الافتراضي أ/ب"، يستخدم مخطط تخزين ضغط XOR مساحة أقل من مخطط التخزين التلقائي لأنّ اللقطات لا تخزِّن 4 كيلوبايت كاملة. يمكن إجراء هذا التخفيض في حجم اللقطة لأنّ بيانات XOR تحتوي على العديد من الأصفار، ومن الأسهل ضغطها مقارنةً ببيانات الوحدات التلقائية غير المُعدَّلة. على أجهزة Pixel، يقلل ضغط XOR من حجم اللقطة بنسبة تتراوح بين ‎25% و‎40%.

بالنسبة إلى الأجهزة التي يتم ترقيتها إلى Android 13 والإصدارات الأحدث، يجب تفعيل ميزة ضغط XOR. لمعرفة التفاصيل، يُرجى الاطّلاع على ضغط xor.

دمج اللقطات

بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 13 والإصدارات الأحدث، يتم تنفيذ عمليات دمج النبذة والنبذات في ميزة "الضغط الافتراضي لاختبار A/B" من خلال عنصر snapuserd مساحة المستخدم. يجب تفعيل هذه الميزة على الأجهزة التي يتم ترقيتها إلى الإصدار 13 من نظام التشغيل Android والإصدارات الأحدث. للاطّلاع على التفاصيل، يُرجى الاطّلاع على مقالة دمج مساحة المستخدم.

في ما يلي وصف لعملية ضغط "الاختبار الافتراضي بين مجموعتَين":

  1. يُثبِّت إطار العمل قسم /system من جهاز dm-verity، الذي يتم تجميعه فوق جهاز dm-user. وهذا يعني أنّ كل عملية I/O من نظام الملفات الجذر يتم توجيهها إلى dm-user.
  2. يوجّه dm-user عمليات الإدخال/الإخراج إلى الخادم الدائم snapuserd في مساحة المستخدم، والذي يعالج طلب الإدخال/الإخراج.
  3. عند اكتمال عملية الدمج، يُدمج الإطار dm-verity على dm-linear (system_base) ويزيل dm-user.

عملية ضغط A/B الافتراضية

الشكل 3: عملية ضغط A/B الافتراضي

يمكن أن تتم مقاطعة عملية دمج اللقطات. في حال إعادة تشغيل الجهاز أثناء عملية الدمج، ستستأنف عملية الدمج بعد إعادة التشغيل.

عمليات النقل المبدئي

عند التشغيل باستخدام لقطات مضغوطة، يجب بدء المرحلة الأولى من عملية الإعداد snapuserd لتركيب الأقسام. يتسبب ذلك في حدوث مشكلة: عند تحميل sepolicy وفرضه، يتم وضع snapuserd في السياق غير الصحيح، ويفشل طلبات القراءة، مع رفض selinux.

لحلّ هذه المشكلة، يتم نقل بيانات snapuserd بشكل متزامن مع init على النحو التالي:

  1. يبدأ الإصدار init من المرحلة الأولى عملية تشغيل snapuserd من قرص RAM، ويحفظ وصف ملف مفعَّلاً فيه في متغيّر بيئة.
  2. في المرحلة الأولى، تبدِّل أداة init نظام الملفات الجذر إلى قسم النظام، ثم تنفِّذ نسخة النظام من init.
  3. تقرأ نسخة النظام من init سياسة الأمان المجمّعة في سلسلة.
  4. يُستخدَم Init لتشغيل mlock() على جميع الصفحات المستندة إلى ext4. بعد ذلك، يتم إيقاف جميع tables لمعرّفات الأجهزة لأجهزة النُسخ الاحتياطية، ويتم إيقاف snapuserd. بعد ذلك، يُحظر القراءة من الأقسام، لأنّ ذلك يؤدي إلى حدوث مشكلة في الشدّة.
  5. باستخدام الوصف المفتوح لنسخة snapuserd من ذاكرة التخزين المؤقت للنظام، يعيد init تشغيل الخادم غير القابل للربط باستخدام سياق selinux الصحيح. يتم إعادة تفعيل جداول Device-mapper لأجهزة النُسخ الاحتياطية.
  6. يُطلِق Init munlockall()، ما يعني أنّه من الآمن تنفيذ عمليات I/O مرة أخرى.

استخدام المساحة

يقدّم الجدول التالي مقارنةً لاستخدام المساحة لمختلف آليات التحديث عبر الهواء باستخدام نظام التشغيل وحجم التحديث عبر الهواء لهواتف Pixel.

تأثير الحجم غير اختبار أ/ب أ/ب اختبار 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 ما مِن قيود مفروضة ما من خصومات ما مِن قيود مفروضة
مساحة تخزين إضافية أثناء تحديث OTA (المساحة التي تم إرجاعها بعد تطبيق تحديث OTA) ‫1.4 غيغابايت في ‎ /data 0 ‫3.8 غيغابايت2 في ‎ /data ‫2.1 غيغابايت2 في ‎ /data
إجمالي مساحة التخزين المطلوبة لتطبيق التحديثات من خلال الهواء ‫5.9 غيغابايت3 (الإصدار المميّز والإصدار العادي) ‫9 غيغابايت (فئة مميزة) ‫8.3 غيغابايت3 (الخطة الفائقة وخطة البيانات) ‫6.6 غيغابايت3 (الإصدار العادي والإصدار المخصّص للبيانات)

1يشير إلى التنسيق المُفترَض استنادًا إلى ربط Pixel.

2: يفترض أن تكون صورة النظام الجديدة بالحجم نفسه مثل الصورة الأصلية.

3تظلّ متطلبات المساحة مؤقتة إلى أن تتم إعادة التشغيل.

ميزة "التبديل التلقائي بين نظامَي التشغيل" الافتراضيَين في Android 11

كتب نظام التشغيل Android 11 من ميزة A/B الافتراضي إلى القسم الديناميكي باستخدام تنسيق COW الخاص بالنواة. وتم إيقاف هذا الإجراء نهائيًا لأنّ تنسيق COW للنواة لا يتيح الضغط.

ميزة "التثبيت المزدوج" الافتراضي في Android 12

في Android 12، يتوفّر ضغط البيانات بتنسيق COW المخصّص لنظام التشغيل Android. يتطلّب هذا الإصدار من ميزة "التحديث التلقائي (A/B)" الافتراضي ترجمة تنسيق COW الخاص بنظام Android إلى تنسيق COW الخاص بالنواة. تم استبدال هذا الإصدار في النهاية في الإصدار Android 13 الذي أزال الاعتماد على تنسيق COW للنواة وdm-snapshot أيضًا.

لتنفيذ اختبار أ/ب الافتراضي أو استخدام إمكانات اللقطات المضغوطة، اطّلِع على تنفيذ اختبار أ/ب الافتراضي.