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