הטמעת Virtual A/B – תיקונים

כדי לפתור את הבעיות הידועות הבאות, צריך להשתמש בקוד מהסתעפות אחרת (Cherry-picking) מהתיקונים הבאים:

בדיקה נכונה של הנפח שניתן להקצאה בהעברה צדדית

העלאה צדדית של חבילת OTA מלאה במכשיר Virtual A/B שיש לו מחיצת-על בגודל קטן מ-*2 * sum(size of update groups)* עלולה להיכשל עם הנתונים הבאים ביומן השחזור /tmp/recovery.log:

The maximum size of all groups with suffix _b (...) has exceeded half of allocatable space for dynamic partitions ...

דוגמה ליומן:

[INFO:dynamic_partition_control_android.cc(1020)] Will overwrite existing partitions. Slot A may be unbootable until update finishes!
[...]
[ERROR:dynamic_partition_control_android.cc(803)] The maximum size of all groups with suffix _b (2147483648) has exceeded half of allocatable space for dynamic partitions 1073741824.

אם נתקלים בבעיה הזו, צריך לבחור את CL 1399393, לבצע build מחדש ולהפעיל את מחיצת האתחול או מחיצת השחזור אם המכשיר לא משתמש בשחזור כאמצעי אתחול.

תיקון שגיאת פילוח במהלך מיזוג

אחרי שמחילים עדכון OTA, במהלך תהליך המיזוג של VAB, קריאה אל update_engine_client --cancel גורמת לקריסה של CleanupPreviousUpdateAction. שגיאה פוטנציאלית של מצביע לא מוגדר קיימת גם אם markSlotSuccessful מגיע מאוחר.

הבעיה נפתרה על ידי הוספת הפונקציה StopActionInternal. ‫CleanupPreviousUpdateAction מבטל משימות בהמתנה בכיבוי סופי. הוא שומר משתנה שעוקב אחרי מזהה המשימה של המשימה בהמתנה בלולאת ההודעות. בזמן השמדה, המשימה בהמתנה מבוטלת כדי למנוע שגיאת פילוח.

כדי לתקן קריסות ב-update_engine במהלך מיזוג, צריך לוודא שהשינויים הבאים נמצאים בעץ המקור של Android 11:SIGSEGV

  • CL 1439792 (תנאי מוקדם ל-CL 1439372)
  • CL 1439372 (CleanupPreviousUpdateAction: cancel pending tasks on destroy)
  • CL 1663460 (תיקון השגיאה הפוטנציאלית של מצביע לא מוגדר כש-markSlotSuccessful מגיע מאוחר)

מניעת מיזוג מוקדם של update_engine

כשמכשיר מופעל (Android 11 ואילך), וההפעלה מסתיימת, הפונקציות update_engine נקראות ScheduleWaitMarkBootSuccessful(), ו WaitForMergeOrSchedule(). תהליך המיזוג יתחיל. עם זאת, המכשיר מופעל מחדש בחריץ הישן. מכיוון שהמיזוג כבר התחיל, המכשיר לא מצליח לאתחל והופך ללא שמיש.

מוסיפים את השינויים הבאים לעץ המקור. הערה: CL 1664859 הוא אופציונלי.

  • CL 1439792 (תנאי מוקדם ל-CL 1439372)
  • CL 1439372 (CleanupPreviousUpdateAction: cancel pending tasks on destroy)
  • CL 1663460 (תיקון השגיאה הפוטנציאלית של מצביע לא מוגדר כש-markSlotSuccessful מגיע מאוחר)
  • CL 1664859 (אופציונלי – מוסיפים unittest בשביל CleanupPreviousUpdateAction)

איך מוודאים שהגדרת dm-verity נכונה

ב-Android מגרסה 11 ואילך, יכול להיות שמכשירים יוגדרו בטעות עם האפשרויות הבאות של dm-verity:

  • CONFIG_DM_VERITY_AVB=y בקרנל
  • טוען האתחול מוגדר להשתמש בכל מצב אימות (למשל AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE) בלי AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO.

במכשירים עם ההגדרה הזו, כל שגיאת אימות גורמת למחיצת ה-vbmeta להיות פגומה, והמכשירים שאינם A/B לא פועלים. באופן דומה, אם התחילה מיזוג, יכול להיות שמכשירי A/B גם לא יפעלו. משתמשים רק בAVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO מצב האמת.

  1. מגדירים את CONFIG_DM_VERITY_AVB=n בליבה.
  2. במקום זאת, צריך להגדיר את המכשירים לשימוש במצב AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO.

מידע נוסף מופיע במאמר בנושא טיפול בשגיאות dm-verity.

מוודאים שהקובץ הממוזג מוגדר בצורה נכונה

אם אתם יוצרים תמונות מערכת ותמונות ספק בנפרד, ואז משתמשים ב-merge_target_files כדי למזג אותן, יכול להיות שהגדרות של Virtual A/B יושמטו באופן שגוי במהלך תהליך המיזוג. כדי לוודא שההגדרות של Virtual A/B נכונות בקובץ היעד הממוזג, צריך להחיל את התיקונים הבאים: CL 2084183 (מיזוג של זוגות זהים של מפתח/ערך במידע על מחיצה דינמית)

עדכון הרכיבים הנדרשים

החל מ-Android 13, ‏ snapuserd הועבר מ-vendor ramdisk ל-generic ramdisk. אם המכשיר שלכם משודרג ל-Android 13, יכול להיות שגם vendor ramdisk וגם generic ramdisk מכילים עותק של snapuserd. במצב הזה, כדי להשתמש ב-Virtual A/B צריך להשתמש בעותק המערכת של snapuserd. כדי לוודא שהעותק הנכון של snapuserd נמצא במקום, צריך להחיל את CL 2031243 (copy snapuserd to first_stage_ramdisk).