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

ב-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 נמצא בין המכשיר לבין מערכת הקבצים. כשמבצעים פעולת mount למחיצה, מתבצעת פעולת TRIM שגורמת למערכת הקבצים להנפיק פקודות TRIM בכל הבלוקים הפנויים. ‫dm_bow מיירט את הגיזומים האלה ומשתמש בהם כדי להגדיר רשימה של בלוקים חופשיים. פעולות הקריאה והכתיבה נשלחות למכשיר ללא שינוי, אבל לפני שמתאפשרת כתיבה, הנתונים שנדרשים לשחזור מגובים לבלוק פנוי.

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

כשמחיצה עם הדגל checkpoint=fs/block מותקנת, מערכת Android קוראת ל-restoreCheckpoint בכונן כדי לאפשר למכשיר לשחזר כל נקודת ביקורת נוכחית. ‫init מפעיל את הפונקציה needsCheckpoint כדי לקבוע אם המכשיר נמצא במצב 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: הפקודה קובעת אם שד ה-health יפעיל מחדש את המכשיר או יבצע את נקודת הבדיקה וימשיך כשהדיסק מלא.

Checkpoint APIs

התכונה 'שימוש בנתונים לשיפור השירות' משתמשת בממשקי API של נקודות ביקורת. למידע על ממשקי API אחרים שמשמשים את UDC, אפשר לעיין במאמר IVold.aidl.

‫void startCheckpoint(int retry)

יוצרת נקודת ביקורת.

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

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

void commitChanges()

מבצעים את השינויים.

המסגרת קוראת לשיטה הזו אחרי הפעלה מחדש, כשהשינויים מוכנים להתחייבות. הפעולה הזו מתבצעת לפני שנתונים (כמו תמונות, סרטונים, הודעות SMS, קבלת אישור מהשרת על קבלת הנתונים) נכתבים ב-userdata ולפני BootComplete.

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

abortChanges()‎

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

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

‫bool needsRollback()

ההגדרה קובעת אם נדרשת חזרה לגרסה קודמת.

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