ایست بازرسی داده‌های کاربر

‫Android 10 «ایست بازرسی داده‌های کاربر» (UDC) را معرفی می‌کند که به Android امکان می‌دهد درصورت ناموفق بودن به‌روزرسانی Android ازطریق هوا (OTA)، به وضعیت قبلی خود برگردد. با UDC، اگر به‌روزرسانی OTA در Android ناموفق باشد، دستگاه می‌تواند به‌طور ایمن به وضعیت قبلی خود برگردد. اگرچه به‌روزرسانی‌های A/B این مشکل را برای راه‌اندازی اولیه حل می‌کند، وقتی پارتیشن داده کاربر (نصب‌شده روی /data) اصلاح می‌شود، بازگرداندن پشتیبانی نمی‌شود.

«کنترل دسترسی کاربر» به دستگاه امکان می‌دهد حتی پس‌از تغییر یافتن، پارتیشن داده‌های کاربر را به حالت قبل برگرداند. ویژگی UDC این کار را با قابلیت‌های ایست بازرسی در سیستم فایل، پیاده‌سازی جایگزین درصورت عدم پشتیبانی سیستم فایل از ایست‌های بازرسی، یکپارچه‌سازی با سازوکار A/B بارکننده، و همچنین پشتیبانی از به‌روزرسانی‌های غیر A/B، و پشتیبانی از اتصال نسخه کلید و جلوگیری از برگرداندن کلید انجام می‌دهد.

تأثیر بر کاربر

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

روش کار

عملکرد ایست بازرسی در سیستم‌های فایل مختلف

برای سیستم فایل F2FS، «کنترل‌کننده داده کاربر» عملکرد ایست‌بازرسی را به هسته Linux 4.20 بالادستی اضافه می‌کند و آن را به همه هسته‌های رایج پشتیبانی‌شده توسط دستگاه‌های دارای Android 10 برمی‌گرداند.

برای سیستم‌های فایل دیگر، UDC از دستگاه مجازی نگاشت دستگاه به‌نام dm_bow برای عملکرد ایست بازرسی استفاده می‌کند. ‫dm_bow بین دستگاه و سیستم فایل قرار می‌گیرد. وقتی پارتیشنی سوار می‌شود، یک دستور trim صادر می‌شود که باعث می‌شود سیستم فایل دستورات trim را روی همه بلوک‌های آزاد صادر کند. dm_bow این برش‌ها را رهگیری می‌کند و از آن‌ها برای راه‌اندازی فهرست مسدودشده رایگان استفاده می‌کند. سپس خواندن‌ها و نوشتن‌ها بدون تغییر به دستگاه ارسال می‌شود، اما قبل‌از اینکه نوشتن مجاز شود، داده‌های موردنیاز برای بازیابی در یک بلوک آزاد پشتیبان‌گیری می‌شود.

فرایند ایست بازرسی

وقتی پارتیشنی با پرچم checkpoint=fs/block سوار می‌شود، Android restoreCheckpoint را در درایو فراخوانی می‌کند تا به دستگاه اجازه دهد هر نقطه بازرسی فعلی را بازیابی کند. سپس init تابع needsCheckpoint را فرا می‌خواند تا تعیین کند که آیا دستگاه در وضعیت bootloader A/B است یا تعداد تلاش مجدد برای به‌روزرسانی را تنظیم کرده است. اگر هریک از این دو درست باشد، Android با createCheckpoint تماس می‌گیرد تا پرچم‌های نصب را اضافه کند یا دستگاه dm_bow را بسازد.

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

مدیریت کلیدهای KeyMint (قبلاً Keymaster)

از کلیدهای KeyMint برای رمزگذاری دستگاه یا اهداف دیگر استفاده می‌شود. برای مدیریت این کلیدها، Android فراخوانی‌های حذف کلید را تا زمانی که نقطه بازرسی ثبت شود به‌تأخیر می‌اندازد.

پایش سلامت

کارگزاری سلامت بررسی می‌کند که فضای دیسک کافی برای ایجاد نقطه بازرسی وجود داشته باشد. کارگزار سلامتی در cp_healthDaemon در Checkpoint.cpp قرار دارد.

کارگزار سلامتی رفتارهای زیر را دارد که می‌توان آن‌ها را پیکربندی کرد:

  • ro.sys.cp_msleeptime: کنترل می‌کند که دستگاه هر چند وقت یک‌بار استفاده از دیسک را بررسی کند.
  • ro.sys.cp_min_free_bytes: حداقل مقداری را که دیمون سلامت به‌دنبال آن می‌گردد کنترل می‌کند.
  • ro.sys.cp_commit_on_full: کنترل می‌کند که آیا کارگزار سلامت دستگاه را بازراه‌اندازی کند یا وقتی دیسک پر است، ایست بازرسی را انجام دهد و ادامه دهد.

میاناهای برنامه‌سازی کاربردی ایست بازرسی

ویژگی UDC از «میاناهای برنامه‌سازی کاربردی ایست بازرسی» استفاده می‌کند. برای دیگر میاناهای برنامه‌سازی کاربردی که UDC استفاده می‌کند، به IVold.aidl مراجعه کنید.

