ภาพรวม A/B เสมือน

Android มีกลไกการอัปเดตสองแบบ: การอัปเดต A/B (ที่ราบรื่น) และการอัปเดตที่ไม่ใช่ A/B เพื่อลดความซับซ้อนของโค้ดและปรับปรุงกระบวนการอัปเดต ใน Android 11 กลไกทั้งสองจะรวมกันเป็นหนึ่งเดียวผ่าน A/B เสมือนเพื่อนำการอัปเดตที่ราบรื่นมาสู่อุปกรณ์ทั้งหมดด้วยต้นทุนพื้นที่จัดเก็บที่ต่ำที่สุด Android 12 เสนอตัวเลือกของการบีบอัด Virtual A/B เพื่อบีบอัดพาร์ติชั่นสแน็ปช็อต ทั้งใน Android 11 และ Android 12 มีข้อกำหนดดังต่อไปนี้:

  • การอัปเดต A/B เสมือนนั้น ราบรื่น เหมือนการอัปเดต A/B การอัปเดต A/B เสมือนช่วยลดเวลาที่อุปกรณ์ออฟไลน์และไม่สามารถใช้งานได้
  • การอัปเดต A/B เสมือนสามารถ ย้อนกลับ ได้ หากระบบปฏิบัติการใหม่ไม่สามารถบู๊ตได้ อุปกรณ์จะย้อนกลับเป็นเวอร์ชันก่อนหน้าโดยอัตโนมัติ
  • การอัพเดต Virtual A/B ใช้ พื้นที่พิเศษขั้นต่ำ โดยทำซ้ำเฉพาะพาร์ติชันที่ใช้โดย bootloader พาร์ติชั่นอื่นๆ ที่สามารถอัพเดตได้จะถูกส แน็ปช็ อต

ความเป็นมาและคำศัพท์

ส่วนนี้กำหนดคำศัพท์และอธิบายเทคโนโลยีที่รองรับ A/B เสมือน

อุปกรณ์ทำแผนที่

Device-mapper เป็นเลเยอร์บล็อกเสมือนของ Linux ที่ใช้บ่อยใน Android ด้วย ไดนามิกพาร์ติชั่ น พาร์ติชั่นอย่าง /system จะเป็นสแต็กของอุปกรณ์ที่มีเลเยอร์:

  • ที่ด้านล่างของสแต็กคือฟิสิคัล ซูเปอร์ พาร์ติชัน (เช่น /dev/block/by-name/super )
  • ตรงกลางคืออุปกรณ์ dm-linear ซึ่งระบุว่าบล็อกใดในซูเปอร์พาร์ติชั่นที่สร้างพาร์ติชั่นที่กำหนด สิ่งนี้ปรากฏเป็น /dev/block/mapper/system_[a|b] บนอุปกรณ์ A/B หรือ /dev/block/mapper/system บนอุปกรณ์ที่ไม่ใช่ A/B
  • ที่ด้านบนมีอุปกรณ์ dm-verity ซึ่งสร้างขึ้นสำหรับพาร์ติชันที่ตรวจสอบแล้ว อุปกรณ์นี้ยืนยันว่าการบล็อกบนอุปกรณ์ dm-linear มีการเซ็นชื่ออย่างถูกต้อง ปรากฏเป็น /dev/block/mapper/system-verity และเป็นที่มาของ /system mount point

รูปที่ 1 แสดงให้เห็นว่าสแต็กภายใต้ /system mount point เป็นอย่างไร

Partition stacking underneath system

รูปที่ 1. กองซ้อนใต้ /จุดต่อเชื่อมระบบ

dm-snapshot

