נקודת ביקורת על נתוני משתמשים

ב-Android 10 הושקה נקודת ביקורת על נתוני משתמשים (UDC), שמאפשרת ל-Android לחזור למצב הקודם במקרה שעדכון OTA של Android נכשל. באמצעות UDC, אם עדכון OTA של Android נכשל, אפשר לחזור למצב הקודם של המכשיר בבטחה. עדכוני A/B פותרים את הבעיה הזו בהפעלה מוקדמת, אבל אין תמיכה בהחזרה לאחור כשמתבצעת שינוי במחיצה של נתוני המשתמשים (שמורכבת ב-/data).

UDC מאפשר למכשיר להחזיר את המחיצה של נתוני המשתמש למצב הקודם גם אחרי שהיא שונתה. התכונה UDC עושה זאת באמצעות יכולות של נקודות עצירה למערכת הקבצים, הטמעה חלופית כשמערכת הקבצים לא תומכת בנקודות עצירה, שילוב עם מנגנון A/B של מנהל האתחול תוך תמיכה גם בעדכונים שאינם A/B, ותמיכה בקישור של גרסאות מפתחות ובמניעת חזרה לאחור של מפתחות.

ההשפעה על המשתמשים

התכונה UDC משפרת את חוויית העדכון של OTA למשתמשים, כי פחות משתמשים מאבדים את הנתונים שלהם כשעדכון OTA נכשל. כך תוכלו לצמצם את מספר שיחות התמיכה ממשתמשים שנתקלים בבעיות במהלך תהליך העדכון. עם זאת, כשעדכון OTA נכשל, המשתמשים עשויים לראות שהמכשיר יופעל מחדש כמה פעמים.

איך זה עובד

הפונקציונליות של נקודות הביקורת במערכות קבצים שונות

במערכת הקבצים F2FS, UDC מוסיף את הפונקציונליות של נקודת הבדיקה לליבה של Linux בגרסה 4.20 ומעביר אותה לאחור לכל הליבות הנפוצות שנתמכות במכשירים עם Android 10.

במערכות קבצים אחרות, UDC משתמש במכשיר וירטואלי למיפוי מכשירים שנקרא dm_bow לצורך פונקציונליות של נקודות עצירה. dm_bow נמצא בין המכשיר למערכת הקבצים. כשמחיצות מותקנות, מתבצע TRIM שגורם למערכת הקבצים להנפיק פקודות TRIM לכל הבלוקסים הפנויים. dm_bow מיירט את הקיצוצים האלה ומשתמש בהם כדי להגדיר רשימת חסימה ללא תשלום. לאחר מכן נתוני הקריאה והכתיבה נשלחים למכשיר ללא שינויים, אבל לפני שאפשרת הכתיבה, הנתונים שדרושים לשחזור מגובים לבלוק חופשי.

תהליך הביקורת

כשמחיצה עם הדגל checkpoint=fs/block מורכבת, מערכת Android קוראת ל-restoreCheckpoint בכונן כדי לאפשר למכשיר לשחזר כל נקודת עצירה (checkpoint) נוכחית. לאחר מכן, init קורא לפונקציה needsCheckpoint כדי לקבוע אם המכשיר נמצא במצב A/B של תוכנת האתחול או שהוגדר בו מספר הניסיונות החוזרים של העדכון. אם כן, מערכת Android מפעילה את הפקודה createCheckpoint כדי להוסיף דגלי טעינה או לבנות מכשיר dm_bow.

אחרי שמרכבים את המחיצה, קוד נקודת הבדיקה נקרא כדי להנפיק פעולות חיתוך. לאחר מכן, תהליך האתחול ממשיך כרגיל. בשלב LOCKED_BOOT_COMPLETE, Android קורא ל-commitCheckpoint כדי לבצע את השמירה של נקודת הביקורת הנוכחית, והעדכון ממשיך כרגיל.

ניהול מפתחות של Keymaster

מפתחות Keymaster משמשים להצפנת המכשיר או למטרות אחרות. כדי לנהל את המפתחות האלה, Android מעכבת את הקריאות למחיקת מפתחות עד שהנקודת הביקורת מועברת.

מעקב אחר בריאות

דימון (daemon) מאמת שיש מספיק מקום בכונן כדי ליצור נקודת ביקורת (checkpoint). הדימון של בריאות המכונה נמצא ב-cp_healthDaemon ב-Checkpoint.cpp.

לדיימון הבריאות יש את ההתנהגויות הבאות שאפשר להגדיר:

  • ro.sys.cp_msleeptime: קובעת את תדירות הבדיקה של השימוש בדיסק במכשיר.
  • ro.sys.cp_min_free_bytes: קובע את הערך המינימלי שדמון הבריאות מחפש.
  • ro.sys.cp_commit_on_full: המדיניות הזו קובעת אם הדימון יוכל להפעיל מחדש את המכשיר או לבצע את נקודת הביקורת, וממשיך כשהדיסק מלא.

ממשקי API של נקודות ביקורת

התכונה UDC משתמשת בממשקי API של Checkpoint. לממשקי API אחרים שבהם UDC משתמש, ראו IVold.aidl.

void startCheckpoint(int retry)

יצירת נקודת עצירה.

כשה-framework מוכן להתחיל עדכון, הוא קורא ל-method הזה. נקודת הבדיקה נוצרת לפני שמערכות קבצים עם נקודות בדיקה, כמו userdata, מותקנות לקריאה וכתיבה אחרי הפעלה מחדש. אם מספר הניסיונות החוזרים חיובי, ה-API יטפל בניסיונות חוזרים למעקב, והעדכון קורא ל-needsRollback כדי לבדוק אם צריך להחזיר את העדכון למצב קודם. אם מספר הניסיונות החוזרים הוא -1, ה-API מקבל את ההחלטה של מנהל האתחול A/B.

המערכת לא קוראת לשיטה הזו כשמבצעים עדכון A/B רגיל.

void commitChanges()‎

שומר את השינויים.

המערכת קוראת ל-method הזה אחרי ההפעלה מחדש, כשהשינויים מוכנים להתחייבות. התכונה הזו נקראת לפני שנתונים (כמו תמונות, וידאו, הודעות SMS, קבלת קבלה דרך השרת) נכתבים לנתוני המשתמש ולפני BootComplete.

אם אין עדכון פעיל שנשמר בנקודת עצירה, לשיטה הזו אין השפעה.

abortChanges()‎

מאלץ הפעלה מחדש וחוזר לנקודת הבדיקה. כל השינויים בנתוני המשתמש מבוטל מאז ההפעלה מחדש הראשונה.

תוכנת ה-framework מפעילה את השיטה הזו אחרי הפעלה מחדש, אבל לפני commitChanges. כאשר מתבצעת קריאה לשיטה הזו, הערך של retry_counter מצטמצם. נוצרות רשומות ביומן.

bool needsRollback()

המדיניות קובעת אם צריך לבצע החזרה למצב קודם.

במכשירים שאינם נקודות בקרה, הפונקציה מחזירה את הערך 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

ב-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

הוספת מחיצה של מטא-נתונים

כדי להשתמש ב-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.

בדיקת היומנים

רשומות ביומן נוצרות כשקוראים ל-Checkpoint APIs.

אימות

כדי לבדוק את ההטמעה של UDC, מריצים את קבוצת הבדיקות VtsKernelCheckpointTest של VTS.