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

اندروید ۱۰، User Data Checkpoint (UDC) را معرفی می‌کند که به اندروید اجازه می‌دهد در صورت عدم موفقیت به‌روزرسانی اندروید از طریق هوا (OTA)، به حالت قبلی خود بازگردد. با UDC، اگر به‌روزرسانی اندروید OTA با شکست مواجه شود، دستگاه می‌تواند با خیال راحت به حالت قبلی خود بازگردد. اگرچه به‌روزرسانی‌های A/B این مشکل را برای بوت زودهنگام حل می‌کنند، اما وقتی پارتیشن داده‌های کاربر (mount شده روی /data ) تغییر کند، Rollback پشتیبانی نمی‌شود.

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

تأثیر کاربر

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

چگونه کار می‌کند؟

قابلیت Checkpoint در سیستم‌های فایل مختلف

برای سیستم فایل F2FS، UDC قابلیت Checkpoint را به هسته‌ی لینوکس ۴.۲۰ بالادستی اضافه می‌کند و آن را به تمام هسته‌های رایج پشتیبانی‌شده توسط دستگاه‌هایی که اندروید ۱۰ را اجرا می‌کنند، Backport می‌کند.

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

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

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

پس از نصب پارتیشن، کد Checkpoint برای صدور trims فراخوانی می‌شود. سپس فرآیند بوت به صورت عادی ادامه می‌یابد. در LOCKED_BOOT_COMPLETE ، اندروید commitCheckpoint را برای ثبت Checkpoint فعلی فراخوانی می‌کند و به‌روزرسانی به صورت عادی ادامه می‌یابد.

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

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

نظارت بر سلامت

یک سرویس سلامت (health daemon) تأیید می‌کند که فضای دیسک کافی برای ایجاد یک Checkpoint وجود دارد. سرویس سلامت در cp_healthDaemon در Checkpoint.cpp قرار دارد.

سرویس سلامت (health daemon) رفتارهای زیر را دارد که می‌توان آنها را پیکربندی کرد:

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

APIهای ایست بازرسی

APIهای Checkpoint توسط ویژگی UDC استفاده می‌شوند. برای سایر APIهای مورد استفاده توسط UDC، به IVold.aidl مراجعه کنید.

نقطه شروع از درجه اعتبار ساقط (امتحان مجدد)

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

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

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

تغییرات کامیت از درجه اعتبار ساقط ()

تغییرات را اعمال می‌کند.

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

اگر هیچ به‌روزرسانیِ دارایِ Checkpoint فعالی وجود نداشته باشد، این متد هیچ تاثیری ندارد.

abortChanges()

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

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

تابع بولی به Rollback نیاز دارد ()

تعیین می‌کند که آیا نیاز به عقب‌گرد (rollback) وجود دارد یا خیر.

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

پیاده‌سازی UDC

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

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

راه‌اندازی

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

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

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

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

اضافه کردن پارتیشن متادیتا

UDC برای ذخیره تعداد و کلیدهای تلاش مجدد غیر بوت لودر به یک پارتیشن فراداده نیاز دارد. یک پارتیشن فراداده تنظیم کنید و آن را در /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 نصب شده است، اضافه کنید.

بررسی لاگ‌ها

ورودی‌های لاگ هنگام فراخوانی APIهای Checkpoint ایجاد می‌شوند.

اعتبارسنجی

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