Virtual A/B อาศัย dm-snapshot ซึ่งเป็นโมดูล device-mapper สำหรับการทำสแนปชอตสถานะของอุปกรณ์จัดเก็บข้อมูล เมื่อใช้ dm-snapshot มีอุปกรณ์อยู่สี่เครื่อง:

  • อุปกรณ์ พื้นฐาน คืออุปกรณ์ที่สแนปชอต ในหน้านี้ อุปกรณ์หลักจะเป็นพาร์ติชันแบบไดนามิกเสมอ เช่น ระบบหรือผู้จำหน่าย
  • อุปกรณ์ คัดลอกเมื่อเขียน (COW) สำหรับบันทึกการเปลี่ยนแปลงไปยังอุปกรณ์พื้นฐาน ขนาดใดก็ได้ แต่ต้องใหญ่พอที่จะรองรับการเปลี่ยนแปลงทั้งหมดกับอุปกรณ์พื้นฐาน
  • อุปกรณ์ส แน็ปช็ อตถูกสร้างขึ้นโดยใช้เป้าหมายส snapshot ชอต การเขียนไปยังอุปกรณ์สแน็ปช็อตจะถูกเขียนไปยังอุปกรณ์ COW อ่านจากอุปกรณ์สแน็ปช็อตจะอ่านจากอุปกรณ์พื้นฐานหรืออุปกรณ์ COW ทั้งนี้ขึ้นอยู่กับว่าข้อมูลที่ถูกเข้าถึงมีการเปลี่ยนแปลงโดยสแน็ปช็อตหรือไม่
  • อุปกรณ์ ต้นทาง ถูกสร้างขึ้นโดยใช้เป้าหมาย snapshot-origin อต อ่านไปยังอุปกรณ์ต้นทางที่อ่านโดยตรงจากอุปกรณ์ฐาน เขียนไปยังอุปกรณ์ต้นทางเขียนโดยตรงไปยังอุปกรณ์ฐาน แต่ข้อมูลดั้งเดิมจะถูกสำรองโดยการเขียนไปยังอุปกรณ์ COW

Device mapping for dm-snapshot

รูปที่ 2. การแมปอุปกรณ์สำหรับ dm-snapshot

สแนปชอตที่บีบอัด

ใน Android 12 เนื่องจากความต้องการพื้นที่บนพาร์ติชั่น /data อาจสูง คุณจึงสามารถเปิดใช้งานสแน็ปช็อตที่บีบอัดในบิลด์ของคุณเพื่อจัดการกับความต้องการพื้นที่ที่สูงขึ้นของพาร์ติชั่น /data

สแน็ปช็อตที่บีบอัด A/B เสมือนสร้างขึ้นจากสององค์ประกอบใหม่ที่มีอยู่ใน Android 12:

  • dm-user ซึ่งเป็นโมดูลเคอร์เนลที่คล้ายกับ FUSE ที่อนุญาตให้ userspace นำอุปกรณ์บล็อกไปใช้
  • snapuserd ภูต userspace เพื่อนำรูปแบบสแน็ปช็อตใหม่ไปใช้

ส่วนประกอบเหล่านี้เปิดใช้งานการบีบอัด การเปลี่ยนแปลงที่จำเป็นอื่นๆ ที่ทำขึ้นเพื่อใช้ความสามารถของสแน็ปช็อตที่บีบอัดนั้นมีระบุไว้ในหัวข้อถัดไป: รูปแบบ COW สำหรับสแน็ปช็อตที่บีบอัด , dm-user และ Snapuserd

รูปแบบ COW สำหรับสแน็ปช็อตที่บีบอัด

ใน Android 12 สแน็ปช็อตที่บีบอัดจะใช้รูปแบบ COW ใหม่ คล้ายกับรูปแบบในตัวของเคอร์เนลที่ใช้สำหรับสแน็ปช็อตที่ไม่บีบอัด รูปแบบ COW สำหรับสแน็ปช็อตที่บีบอัดมีส่วนของข้อมูลเมตาและข้อมูลสลับกัน ข้อมูลเมตาของรูปแบบดั้งเดิมอนุญาตสำหรับการดำเนินการ "แทนที่" เท่านั้น: แทนที่บล็อก X ในภาพฐานด้วยเนื้อหาของบล็อก Y ในสแน็ปช็อต รูปแบบ COW ของสแน็ปช็อตที่บีบอัดนั้นสื่ออารมณ์ได้มากกว่าและรองรับการทำงานสามอย่าง:

  • คัดลอก - บล็อก X ในอุปกรณ์หลักควรแทนที่ด้วยบล็อก Y ในอุปกรณ์หลัก
  • แทนที่ - บล็อก X ในอุปกรณ์พื้นฐานควรแทนที่ด้วยเนื้อหาของบล็อก Y ในสแน็ปช็อต แต่ละบล็อคเหล่านี้ถูกบีบอัด gz
  • Zero - Block X ในอุปกรณ์พื้นฐานควรแทนที่ด้วยศูนย์ทั้งหมด

การอัปเดต OTA แบบเต็มประกอบด้วยการ แทนที่ และการดำเนินการ เป็นศูนย์ เท่านั้น การอัปเดต OTA ที่เพิ่มขึ้นสามารถดำเนินการ คัดลอก เพิ่มเติมได้

dm-user ใน Android 12

