نمای کلی A/B مجازی

A/B مجازی مکانیزم اصلی به‌روزرسانی اندروید است. A/B مجازی بر پایه به‌روزرسانی‌های A/B قدیمی (به به‌روزرسانی‌های سیستمی A/B مراجعه کنید) و non-A/B که در نسخه ۱۵ برای کاهش فضای اشغال‌شده به‌روزرسانی‌ها منسوخ شده است، ساخته می‌شود.

Virtual A/B در واقع اسلات اضافی برای پارتیشن‌های پویا ندارد، به بخش پارتیشن‌های پویا مراجعه کنید. در عوض، دلتا در یک اسنپ‌شات نوشته می‌شود و سپس پس از تأیید بوت موفقیت‌آمیز، در پارتیشن پایه ادغام می‌شود. Virtual A/B از یک فرمت اسنپ‌شات مخصوص اندروید استفاده می‌کند. برای اسنپ‌شات‌های فشرده به فرمت COW مراجعه کنید که امکان فشرده‌سازی اسنپ‌شات‌ها را فراهم می‌کند و استفاده از فضای دیسک را به حداقل می‌رساند. در یک OTA کامل، اندازه اسنپ‌شات با فشرده‌سازی حدود ۴۵٪ کاهش می‌یابد و اندازه اسنپ‌شات OTA افزایشی حدود ۵۵٪ کاهش می‌یابد.

اندروید ۱۲ گزینه فشرده‌سازی مجازی A/B را برای فشرده‌سازی پارتیشن‌های اسنپ‌شات‌شده ارائه می‌دهد. مجازی A/B موارد زیر را ارائه می‌دهد.

  • به‌روزرسانی‌های مجازی A/B مانند به‌روزرسانی‌های A/B یکپارچه هستند (به‌روزرسانی کاملاً در پس‌زمینه و در حالی که دستگاه در حال کار است، اتفاق می‌افتد). به‌روزرسانی‌های مجازی A/B زمان آفلاین بودن و غیرقابل استفاده بودن دستگاه را به حداقل می‌رسانند.
  • به‌روزرسانی‌های مجازی A/B را می‌توان به حالت قبل برگرداند . اگر سیستم‌عامل جدید نتواند بوت شود، دستگاه‌ها به‌طور خودکار به نسخه قبلی برمی‌گردند.
  • به‌روزرسانی‌های مجازی A/B با کپی کردن فقط پارتیشن‌هایی که توسط بوت‌لودر استفاده می‌شوند ، حداقل فضای اضافی را اشغال می‌کنند. سایر پارتیشن‌های قابل به‌روزرسانی اسنپ‌شات می‌شوند.

پیشینه و اصطلاحات

این بخش اصطلاحات را تعریف می‌کند و فناوری پشتیبانی‌کننده از A/B مجازی را شرح می‌دهد. در طول نصب OTA، داده‌های سیستم عامل جدید یا در اسلات جدید آن برای پارتیشن‌های فیزیکی یا در یک دستگاه COW مخصوص اندروید نوشته می‌شوند. پس از راه‌اندازی مجدد دستگاه، داده‌های پارتیشن پویا از طریق استفاده از dm-user و snapuserd daemon دوباره در دستگاه پایه ادغام می‌شوند. این فرآیند کاملاً در فضای کاربری اتفاق می‌افتد.

نقشه بردار دستگاه

نگاشت‌کننده‌ی دستگاه (Device-mapper) یک لایه بلوک مجازی لینوکس است که اغلب در اندروید استفاده می‌شود. با پارتیشن‌های پویا ، پارتیشن‌هایی مانند /system مجموعه‌ای از دستگاه‌های لایه‌بندی شده هستند:

  • در پایین‌ترین بخش پشته، پارتیشن فیزیکی super قرار دارد (برای مثال، /dev/block/by-name/super ).
  • در وسط یک دستگاه dm-linear قرار دارد که مشخص می‌کند کدام بلوک‌ها در super partition، پارتیشن پویای داده شده را تشکیل می‌دهند. این در یک دستگاه A/B به صورت /dev/block/mapper/system_[a|b] یا در یک دستگاه غیر A/B به صورت /dev/block/mapper/system ظاهر می‌شود.
  • در بالا یک دستگاه dm-verity قرار دارد که برای پارتیشن‌های تأیید شده ایجاد شده است. این دستگاه تأیید می‌کند که بلوک‌های روی دستگاه dm-linear به درستی امضا شده‌اند. این دستگاه به صورت /dev/block/mapper/system-verity ظاهر می‌شود و منبع نقطه اتصال /system است.

