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

يحتوي 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.
  • يجب استبدال Zero - Block X في الجهاز الأساسي بجميع الأصفار.

تتكون تحديثات 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.

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

توفر هذه الأقسام تفاصيل تتعلق بالعمليات المستخدمة في ضغط Virtual A / B: قراءة البيانات الوصفية والدمج وإجراء انتقالات init.

قراءة البيانات الوصفية

يتم إنشاء البيانات الوصفية بواسطة البرنامج الخفي 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. تدفق التسلسل لمسار الإدخال / الإخراج في بناء البيانات الوصفية

الدمج

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

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

Merge IO path

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

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

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

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

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

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