OTA למכשירי A/B עם מחיצות דינמיות

Android 10 תומך במחיצות דינמיות, מערכת מחיצות במרחב המשתמש שאפשר ליצור בה מחיצות, לשנות את הגודל שלהן ולהשמיד אותן במהלך עדכונים אוויריים (OTA).

בדף הזה מוסבר איך לשנות את הגודל של מחיצות דינמיות במהלך עדכון במכשירי A/B שהושקו עם תמיכה במחיצות דינמיות, במכשירים עם Android 9 וגרסאות ישנות יותר.

רקע

יש מחיצה אחת מסוג super במכשיר. למחיצה הזו אין סיומת של חריץ. מכשיר ה-block חייב להתקיים יחד עם הרשומה blk_device עבור /misc ב-fstab. לדוגמה, אם בקובץ fstab מפורטים:

/dev/block/bootdevice/by-name/misc    /misc    # Other fields

במקרה כזה, מכשיר הבלוק של super חייב להופיע ב-/dev/block/bootdevice/by-name/super, אבל לא צריך לציין את המחיצה super בקובץ fstab.

במחיצה super יש שני משבצות מטא-נתונים, שממוספרות 0 ו-1, שתואמות למשבצות A/B למחיצות. בדף הזה, המשבצות למטא-נתונים נקראות 'מטא-נתונים S (מקור)' ו'מטא-נתונים T' (יעד). באופן דומה, מחיצות נקראות system_s,‏ vendor_t וכן הלאה.

לפני השדרוג, Metadata S מכיל את המידע על המחיצות הדינמיות שבשימוש (בדרך כלל, system_s,‏ vendor_s,‏ product_s וכו'). המערכת קוראת את מידות המחיצות האלו במהלך העדכון, כך שלא ניתן למחוק אותן.

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

דוגמה למטא-נתונים במכשיר:

  • מטא-נתונים 0
    • קבוצה foo_a
      • מחיצה system_a
      • מחיצה product_services_a
      • מחיצות אחרות שעודכנו על ידי Foo
    • קבוצה bar_a
      • מחיצה vendor_a
      • מחיצה product_a
      • מחיצות אחרות שעודכנו על ידי הסרגל
    • קבוצה foo_b (שאריות משדרוג קודם)
    • קבוצה bar_b (שאריות משדרוג קודם)
  • מטא-נתונים 1
    • קבוצה foo_a (פריטים שנותרו מהשדרוג הקודם)
    • קבוצה bar_a (שאריות משדרוג קודם)
    • קבוצה foo_b
      • מחיצה system_b
      • מחיצה product_services_b
      • מחיצות אחרות שעודכנו על ידי Foo
    • קבוצה bar_b
      • מחיצה vendor_b
      • מחיצה product_b
      • מחיצות אחרות שעודכנו על ידי הסרגל

אפשר להשתמש בכלי lpdump (קוד המקור נמצא ב-system/extras/partition_tools) כדי לדגום את המטא-נתונים במכשיר. לדוגמה:

lpdump --slot 0 /dev/block/bootdevice/by-name/super
lpdump --slot 1 /dev/block/bootdevice/by-name/super

תהליך עדכון

  1. מאתחלים את המטא-נתונים של המחיצה super.
    1. טוענים את ה-extents של המחיצות הדינמיות של המקור מ-Metadata S. מגדירים את M כמטא-נתונים שנטענים.
    2. מסירים את הקבוצות והמחיצות של היעד (לדוגמה, foo_t,‏ bar_t) מ-M, כך ש-M מכיל רק מחיצות וקבוצות עם הסיומת _s.
    3. מוסיפים קבוצות יעד ומחיצות בהתאם לשדה dynamic_partition_metadata במניפסט העדכון.
      הגודל של כל מחיצה מופיע ב-new_partition_info.
    4. כותבים M ל-Metadata T.
    5. ממפים את המחיצות שנוספו בממפה של המכשיר כמחיצות שאפשר לכתוב בהן.
  2. מחילים את העדכון במכשירים שחוסמו.
    1. במקרה הצורך, צריך למפות את מחיצות המקור במיפוי המכשיר כ'קריאה בלבד'. הדבר נחוץ להעלאה צדדית כי המחיצות של המקור לא ממפות לפני העדכון.
    2. צריך להחיל עדכון מלא או עדכון דלתא על כל המכשירים החסומים במיקום היעד.
    3. מחברים את המחיצות כדי להריץ את הסקריפט שלאחר ההתקנה, ואז מנתקים את המחיצות.
  3. ביטול המיפוי של המחיצות היעד

לפני ואחרי העדכון, למאפייני המערכת הבאים צריכים להיות הערכים המתאימים:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

הוספת קבוצות ומחיצות למניפסט העדכון

כשמבצעים עדכון OTA במכשיר A/B עם מחיצות דינמיות, או במכשיר A/B שמוסיף תמיכה במחיצות דינמיות, צריך להוסיף קבוצות ומחיצות למניפסט העדכון. קטע הקוד שבהמשך מציג מידע נוסף על המניפסט של העדכון לתמיכה במחיצות דינמיות. במאמר update_metadata.proto אפשר לקרוא הסבר מפורט על כל שדה.

message DeltaArchiveManifest {
    optional DynamicPartitionMetadata dynamic_partition_metadata;
}

message DynamicPartitionMetadata {
    repeated DynamicPartitionGroup groups;
}

message DynamicPartitionGroup {
    required string name;
    optional uint64 size; // maximum size of group
    repeated string partition_names;
}