شکل ۱ نشان می‌دهد که پشته در زیر نقطه اتصال /system چگونه به نظر می‌رسد.

Partition stacking underneath
system

شکل ۱. پشته در زیر نقطه اتصال /system

عکس‌های فوری فشرده‌شده

در اندروید ۱۲ و بالاتر، از آنجایی که فضای مورد نیاز در پارتیشن /data می‌تواند زیاد باشد، می‌توانید در نسخه خود، فشرده‌سازی اسنپ‌شات‌ها را فعال کنید تا به فضای مورد نیاز پارتیشن /data رسیدگی شود.

اسنپ‌شات‌های فشرده‌شده‌ی مجازی A/B بر روی اجزای زیر که در اندروید ۱۲ و بالاتر موجود هستند، ساخته می‌شوند:

  • dm-user ، یک ماژول هسته مشابه FUSE که به userspace اجازه می‌دهد دستگاه‌های بلوکی را پیاده‌سازی کند.
  • snapuserd ، یک سرویس فضای کاربری برای پیاده‌سازی یک فرمت جدید اسنپ‌شات.

این اجزا فشرده‌سازی را فعال می‌کنند. سایر تغییرات لازم برای پیاده‌سازی قابلیت‌های اسنپ‌شات‌های فشرده‌شده در بخش‌های بعدی ارائه شده است: فرمت COW برای اسنپ‌شات‌های فشرده‌شده ، dm-user و snapuserd .

فرمت COW برای اسنپ‌شات‌های فشرده

در اندروید ۱۲ و بالاتر، اسنپ‌شات‌های فشرده‌شده از فرمت COW مخصوص اندروید استفاده می‌کنند. فرمت COW شامل فراداده‌هایی در مورد OTA است و بافرهای مجزایی دارد که شامل عملیات COW و داده‌های سیستم عامل جدید هستند. در مقایسه با فرمت اسنپ‌شات هسته که فقط عملیات جایگزینی (جایگزینی بلوک X در تصویر پایه با محتوای بلوک Y در اسنپ‌شات) را مجاز می‌دانست، فرمت COW اسنپ‌شات‌های فشرده‌شده اندروید رساتر است و از عملیات زیر پشتیبانی می‌کند:

  • کپی : بلوک X در دستگاه پایه باید با بلوک Y در دستگاه پایه جایگزین شود.
  • جایگزینی : بلوک X در دستگاه پایه باید با محتویات بلوک Y در snapshot جایگزین شود. هر یک از این بلوک‌ها به صورت gz فشرده شده‌اند.
  • صفر : بلوک X در دستگاه پایه باید با تمام صفرها جایگزین شود.
  • XOR : دستگاه COW بایت‌های فشرده‌شده‌ی XOR را بین بلوک X و بلوک Y ذخیره می‌کند. (در اندروید ۱۳ و بالاتر موجود است.)

به‌روزرسانی‌های کامل OTA فقط شامل عملیات جایگزینی و صفر هستند. به‌روزرسانی‌های افزایشی OTA می‌توانند علاوه بر این، عملیات کپی نیز داشته باشند.

طرح کلی snapshot روی دیسک به این شکل است:

cow format

شکل 2. قالب‌بندی COW اندروید روی دیسک

کاربر dm

ماژول هسته dm-user userspace این امکان را می‌دهد که دستگاه‌های بلوک نگاشت‌کننده دستگاه را پیاده‌سازی کند. یک ورودی جدول dm-user یک دستگاه متفرقه را در مسیر /dev/dm-user/<control-name> ایجاد می‌کند. یک فرآیند userspace می‌تواند دستگاه را برای دریافت درخواست‌های خواندن و نوشتن از هسته، بررسی کند. هر درخواست دارای یک بافر مرتبط برای userspace است تا یا آن را پر کند (برای خواندن) یا منتشر کند (برای نوشتن).

ماژول هسته dm-user یک رابط کاربری جدید برای هسته فراهم می‌کند که بخشی از کد اصلی kernel.org نیست. تا زمانی که این کدها وجود داشته باشند، گوگل حق تغییر رابط کاربری dm-user در اندروید را برای خود محفوظ می‌دارد.

اسنپ‌سر

