ב-Android 10 הוצגה התכונה User Data Checkpoint (נקודת ביקורת של נתוני משתמש, UDC), שמאפשרת למערכת Android לחזור למצב הקודם שלה אם עדכון Android over-the-air (OTA) נכשל. בעזרת UDC, אם עדכון OTA של Android נכשל, המכשיר יכול לחזור בבטחה למצב הקודם שלו. למרות שעדכוני A/B פותרים את הבעיה הזו לגבי אתחול מוקדם, לא ניתן לבצע שחזור אם מחיצת נתוני המשתמשים (שמצורפת ל-/data) משתנה.
התכונה UDC מאפשרת למכשיר להחזיר את מחיצת נתוני המשתמש למצב הקודם שלה גם אחרי שהיא שונתה. תכונת ה-UDC עושה זאת באמצעות יכולות של נקודות ביקורת במערכת הקבצים, הטמעה חלופית כשמערכת הקבצים לא תומכת בנקודות ביקורת, שילוב עם מנגנון A/B של טוען האתחול ותמיכה בעדכונים שאינם A/B, ותמיכה בקישור של גרסת המפתח ומניעת חזרה לגרסה קודמת של המפתח.
השפעה על משתמשים
התכונה UDC משפרת את חוויית המשתמשים בעדכוני OTA, כי פחות משתמשים מאבדים את הנתונים שלהם כשעדכון OTA נכשל. כך אפשר לצמצם את מספר הפניות לתמיכה של משתמשים שנתקלים בבעיות במהלך תהליך העדכון. עם זאת, אם עדכון OTA נכשל, יכול להיות שהמשתמשים יבחינו בהפעלה מחדש של המכשיר מספר פעמים.
איך זה עובד
פונקציונליות של נקודות ביקורת במערכות קבצים שונות
במערכת הקבצים F2FS, UDC מוסיף את הפונקציונליות של נקודת הבדיקה לליבת Linux בגרסה 4.20 ומעלה, ומבצע backport לכל הליבות הנפוצות שנתמכות במכשירים עם Android 10.
במערכות קבצים אחרות, UDC משתמש במכשיר וירטואלי של מיפוי מכשירים שנקרא dm_bow כדי ליצור פונקציונליות של נקודת ביקורת. dm_bow נמצא בין המכשיר לבין מערכת הקבצים. כשמבצעים טעינה של מחיצה, מתבצעת פעולת TRIM שגורמת למערכת הקבצים להנפיק פקודות TRIM בכל הבלוקים הפנויים. dm_bow מיירט את הגיזומים האלה ומשתמש בהם כדי להגדיר רשימה של בלוקים חופשיים. פעולות הקריאה והכתיבה נשלחות למכשיר ללא שינוי, אבל לפני שמתאפשרת כתיבה, הנתונים שנדרשים לשחזור מגובים לבלוק פנוי.
תהליך נקודת הביקורת
כשמבצעים טעינה של מחיצה עם הדגל checkpoint=fs/block, מערכת Android קוראת את restoreCheckpoint בכונן כדי לאפשר למכשיר לשחזר כל נקודת ביקורת נוכחית. init ואז קוראת לפונקציה needsCheckpoint כדי לקבוע אם המכשיר נמצא במצב A/B של תוכנת האתחול או שהוגדר בו מספר הניסיונות החוזרים לעדכון. אם אחד מהתנאים מתקיים, מערכת Android קוראת ל-createCheckpoint כדי להוסיף mount
flags או ליצור מכשיר 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: ההגדרה הזו קובעת אם דמון הבריאות יפעיל מחדש את המכשיר או יבצע את נקודת הבדיקה וימשיך כשהדיסק מלא.
Checkpoint APIs
תכונת ה-UDC משתמשת ב-Checkpoint APIs. למידע על ממשקי API אחרים שמשמשים את UDC, אפשר לעיין במאמר IVold.aidl.
void startCheckpoint(int retry)
יוצרת נקודת ביקורת.
המסגרת קוראת לשיטה הזו כשהיא מוכנה להתחיל עדכון. נקודת הבדיקה נוצרת לפני שמערכות קבצים עם נקודות בדיקה, כמו userdata, מותקנות במצב קריאה/כתיבה אחרי הפעלה מחדש. אם מספר הניסיונות החוזרים הוא חיובי, ה-API מטפל במעקב אחר ניסיונות חוזרים, ושירות העדכונים קורא ל-needsRollback כדי לבדוק אם נדרשת החזרה למצב קודם של העדכון. אם מספר הניסיונות החוזרים הוא -1, ה-API מסתמך על ההחלטה של טוען האתחול A/B.
השיטה הזו לא מופעלת כשמבצעים עדכון רגיל של A/B.
void commitChanges()
מבצעים את השינויים.
ה-framework קורא ל-method הזו אחרי הפעלה מחדש, כשהשינויים מוכנים להתחייבות. הפעולה הזו מתבצעת לפני שנתונים (כמו תמונות, סרטונים, הודעות SMS, קבלת אישור מהשרת על קבלת הנתונים) נכתבים ב-userdata ולפני BootComplete.
אם לא קיים עדכון פעיל עם נקודת ביקורת, לשיטה הזו אין השפעה.
abortChanges()
מבצע הפעלה מחדש וחוזר לנקודת הבדיקה. מבטל את כל השינויים בנתוני המשתמש מאז האתחול הראשון.
ה-framework מפעיל את ה-method הזו אחרי הפעלה מחדש, אבל לפני commitChanges.
הערך של retry_counter יורד כשקוראים ל-method הזו. נוצרות רשומות ביומן.
bool needsRollback()
ההגדרה קובעת אם נדרשת חזרה לגרסה קודמת.
במכשירים שאינם checkpoint, הערך שמוחזר הוא false. במכשירי נקודת ביקורת, הפקודה מחזירה true
במהלך אתחול שאינו נקודת ביקורת.
הטמעה של UDC
הטמעה לדוגמה
דוגמה להטמעה של 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
הוספה של קטגוריית מטא-נתונים
כדי להשתמש ב-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.