ב-Android 10 נוספה נקודת בקרה של נתוני משתמשים (UDC), שמאפשרת ל-Android לחזור למצב הקודם אם עדכון Android אופליין (OTA) נכשל. באמצעות 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) שגורם למערכת הקבצים להוציא פקודות חיתוך לכל הבלוקסים הפנויים. dm_bow
מיירט את הקיצוצים האלה ומשתמש בהם כדי להגדיר רשימת חסימה ללא תשלום. לאחר מכן, פעולות הקריאה והכתיבה נשלחות למכשיר ללא שינוי, אבל לפני שמאפשרים פעולת כתיבה, הנתונים הנדרשים לשחזור מגובים בבלוק פנוי.
תהליך נקודת הביקורת
כשמחיצה עם הדגל checkpoint=fs/block
מורכבת, מערכת Android קוראת ל-restoreCheckpoint
בכונן כדי לאפשר למכשיר לשחזר כל נקודת עצירה (checkpoint) נוכחית. לאחר מכן, init
קורא לפונקציה needsCheckpoint
כדי לקבוע אם המכשיר נמצא במצב A/B של תוכנת האתחול או שהוגדר בו מספר הניסיונות החוזרים של העדכון. אם אחד מהם נכון, Android קורא ל-createCheckpoint
כדי להוסיף דגלים של התקנה או כדי ליצור מכשיר dm_bow
.
אחרי שמרכבים את המחיצה, קוד נקודת הבדיקה נקרא כדי להנפיק פעולות חיתוך.
לאחר מכן, תהליך האתחול ממשיך כרגיל. בשלב LOCKED_BOOT_COMPLETE
, Android קורא ל-commitCheckpoint
כדי לאשר את נקודת הביקורת הנוכחית, והעדכון ממשיך כרגיל.
ניהול מפתחות של Keymaster
מפתחות Keymaster משמשים להצפנת המכשיר או למטרות אחרות. כדי לנהל את המפתחות האלה, Android מעכבת את הקריאות למחיקת מפתחות עד שהנקודת הביקורת מועברת.
מעקב אחר בריאות
דימון לניטור תקינות מאמת שיש מספיק מקום בדיסק כדי ליצור נקודת עצירה. הדימון של בריאות המכונה נמצא ב-cp_healthDaemon
ב-Checkpoint.cpp
.
לדיימון הבריאות יש את ההתנהגויות הבאות שאפשר להגדיר:
ro.sys.cp_msleeptime
: קובעת את תדירות הבדיקה של השימוש בדיסק במכשיר.ro.sys.cp_min_free_bytes
: קובע את הערך המינימלי שדמון הבריאות מחפש.ro.sys.cp_commit_on_full
: קובע אם הדימון של בדיקת התקינות יפעיל מחדש את המכשיר או יאחסן את נקודת הבדיקה וימשיך כשהדיסק מלא.
ממשקי API של Checkpoint
התכונה UDC משתמשת בממשקי API של Checkpoint. לממשקי API אחרים שבהם UDC משתמשת, ראו IVold.aidl
.
void startCheckpoint(int retry)
יצירת נקודת עצירה.
המסגרת קוראת לשיטה הזו כשהיא מוכנה להתחיל עדכון. נקודת הבדיקה נוצרת לפני שמערכות קבצים עם נקודות בדיקה, כמו userdata, מותקנות לקריאה וכתיבה אחרי הפעלה מחדש. אם מספר הניסיונות החוזרים הוא חיובי, ה-API מטפל במעקב אחר הניסיונות החוזרים, והעדכן קורא ל-needsRollback
כדי לבדוק אם נדרש החזרה לאחור של העדכון. אם מספר הניסיונות החוזרים הוא -1
, ה-API מקבל את ההחלטה של מנהל האתחול A/B.
השיטה הזו לא נקראת כשמבצעים עדכון A/B רגיל.
void commitChanges()
שומר את השינויים.
המערכת קוראת לשיטה הזו אחרי ההפעלה מחדש, כשהשינויים מוכנים להתחייבות. הקריאה מתבצעת לפני שהנתונים (כמו תמונות, סרטונים, הודעות SMS, אישור קבלה מהשרת) נכתבים ב-userdata, וגם לפני 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
בקובץ init.hardware.rc
, בקטע on late-fs
, צריך לוודא שיש:
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.