โมดูลเคอร์เนล dm-user ช่วยให้ userspace สามารถใช้อุปกรณ์บล็อกตัวแมปอุปกรณ์ รายการตารางผู้ใช้ dm สร้างอุปกรณ์เบ็ดเตล็ดภายใต้ /dev/dm-user/<control-name> กระบวนการ userspace สามารถสำรวจอุปกรณ์เพื่อรับคำขออ่านและเขียนจากเคอร์เนล คำขอแต่ละรายการมีบัฟเฟอร์ที่เกี่ยวข้องสำหรับ userspace เพื่อเติมข้อมูล (สำหรับการอ่าน) หรือเผยแพร่ (สำหรับการเขียน)

โมดูลเคอร์เนล dm-user มีอินเทอร์เฟซใหม่ที่ผู้ใช้มองเห็นได้กับเคอร์เนลที่ไม่ได้เป็นส่วนหนึ่งของฐานโค้ดเคอร์เนลต้นน้ำ Google ขอสงวนสิทธิ์ในการแก้ไขส่วนต่อประสาน dm-user ใน Android

Snapuserd

snapuserd userspace สำหรับ dm-user การบีบอัด A/B เสมือน

ใน Virtual A/B เวอร์ชันที่ไม่มีการบีบอัด (ทั้งใน Android 11 และต่ำกว่า หรือใน Android 12 ที่ไม่มีตัวเลือกสแน็ปช็อตที่บีบอัด) อุปกรณ์ COW จะเป็นไฟล์ดิบ เมื่อเปิดใช้งานการบีบอัด COW จะทำหน้าที่เป็นอุปกรณ์ dm-user ซึ่งเชื่อมต่อกับอินสแตนซ์ของ snapuserd daemon

เคอร์เนลไม่ได้ใช้รูปแบบ COW ใหม่ ดังนั้นส่วนประกอบ snapuserd แปลคำขอระหว่างรูปแบบ Android COW และรูปแบบในตัวของเคอร์เนล:

Snapuserd component translating requests between Android COW format and kernel built-in format

รูปที่ 3 แผนภาพการไหลของ snapuserd เป็นตัวแปลระหว่างรูปแบบ Android และ Kernel COW

การแปลและคลายการบีบอัดนี้ไม่เคยเกิดขึ้นบนดิสก์ คอมโพเนนต์ snapuserd ดักจับ COW อ่านและเขียนที่เกิดขึ้นในเคอร์เนล และนำไปใช้โดยใช้รูปแบบ Android COW

กระบวนการบีบอัด A/B เสมือน

ส่วนเหล่านี้ให้รายละเอียดเกี่ยวกับกระบวนการที่ใช้ในการบีบอัด A/B เสมือน: การอ่านข้อมูลเมตา การผสาน และการดำเนินการในช่วงเริ่มต้น

การอ่านข้อมูลเมตา

ข้อมูลเมตาถูกสร้างขึ้นโดย snapuserd daemon ข้อมูลเมตาเป็นหลักเป็นการจับคู่รหัส 2 รหัส โดยแต่ละรหัสมี 8 ไบต์ ซึ่งเป็นตัวแทนของส่วนต่างๆ ที่จะรวมเข้าด้วยกัน ใน dm-snapshot เรียกว่า disk_exception

struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
};

ข้อยกเว้นของดิสก์จะใช้เมื่อกลุ่มข้อมูลเก่าถูกแทนที่ด้วยข้อมูลใหม่

Snapuserd daemon อ่านไฟล์ COW ภายในผ่านไลบรารี COW และสร้างข้อมูลเมตาสำหรับการดำเนินการ COW แต่ละรายการที่มีอยู่ในไฟล์ COW

การอ่านข้อมูลเมตาเริ่มต้นจาก dm-snapshot ในเคอร์เนล เมื่อมีการสร้างอุปกรณ์ dm- snapshot

รูปด้านล่างแสดงแผนภาพลำดับสำหรับเส้นทาง IO สำหรับการสร้างข้อมูลเมตา

Sequence diagram, IO path for metadata construction

รูปที่ 4 ลำดับขั้นตอนสำหรับเส้นทาง IO ในการสร้างข้อมูลเมตา

ผสาน

เมื่อกระบวนการบู๊ตเสร็จสิ้น เอ็นจิ้นการอัพเดทจะทำเครื่องหมายสล็อตว่าบู๊ตสำเร็จและเริ่มการรวมโดยเปลี่ยนเป้าหมาย dm-snapshot เป็นเป้าหมาย dm-snapshot-merge

