הטמעת A/B וירטואלי – תיקונים

אפשר לבחור את התיקונים הבאים כדי לטפל בבעיות הידועות הבאות.

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

יכול להיות שטעינה צדדית של חבילת OTA מלאה במכשיר 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, יוצרים מחדש את מחיצת האתחול או את מחיצת השחזור ומעבירים אותן באמצעות Flash, אם המכשיר לא משתמש בשחזור כאתחול.

תיקון segmentation fault במהלך מיזוג

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

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

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

  • 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 בליבה
  • מנהל האתחול מוגדר להשתמש בכל מצב של Verity (כמו 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.

למידע נוסף, אפשר לעיין במסמכי התיעוד של Verity: טיפול בטעויות של dm-verity.

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

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

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

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