ב-Android 10 הושקה נקודת ביקורת על נתוני משתמשים (UDC), שמאפשרת ל-Android לחזור למצב הקודם במקרה שעדכון OTA של Android נכשל. באמצעות 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 שגורם למערכת הקבצים להנפיק פקודות 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 מעכבת את הקריאות למחיקת מפתחות עד שהנקודת הביקורת מועברת.
מעקב אחר בריאות
דימון (daemon) מאמת שיש מספיק מקום בכונן כדי ליצור נקודת ביקורת (checkpoint). הדימון של בריאות המכונה נמצא ב-cp_healthDaemon
ב-Checkpoint.cpp
.
לדיימון הבריאות יש את ההתנהגויות הבאות שאפשר להגדיר:
ro.sys.cp_msleeptime
: קובעת את תדירות הבדיקה של השימוש בדיסק במכשיר.ro.sys.cp_min_free_bytes
: קובע את הערך המינימלי שדמון הבריאות מחפש.ro.sys.cp_commit_on_full
: המדיניות הזו קובעת אם הדימון יוכל להפעיל מחדש את המכשיר או לבצע את נקודת הביקורת, וממשיך כשהדיסק מלא.
ממשקי API של נקודות ביקורת
התכונה UDC משתמשת בממשקי API של Checkpoint. לממשקי API אחרים שבהם UDC משתמש, ראו IVold.aidl
.
void startCheckpoint(int retry)
יצירת נקודת עצירה.
כשה-framework מוכן להתחיל עדכון, הוא קורא ל-method הזה. נקודת הבדיקה נוצרת לפני שמערכות קבצים עם נקודות בדיקה, כמו userdata, מותקנות לקריאה וכתיבה אחרי הפעלה מחדש. אם מספר הניסיונות החוזרים חיובי, ה-API יטפל בניסיונות חוזרים למעקב, והעדכון קורא ל-needsRollback
כדי לבדוק אם צריך להחזיר את העדכון למצב קודם. אם מספר הניסיונות החוזרים הוא -1
, ה-API מקבל את ההחלטה של מנהל האתחול A/B.
המערכת לא קוראת לשיטה הזו כשמבצעים עדכון A/B רגיל.
void commitChanges()
שומר את השינויים.
המערכת קוראת ל-method הזה אחרי ההפעלה מחדש, כשהשינויים מוכנים להתחייבות. התכונה הזו נקראת לפני שנתונים (כמו תמונות, וידאו, הודעות SMS, קבלת קבלה דרך השרת) נכתבים לנתוני המשתמש ולפני 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
ב-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.