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

ميزة "التحديث الثنائي الظاهري" هي آلية التحديث الرئيسية في Android. تستند عمليات الإصدار الافتراضي من ميزة "الاختبار التجريبي/الإصدار العلني" إلى تحديثات "الاختبار التجريبي/الإصدار العلني" القديمة (راجِع تحديثات نظام "الاختبار التجريبي/الإصدار العلني") والإصدارات غير المستندة إلى ميزة "الاختبار التجريبي/الإصدار العلني" التي تم إيقافها نهائيًا في الإصدار 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

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

  • في أسفل الحزمة، يكون القسم super (على سبيل المثال، /dev/block/by-name/super).
  • في المنتصف، يظهر جهاز dm-linear يحدِّد الكتل التي تشكّل القسم الديناميكي المحدَّد في القسم الفائق. يظهر هذا العنوان في شكل /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

يتم إنشاء النُسخ المصغّرة الافتراضية من ميزة "التحديث التلقائي" استنادًا إلى المكوّنات التالية التي تتوفّر في الإصدار 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 compression (التصغير باستخدام XOR) التي تكون مفعّلة تلقائيًا إمكانية استخدام لقطات المستخدمين لحفظ وحدات البايت المضغوطة باستخدام XOR بين الكتل القديمة والكتل الجديدة. عندما يتم تغيير بضعة بايت فقط في كتلة في تحديث "الاختبار الافتراضي أ/ب"، يستخدم مخطّط تخزين ضغط XOR مساحة أقل من مخطّط التخزين التلقائي لأنّ اللقطات لا تخزّن 4 كيلوبايت كاملة. يمكن أن يحدث هذا الانخفاض في حجم اللقطة لأنّ بيانات XOR تحتوي على العديد من الأصفار ويسهل ضغطها من بيانات الكتلة الأولية. على أجهزة Pixel، يقلل ضغط XOR من حجم اللقطة بنسبة تتراوح بين ‎25% و‎40%.

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

دمج اللقطات

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

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

  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. وبعد ذلك، تُوقف جميع جداول برامج تخصيص الأجهزة لأجهزة أخذ لقطات الشاشة، وتوقف snapuserd. بعد ذلك، يُحظر القراءة من الأقسام، حيث يؤدي ذلك إلى حدوث توقف مؤقت.
  5. يؤدي استخدام الواصف المفتوح مع نسخة ramdisk من snapuserd init إلى إعادة تشغيل البرنامج الخفي باستخدام سياق selinux الصحيح. يتم إعادة تفعيل جداول Device-mapper لأجهزة النُسخ الاحتياطية.
  6. يُطلِق Init munlockall()، ما يعني أنّه من الآمن تنفيذ عمليات I/O مرة أخرى.

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

يقدّم الجدول التالي مقارنةً لاستخدام المساحة لمختلف آليات التحديثات عبر الهواء باستخدام نظام التشغيل وحجم التحديثات عبر الهواء لهواتف 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 بدون تحديد نمط ما من خصومات بدون تحديد نمط
مساحة تخزين إضافية أثناء تحديث 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تظلّ متطلبات المساحة مؤقتة إلى أن تتم إعادة التشغيل.

اختبار A/B افتراضي لنظام Android 11

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

ميزة "التحديث التلقائي" الافتراضي في Android 12

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

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