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

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

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

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

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

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

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

Device-mapper

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

  • في أسفل الحزمة، يقع القسم الرئيسي الفعلي (على سبيل المثال، /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.

تستند اللقطات المضغوطة من Virtual A/B إلى المكوّنات التالية المتوفّرة في الإصدار 12 من نظام التشغيل Android والإصدارات الأحدث:

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

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

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

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

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

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

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

تنسيق البقرة

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

dm-user

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

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

snapuserd

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

ضغط XOR

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

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

دمج اللقطات

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

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

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

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

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

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

عمليات الانتقال إلى الحالة الأولية

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

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

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

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

يقدّم الجدول التالي مقارنة بين مساحة التخزين المستخدَمة لآليات تحديث البرامج عبر الأثير (OTA) المختلفة باستخدام أحجام نظام التشغيل وتحديثات البرامج عبر الأثير على هواتف Pixel.

تأثير الحجم non-A/B A/B اختبار A/B الافتراضي اختبار A/B الافتراضي (مضغوط)
صورة المصنع الأصلية ‫4.5 غيغابايت (3.8 غيغابايت للصور + 700 ميغابايت محجوزة)1 ‫9 غيغابايت (3.8 غيغابايت + 700 ميغابايت محجوزة، لشريحتَي SIM) ‫4.5 غيغابايت (3.8 غيغابايت للصورة + 700 ميغابايت محجوزة) ‫4.5 غيغابايت (3.8 غيغابايت للصورة + 700 ميغابايت محجوزة)
الأقسام الثابتة الأخرى /cache بدون تحديد نمط ما من خصومات بدون تحديد نمط
مساحة التخزين الإضافية أثناء التحديث عبر الهواء (تتم استعادة المساحة بعد تطبيق التحديث) ‫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 في القسم الديناميكي باستخدام تنسيق Kernel COW. تم إيقاف هذه الميزة نهائيًا لأنّ تنسيق Kernel COW لا يتيح الضغط.

ميزة "الإصدار الافتراضي من A/B" في Android 12

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

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