کامپوننت فضای کاربری snapuserd در dm-user ، فشرده‌سازی مجازی A/B را پیاده‌سازی می‌کند. Snapuserd یک سرویس فضای کاربری است که وظیفه نوشتن و خواندن دستگاه‌های Android COW را بر عهده دارد. تمام ورودی/خروجی‌ها به snapshot باید از طریق این سرویس انجام شود. در طول نصب OTA، داده‌های جدید سیستم عامل توسط snapuserd (با فشرده‌سازی) در snapshot نوشته می‌شوند. تجزیه فراداده‌ها و باز کردن داده‌های بلوک جدید نیز در اینجا انجام می‌شود.

فشرده‌سازی XOR

برای دستگاه‌هایی که با اندروید ۱۳ و بالاتر عرضه می‌شوند، ویژگی فشرده‌سازی XOR که به طور پیش‌فرض فعال است، به اسنپ‌شات‌های فضای کاربری امکان می‌دهد تا بایت‌های فشرده‌شده XOR را بین بلوک‌های قدیمی و بلوک‌های جدید ذخیره کنند. هنگامی که فقط چند بایت در یک بلوک در به‌روزرسانی مجازی A/B تغییر می‌کنند، طرح ذخیره‌سازی فشرده‌سازی XOR از فضای کمتری نسبت به طرح ذخیره‌سازی پیش‌فرض استفاده می‌کند زیرا اسنپ‌شات‌ها ۴K بایت کامل را ذخیره نمی‌کنند. این کاهش در اندازه اسنپ‌شات امکان‌پذیر است زیرا داده‌های XOR حاوی صفرهای زیادی هستند و فشرده‌سازی آنها نسبت به داده‌های بلوک خام آسان‌تر است. در دستگاه‌های پیکسل، فشرده‌سازی XOR اندازه اسنپ‌شات را ۲۵ تا ۴۰ درصد کاهش می‌دهد.

برای دستگاه‌هایی که به اندروید ۱۳ و بالاتر ارتقا می‌یابند، فشرده‌سازی XOR باید فعال باشد. برای جزئیات بیشتر، به فشرده‌سازی XOR مراجعه کنید.

ادغام اسنپ‌شات

برای دستگاه‌هایی که با اندروید ۱۳ و بالاتر راه‌اندازی می‌شوند، فرآیندهای snapshot و ادغام snapshot در فشرده‌سازی Virtual A/B توسط کامپوننت snapuserd userspace انجام می‌شود. برای دستگاه‌هایی که به اندروید ۱۳ و بالاتر ارتقا می‌یابند، این ویژگی باید فعال باشد. برای جزئیات بیشتر، به Userspace merge مراجعه کنید.

در ادامه فرآیند فشرده‌سازی مجازی A/B شرح داده شده است:

  1. این فریم‌ورک پارتیشن /system را از یک دستگاه dm-verity که روی یک دستگاه dm-user قرار دارد، mount می‌کند. این بدان معناست که هر ورودی/خروجی از سیستم فایل ریشه به dm-user هدایت می‌شود.
  2. dm-user ورودی/خروجی را به سرویس snapuserd فضای کاربر هدایت می‌کند که درخواست ورودی/خروجی را مدیریت می‌کند.
  3. وقتی عملیات ادغام کامل شد، چارچوب dm-verity را روی dm-linear ( system_base ) قرار می‌دهد و dm-user حذف می‌کند.

فرآیند فشرده‌سازی مجازی A/B

شکل ۳. فرآیند فشرده‌سازی مجازی A/B

فرآیند ادغام snapshot می‌تواند قطع شود. اگر دستگاه در حین فرآیند ادغام راه‌اندازی مجدد شود، فرآیند ادغام پس از راه‌اندازی مجدد از سر گرفته می‌شود.

انتقال‌های اولیه

هنگام بوت شدن با اسنپ‌شات‌های فشرده، init مرحله اول باید snapuserd برای مانت کردن پارتیشن‌ها شروع کند. این یک مشکل ایجاد می‌کند: وقتی sepolicy بارگذاری و اجرا می‌شود، snapuserd در متن اشتباه قرار می‌گیرد و درخواست‌های خواندن آن با شکست مواجه می‌شوند و selinux آنها را رد می‌کند.

