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