نظرة عامة على أ / ب الظاهري

يحتوي Android على آليتين للتحديث: تحديثات A / B (سلسة) وتحديثات بخلاف A / B. لتقليل تعقيد التعليمات البرمجية وتحسين عملية التحديث ، في Android 11 يتم توحيد الآليتين من خلال A / B الظاهري لتقديم تحديثات سلسة لجميع الأجهزة مع تقليل تكلفة التخزين. يوفر Android 12 خيار ضغط Virtual A / B لضغط الأقسام التي تم التقاطها. في كل من Android 11 و Android 12 ، ينطبق ما يلي:

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

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

يحدد هذا القسم المصطلحات ويصف التقنية التي تدعم أ / ب الظاهري.

جهاز مخطط

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 .

Partition stacking underneath system

الشكل 1. ضعها تحت نقطة تثبيت النظام

لقطة dm

يعتمد Virtual A / B على dm-snapshot ، وهو وحدة تعيين جهاز لالتقاط حالة جهاز التخزين. عند استخدام dm-snapshot ، هناك أربعة أجهزة قيد التشغيل:

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

Device mapping for dm-snapshot

الشكل 2. جهاز رسم الخرائط ل DM- لقطة

لقطات مضغوطة

في Android 12 والإصدارات الأحدث ، نظرًا لأن متطلبات المساحة على قسم /data يمكن أن تكون عالية ، يمكنك تمكين اللقطات المضغوطة في جهازك لتلبية متطلبات المساحة الأعلى لقسم /data .

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

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

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

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

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

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

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

مستخدم dm في Android 12

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

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

snapuserd

يقوم مكون مساحة المستخدمين snapuserd إلى dm-user بتنفيذ ضغط A / B الظاهري.

في الإصدار غير المضغوط من Virtual A / B ، (إما في Android 11 والإصدارات الأقدم ، أو في Android 12 بدون خيار اللقطة المضغوطة) ، يعد جهاز COW ملفًا خامًا. عند تمكين الضغط ، يعمل COW بدلاً من ذلك كجهاز dm-user ، وهو متصل بمثيل من البرنامج الخفي snapuserd .

لا تستخدم النواة تنسيق COW الجديد. لذا فإن المكون snapuserd يترجم الطلبات بين تنسيق Android COW والتنسيق المدمج في kernel:

Snapuserd component translating requests between Android COW format and kernel built-in format

الشكل 3. مخطط تدفق snapuserd كمترجم بين تنسيقات Android و Kernel COW

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

ضغط XOR

بالنسبة للأجهزة التي تعمل بنظام Android 13 والإصدارات الأحدث ، فإن ميزة ضغط XOR ، والتي يتم تمكينها افتراضيًا ، تتيح للمستخدمين لقطات مساحة تخزين XOR البايت المضغوطة بين الكتل القديمة والكتل الجديدة. عندما يتم تغيير عدد قليل من البايتات في الكتلة في تحديث Virtual A / B ، يستخدم نظام تخزين ضغط XOR مساحة أقل من نظام التخزين الافتراضي لأن اللقطات لا تخزن كامل وحدات بايت 4K. هذا التخفيض في حجم اللقطة ممكن لأن بيانات XOR تحتوي على العديد من الأصفار ومن السهل ضغطها من بيانات الكتلة الأولية. على أجهزة Pixel ، يقلل ضغط XOR حجم اللقطة بنسبة 25٪ إلى 40٪.

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

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

يقدم هذا القسم تفاصيل حول عملية ضغط A / B الافتراضية المستخدمة في Android 13 و Android 12.

قراءة البيانات الوصفية (Android 12)

يتم إنشاء البيانات الوصفية بواسطة البرنامج الخفي snapuserd . البيانات الوصفية هي في الأساس تعيين معرفين ، 8 بايت لكل منهما ، والتي تمثل القطاعات المراد دمجها. في dm-snapshot يطلق عليه disk_exception .

struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
};

يتم استخدام استثناء القرص عند استبدال جزء قديم من البيانات بآخر جديد.

يقوم برنامج snapuserd الخفي بقراءة ملف COW الداخلي من خلال مكتبة COW ويقوم ببناء البيانات الوصفية لكل من عمليات COW الموجودة في ملف COW.

يتم بدء قراءات البيانات الأولية من dm-snapshot في النواة عند إنشاء جهاز dm- snapshot .

يوفر الشكل أدناه مخطط تسلسل لمسار الإدخال / الإخراج لبناء البيانات الوصفية.

Sequence diagram, IO path for metadata construction

الشكل 4. تدفق التسلسل لمسار الإدخال / الإخراج في بناء البيانات الوصفية

الدمج (Android 12)

بمجرد اكتمال عملية التمهيد ، يقوم محرك التحديث بتمييز الفتحة على أنها عملية تمهيد ناجحة ويبدأ الدمج عن طريق تحويل هدف dm-snapshot إلى هدف dm-snapshot-merge .

يمشي dm-snapshot خلال البيانات الوصفية ويبدأ إدخال إدخال / إخراج دمج لكل استثناء قرص. يتم عرض نظرة عامة عالية المستوى لمسار إدخال / إخراج الدمج أدناه.

Merge IO path

الشكل 5. نظرة عامة على مسار دمج الإدخال / الإخراج

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

طبقات مخطط الجهاز

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

فيما يلي وصف لعملية ضغط 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 الافتراضية

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

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

التحولات الأولية

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

لمعالجة هذا الأمر ، انتقالات snapuserd في خطوة القفل مع init ، على النحو التالي:

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

استخدام الفضاء

يوفر الجدول التالي مقارنة بين استخدام المساحة لآليات OTA المختلفة باستخدام أحجام OS و OTA الخاصة بـ Pixel.

تأثير الحجم غير أ / ب أ / ب الظاهري أ / ب Virtual A / B (مضغوط)
الصورة الأصلية للمصنع 4.5 جيجا سوبر (3.8 جيجا صورة + 700 ميجا محجوزة) 1 9GB Super (3.8G + 700M محجوزة ، لفتحتين) 4.5 جيجا سوبر (3.8 جيجا صورة + 700 ميجا محجوز) 4.5 جيجا سوبر (3.8 جيجا صورة + 700 ميجا محجوز)
أقسام ثابتة أخرى /مخبأ لا أحد لا أحد لا أحد
تخزين إضافي أثناء OTA (تم إرجاع المساحة بعد تطبيق OTA) 1.4 جيجابايت على / بيانات 0 3.8 جيجابايت 2 على / بيانات 2.1GB 2 على / البيانات
إجمالي مساحة التخزين المطلوبة لتطبيق OTA 5.9 جيجابايت 3 (بيانات فائقة وبيانات) 9 جيجا سوبر 8.3 جيجا بايت 3 (فائقة وبيانات) 6.6 جيجا 3 (بيانات فائقة وبيانات)

1 يشير إلى التخطيط المفترض بناءً على تعيين البكسل.

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

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

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