void startCheckpoint(int retry)

نقطه بازرسی ایجاد می‌کند.

چارچوب وقتی آماده شروع به‌روزرسانی است این روش را فرا می‌خواند. نقطه بازرسی قبل‌از نصب شدن سیستم‌های فایل نقطه‌بازرسی‌شده مانند userdata به‌صورت خواندن/نوشتن پس‌از بازراه‌اندازی ایجاد می‌شود. اگر تعداد تلاش مجدد مثبت باشد، API تلاش‌های مجدد ردیابی را مدیریت می‌کند و به‌روزرساننده needsRollback را فرا می‌خواند تا بررسی کند آیا بازگرداندن به‌روزرسانی به نسخه قبلی لازم است یا نه. اگر تعداد دفعات تکرار -1 باشد، API به قضاوت بوت‌لودر A/B واگذار می‌کند.

این روش هنگام انجام به‌روزرسانی A/B معمولی فراخوانی نمی‌شود.

void commitChanges()

تغییرات را ثبت می‌کند.

چارچوب پس‌از بازراه‌اندازی و زمانی که تغییرات آماده تعهد شدن هستند، این روش را فرا می‌خواند. این تابع قبل‌از اینکه داده‌ها (مثل عکس‌ها، ویدیو، پیامک، رسید سرور برای دریافت) در داده‌های کاربر نوشته شود و قبل‌از BootComplete فراخوانی می‌شود.

اگر به‌روزرسانی نقطه‌وار فعالی وجود نداشته باشد، این روش تأثیری ندارد.

abortChanges()‎

دستگاه را مجبور به بازراه‌اندازی می‌کند و به ایست بازرسی برمی‌گرداند. همه تغییرات userdata را از اولین بازراه‌اندازی رها می‌کند.

چارچوب این روش را پس‌از بازراه‌اندازی اما قبل‌از commitChanges فرا می‌خواند. وقتی این روش فراخوانی می‌شود، retry_counter کاهش می‌یابد. ورودی‌های گزارش تولید می‌شوند.

‫bool needsRollback()

تعیین می‌کند که آیا بازگرداندن لازم است یا نه.

در دستگاه‌های غیرنقطه بازرسی، false را برمی‌گرداند. در دستگاه‌های نقطه بازرسی، true را درطول راه‌اندازی غیرنقطه بازرسی برمی‌گرداند.

پیاده‌سازی «کنترل‌های داده‌های کاربر»

پیاده‌سازی مرجع

برای نمونه‌ای از نحوه پیاده‌سازی UDC، به dm-bow.c مراجعه کنید. برای اسناد بیشتر درباره این ویژگی، به dm-bow.txt مراجعه کنید.

راه‌اندازی

در on fs در فایل init.hardware.rc، مطمئن شوید که موارد زیر را دارید:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early

در on late-fs در فایل init.hardware.rc، مطمئن شوید که موارد زیر را دارید:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

در فایل fstab.hardware، مطمئن شوید که /data به‌عنوان latemount برچسب‌گذاری شده است.

/dev/block/bootdevice/by-name/userdata              /data              f2fs
noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs

افزودن بخش فراداده

«مرکز داده کاربر» برای ذخیره تعداد تلاش‌های مجدد غیربوت‌لودر و کلیدها به پارتیشن فراداده نیاز دارد. یک پارتیشن فراداده راه‌اندازی کنید و آن را در /metadata زود نصب کنید.

در فایل fstab.hardware، مطمئن شوید /metadata به‌عنوان earlymount یا first_stage_mount برچسب‌گذاری شده باشد.

/dev/block/by-name/metadata           /metadata           ext4
noatime,nosuid,nodev,discard,sync
wait,formattable,first_stage_mount

بخش را با همه صفرها مقداردهی اولیه کنید.

خطوط زیر را به BoardConfig.mk اضافه کنید:

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

به‌روزرسانی سیستم‌ها

سیستم‌های F2FS

برای سیستم‌هایی که از F2FS برای قالب‌بندی داده‌ها استفاده می‌کنند، مطمئن شوید که نسخه F2FS شما از نقاط بازرسی پشتیبانی می‌کند. برای اطلاعات بیشتر، عملکرد ایست بازرسی در سیستم‌های فایل مختلف را ببینید.

پرچم checkpoint=fs را به بخش <fs_mgr_flags> در fstab برای دستگاه نصب‌شده در /data اضافه کنید.

سیستم‌های غیر F2FS

برای سیستم‌های غیر F2FS،‏ dm-bow باید در پیکربندی هسته فعال شود.

پرچم checkpoint=block را به بخش <fs_mgr_flags> در fstab برای دستگاه نصب‌شده در /data اضافه کنید.

بررسی گزارش‌ها

وقتی میاناهای برنامه‌سازی کاربردی Checkpoint فراخوانی می‌شوند، ورودی‌های گزارش تولید می‌شوند.

اعتبارسنجی

برای آزمایش کردن پیاده‌سازی UDC، VtsKernelCheckpointTest مجموعه آزمایش‌های VTS را اجرا کنید.