برای رفع این مشکل، snapuserd با init به صورت lock-step به صورت زیر عمل می‌کند:

  1. init مرحله اول، snapuserd از ramdisk اجرا می‌کند و یک توصیف‌گر فایل باز را در یک متغیر محیطی در آن ذخیره می‌کند.
  2. مرحله اول init سیستم فایل ریشه را به پارتیشن سیستم تغییر می‌دهد، سپس کپی سیستمی init را اجرا می‌کند.
  3. کپی سیستمی init ، sepolicy ترکیبی را به صورت یک رشته می‌خواند.
  4. Init تابع mlock() روی تمام صفحات ext4-backed فراخوانی می‌کند. سپس تمام جداول device-mapper را برای دستگاه‌های snapshot غیرفعال می‌کند و snapuserd متوقف می‌کند. پس از این، خواندن از پارتیشن‌ها ممنوع است، زیرا انجام این کار باعث ایجاد بن‌بست می‌شود.
  5. با استفاده از توصیفگر open برای کپی ramdisk از snapuserd ، دستور init سرویس را با زمینه selinux صحیح مجدداً راه‌اندازی می‌کند. جداول نگاشت دستگاه برای دستگاه‌های snapshot دوباره فعال می‌شوند.
  6. تابع init، تابع munlockall() را فراخوانی می‌کند - انجام دوباره عملیات IO ایمن است.

استفاده از فضا

جدول زیر مقایسه‌ای از میزان استفاده از فضا برای سازوکارهای مختلف OTA با استفاده از سیستم‌عامل و اندازه‌های OTA پیکسل ارائه می‌دهد.

تأثیر اندازه غیر A/B الف/ب الف/ب مجازی A/B مجازی (فشرده‌سازی شده)
تصویر اصلی کارخانه ۴.۵ گیگابایت فوق‌العاده (۳.۸ گیگابایت تصویر + ۷۰۰ مگابایت رزرو شده) ۱ ۹ گیگابایت حافظه‌ی فوق‌العاده (۳.۸ گیگابایت + ۷۰۰ مگابایت رزرو شده، برای دو اسلات) ۴.۵ گیگابایت فضای ذخیره‌سازی فوق‌العاده (۳.۸ گیگابایت تصویر + ۷۰۰ مگابایت رزرو شده) ۴.۵ گیگابایت فضای ذخیره‌سازی فوق‌العاده (۳.۸ گیگابایت تصویر + ۷۰۰ مگابایت رزرو شده)
سایر پارتیشن‌های استاتیک /حافظه پنهان هیچکدام هیچکدام هیچکدام
فضای ذخیره‌سازی اضافی در طول OTA (فضای بازگردانده شده پس از اعمال OTA) ۱.۴ گیگابایت روی /داده 0 ۳.۸ گیگابایت ۲ روی /داده ۲.۱ گیگابایت ۲ روی /داده
کل فضای ذخیره‌سازی مورد نیاز برای اعمال OTA ۵.۹ گیگابایت ۳ (فوق‌العاده و داده) ۹ گیگابایت (فوق‌العاده) ۸.۳ گیگابایت ۳ (فوق‌العاده و داده) ۶.۶ گیگابایت ۳ (فوق‌العاده و داده)

۱ طرح‌بندی فرضی بر اساس نگاشت پیکسلی را نشان می‌دهد.

۲- فرض می‌کند که تصویر سیستم جدید هم‌اندازه‌ی تصویر اصلی است.

۳- فضای مورد نیاز تا زمان راه‌اندازی مجدد، موقت است.

اندروید ۱۱ مجازی A/B

اندروید ۱۱ از Virtual A/B با استفاده از فرمت Kernel COW روی پارتیشن پویا نوشت. این فرمت در نهایت منسوخ شد زیرا فرمت Kernel COW از فشرده‌سازی پشتیبانی نمی‌کند.

اندروید ۱۲ مجازی A/B

در اندروید ۱۲، فشرده‌سازی به شکل فرمت COW مخصوص اندروید پشتیبانی می‌شود. این نسخه از Virtual A/B نیاز به ترجمه COW مخصوص اندروید به فرمت COW مخصوص کرنل داشت. در نهایت این فرمت در اندروید ۱۳ جایگزین شد که وابستگی به فرمت COW مخصوص کرنل و همچنین dm-snapshot را از بین برد.

برای پیاده‌سازی Virtual A/B یا استفاده از قابلیت‌های فشرده‌سازی Snapshot، به بخش پیاده‌سازی Virtual A/B مراجعه کنید.