dm-snapshot อธิบายข้อมูลเมตาและเริ่มการรวม IO สำหรับข้อยกเว้นของดิสก์แต่ละรายการ ภาพรวมระดับสูงของพาธการผสาน IO แสดงอยู่ด้านล่าง

Merge IO path

รูปที่ 5. ภาพรวมพาธผสาน IO

หากรีบูตอุปกรณ์ในระหว่างกระบวนการผสาน การผสานจะดำเนินต่อไปในการรีบูตครั้งถัดไป และการผสานจะเสร็จสิ้น

การเริ่มต้นการเปลี่ยน

เมื่อทำการบูทด้วยสแน็ปช็อตที่บีบอัด init ของสเตจแรกจะต้องเริ่ม snapuserd เพื่อต่อเชื่อมพาร์ติชั่น สิ่งนี้ทำให้เกิดปัญหา: เมื่อมีการโหลดและบังคับใช้การ snapuserd sepolicy ถูกใส่ในบริบทที่ไม่ถูกต้อง และคำขออ่านล้มเหลวโดยมีการปฏิเสธ selinux

เพื่อแก้ไขปัญหานี้ snapuserd การเปลี่ยนในขั้นตอนล็อคด้วย init ดังนี้:

  1. init ขั้นตอนแรกเปิด snapuserd จาก ramdisk และบันทึกไฟล์อธิบายที่เปิดอยู่ในตัวแปรสภาพแวดล้อม
  2. init ขั้นตอนแรกสลับระบบไฟล์รูทไปยังพาร์ติชั่นระบบ จากนั้นรันสำเนาระบบของ init
  3. สำเนาระบบของ init จะอ่านการแยกส่วนรวมเป็นสตริง
  4. Init เรียกใช้ mlock() บนหน้าที่สำรอง ext4 ทั้งหมด จากนั้นจะปิดใช้งานตารางตัวแมปอุปกรณ์ทั้งหมดสำหรับอุปกรณ์สแน็ปช็อต และหยุด snapuserd หลังจากนี้ห้ามมิให้อ่านจากพาร์ติชั่นเนื่องจากการทำเช่นนั้นทำให้เกิดการหยุดชะงัก
  5. การใช้ open descriptor กับสำเนา ramdisk ของ snapuserd init จะเปิดใช้ daemon อีกครั้งด้วยบริบท selinux ที่ถูกต้อง ตาราง Device-mapper สำหรับอุปกรณ์สแน็ปช็อตถูกเปิดใช้งานอีกครั้ง
  6. Init เรียกใช้ munlockall() - สามารถทำ IO ได้อย่างปลอดภัยอีกครั้ง

การใช้พื้นที่

ตารางต่อไปนี้แสดงการเปรียบเทียบการใช้พื้นที่สำหรับกลไก OTA ต่างๆ โดยใช้ขนาด OS และ OTA ของ Pixel

ขนาดผลกระทบ ไม่ใช่ A/B A/B เสมือน A/B A/B เสมือน (บีบอัด)
ภาพโรงงานเดิม ซูเปอร์ 4.5GB (ภาพ 3.8G + สงวนไว้ 700M) 1 9GB super (สงวนไว้ 3.8G + 700M สำหรับสองช่อง) ซุปเปอร์ 4.5GB (ภาพ 3.8G + สงวนไว้ 700M) ซุปเปอร์ 4.5GB (ภาพ 3.8G + สงวนไว้ 700M)
พาร์ติชั่นแบบคงที่อื่นๆ /cache ไม่มี ไม่มี ไม่มี
พื้นที่จัดเก็บเพิ่มเติมระหว่าง OTA (พื้นที่ที่ส่งคืนหลังจากใช้ OTA) เปิด /data . 1.4GB 0 3.8GB 2 บน /data 2.1GB 2 บน /data
พื้นที่เก็บข้อมูลทั้งหมดที่ต้องใช้เพื่อใช้ OTA 5.9GB 3 (ซูเปอร์และข้อมูล) 9GB (ซุปเปอร์) 8.3GB 3 (ซูเปอร์และข้อมูล) 6.6GB 3 (ซูเปอร์และข้อมูล)

1 ระบุรูปแบบที่สมมติขึ้นตามการแมปพิกเซล

2 สมมติว่าอิมเมจระบบใหม่มีขนาดเท่ากับต้นฉบับ

3 ความต้องการพื้นที่ว่างชั่วคราวจนกว่าจะรีบูต

ในการใช้ Virtual A/B หรือใช้ความสามารถของสแน็ปช็อตที่บีบอัด โปรดดูที่ การใช้ Virtual A/B