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 เป็นอย่างไร
รูปที่ 1. กองซ้อนใต้ /จุดต่อเชื่อมระบบ
dm-snapshot
Virtual A/B อาศัย dm-snapshot
ซึ่งเป็นโมดูล device-mapper สำหรับการทำสแนปชอตสถานะของอุปกรณ์จัดเก็บข้อมูล เมื่อใช้ dm-snapshot
มีอุปกรณ์สี่เครื่องที่เล่น:
- อุปกรณ์ พื้นฐาน คืออุปกรณ์ที่สแนปชอต ในหน้านี้ อุปกรณ์หลักจะเป็นพาร์ติชันแบบไดนามิกเสมอ เช่น ระบบหรือผู้ขาย
- อุปกรณ์ คัดลอกเมื่อเขียน (COW) สำหรับบันทึกการเปลี่ยนแปลงไปยังอุปกรณ์พื้นฐาน ขนาดใดก็ได้ แต่ต้องใหญ่พอที่จะรองรับการเปลี่ยนแปลงทั้งหมดกับอุปกรณ์พื้นฐาน
- อุปกรณ์ส แน็ปช็ อตถูกสร้างขึ้นโดยใช้เป้าหมายส
snapshot
ชอต การเขียนไปยังอุปกรณ์สแน็ปช็อตจะถูกเขียนไปยังอุปกรณ์ COW อ่านจากอุปกรณ์สแนปชอตจะอ่านจากอุปกรณ์พื้นฐานหรืออุปกรณ์ COW ทั้งนี้ขึ้นอยู่กับว่าข้อมูลที่ถูกเข้าถึงมีการเปลี่ยนแปลงโดยสแน็ปช็อตหรือไม่ - อุปกรณ์ ต้นทาง ถูกสร้างขึ้นโดยใช้เป้าหมาย
snapshot-origin
ชอต อ่านไปยังอุปกรณ์ต้นทางที่อ่านโดยตรงจากอุปกรณ์ฐาน เขียนไปยังอุปกรณ์ต้นทางเขียนโดยตรงไปยังอุปกรณ์ฐาน แต่ข้อมูลดั้งเดิมจะถูกสำรองโดยการเขียนไปยังอุปกรณ์ COW
รูปที่ 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 ของสแน็ปช็อตที่บีบอัดนั้นสื่อความหมายได้มากกว่าและรองรับการทำงานต่อไปนี้:
- Copy : Block X ในอุปกรณ์ฐานควรแทนที่ด้วย block Y ในอุปกรณ์ฐาน
- แทนที่ : ควรแทนที่บล็อก X ในอุปกรณ์พื้นฐานด้วยเนื้อหาของบล็อก Y ในสแน็ปช็อต แต่ละบล็อกเหล่านี้ถูกบีบอัด gz
- Zero : ควรแทนที่ Block X ในอุปกรณ์พื้นฐานด้วยศูนย์ทั้งหมด
- XOR : อุปกรณ์ COW เก็บ XOR บีบอัดไบต์ระหว่างบล็อก X และบล็อก Y (มีให้ใน Android 13 ขึ้นไป)
การอัปเดต 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
การบีบอัด Virtual A/B
ใน Virtual A/B เวอร์ชันที่ไม่มีการบีบอัด (ทั้งใน Android 11 และต่ำกว่า หรือใน Android 12 ที่ไม่มีตัวเลือกสแน็ปช็อตที่บีบอัด) อุปกรณ์ COW จะเป็นไฟล์ดิบ เมื่อเปิดใช้งานการบีบอัด COW จะทำหน้าที่เป็นอุปกรณ์ dm-user
ซึ่งเชื่อมต่อกับอินสแตนซ์ของ snapuserd
daemon
เคอร์เนลไม่ได้ใช้รูปแบบ COW ใหม่ ดังนั้นองค์ประกอบ snapuserd
แปลคำขอระหว่างรูปแบบ Android COW และรูปแบบในตัวของเคอร์เนล:
รูปที่ 3 แผนภาพการไหลของ snapuserd เป็นตัวแปลระหว่างรูปแบบ Android และ Kernel COW
การแปลและคลายการบีบอัดนี้ไม่เคยเกิดขึ้นบนดิสก์ คอมโพเนนต์ snapuserd
ดักจับ COW อ่านและเขียนที่เกิดขึ้นในเคอร์เนล และดำเนินการโดยใช้รูปแบบ Android COW
การบีบอัด XOR
สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 13 ขึ้นไป คุณลักษณะการบีบอัด XOR ซึ่งเปิดใช้งานโดยค่าเริ่มต้น จะช่วยให้สแนปชอตของพื้นที่ผู้ใช้จัดเก็บไบต์ที่บีบอัด XOR ระหว่างบล็อกเก่าและบล็อกใหม่ เมื่อมีการเปลี่ยนแปลงเพียงไม่กี่ไบต์ในบล็อกในการอัปเดต Virtual A/B แผนการจัดเก็บการบีบอัด XOR จะใช้พื้นที่น้อยกว่ารูปแบบการจัดเก็บข้อมูลเริ่มต้น เนื่องจากสแน็ปช็อตไม่ได้จัดเก็บ 4K ไบต์แบบเต็ม การลดขนาดสแน็ปช็อตนี้เป็นไปได้เนื่องจากข้อมูล XOR มีศูนย์จำนวนมากและบีบอัดได้ง่ายกว่าข้อมูลบล็อกดิบ บนอุปกรณ์ Pixel การบีบอัด XOR จะลดขนาดสแนปชอตลง 25% ถึง 40%
สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 13 ขึ้นไป ต้องเปิดใช้งานการบีบอัด XOR สำหรับรายละเอียด โปรดดูที่ การบีบอัด XOR
กระบวนการบีบอัด A/B เสมือน
ส่วนนี้ให้รายละเอียดเกี่ยวกับกระบวนการบีบอัด Virtual A/B ที่ใช้ใน Android 13 และ Android 12
การอ่านข้อมูลเมตา (Android 12)
ข้อมูลเมตาถูกสร้างขึ้นโดย snapuserd
daemon ข้อมูลเมตาเป็นหลักเป็นการจับคู่รหัสสองรหัส โดยแต่ละรหัสมีขนาด 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 สำหรับการสร้างข้อมูลเมตา
รูปที่ 4 ลำดับขั้นตอนสำหรับเส้นทาง IO ในการสร้างข้อมูลเมตา
การรวม (Android 12)
เมื่อกระบวนการบู๊ตเสร็จสิ้น เอ็นจิ้นการอัพเดทจะทำเครื่องหมายสล็อตว่าบู๊ตสำเร็จและเริ่มการรวมโดยเปลี่ยนเป้าหมาย dm-snapshot
เป็นเป้าหมาย dm-snapshot-merge
dm-snapshot
จะอธิบายข้อมูลเมตาและเริ่มการรวม IO สำหรับข้อยกเว้นของดิสก์แต่ละรายการ ภาพรวมระดับสูงของพาธการผสาน IO แสดงอยู่ด้านล่าง
รูปที่ 5. ภาพรวมพาธผสาน IO
หากรีบูตอุปกรณ์ในระหว่างกระบวนการผสาน การผสานจะดำเนินการต่อในการรีบูตครั้งถัดไป และการผสานจะเสร็จสมบูรณ์
การวางเลเยอร์อุปกรณ์ทำแผนที่
สำหรับอุปกรณ์ที่เปิดใช้ Android 13 ขึ้นไป กระบวนการรวมสแน็ปช็อตและสแน็ปช็อตในการบีบอัด Virtual A/B จะดำเนินการโดยคอมโพเนนต์ snapuserd
userspace สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 13 ขึ้นไป ต้องเปิดใช้งานคุณสมบัตินี้ สำหรับรายละเอียด โปรดดู ที่ การผสาน Userspace
ข้อมูลต่อไปนี้อธิบายกระบวนการบีบอัด Virtual A/B:
- กรอบงานเมาต์พาร์ติชั่น
/system
จากอุปกรณ์dm-verity
ซึ่งซ้อนอยู่บนอุปกรณ์dm-user
ซึ่งหมายความว่าทุก I/O จากระบบไฟล์รูทจะถูกส่งไปยังdm-user
-
dm-user
กำหนดเส้นทาง I/O ไปยัง userspacesnapuserd
daemon ซึ่งจัดการคำขอ I/O - เมื่อการผสานเสร็จสมบูรณ์ เฟรมเวิร์กจะยุบ
dm-verity
ที่ด้านบนของdm-linear
(system_base
) และลบdm-user
รูปที่ 6. กระบวนการบีบอัด A/B เสมือน
กระบวนการรวมสแน็ปช็อตสามารถถูกขัดจังหวะได้ หากรีบูตอุปกรณ์ระหว่างกระบวนการผสาน กระบวนการผสานจะดำเนินการต่อหลังจากรีบูต
เริ่มต้นช่วงการเปลี่ยนภาพ
เมื่อทำการบูทด้วยสแน็ปช็อตที่บีบอัด init ของสเตจแรกจะต้องเริ่ม snapuserd
เพื่อต่อเชื่อมพาร์ติชั่น สิ่งนี้ก่อให้เกิดปัญหา: เมื่อมีการโหลดและบังคับใช้การ snapuserd
sepolicy
ถูกใส่ในบริบทที่ไม่ถูกต้อง และคำขออ่านล้มเหลวโดยมีการปฏิเสธ selinux
เพื่อแก้ไขปัญหานี้ snapuserd
การเปลี่ยนในขั้นตอนล็อคด้วย init
ดังนี้:
-
init
ขั้นตอนแรกเปิดsnapuserd
จาก ramdisk และบันทึกไฟล์อธิบายที่เปิดอยู่ในตัวแปรสภาพแวดล้อม - ขั้นตอนแรก
init
จะสลับระบบไฟล์รูทไปยังพาร์ติชั่นระบบ จากนั้นรันสำเนาระบบของinit
- สำเนาระบบของ
init
จะอ่านการแยกส่วนรวมเป็นสตริง -
Init
เรียกใช้mlock()
บนหน้าที่สำรอง ext4 ทั้งหมด จากนั้นจะปิดใช้งานตารางตัวแมปอุปกรณ์ทั้งหมดสำหรับอุปกรณ์สแน็ปช็อต และหยุดsnapuserd
หลังจากนี้ห้ามมิให้อ่านจากพาร์ติชั่นเนื่องจากการทำเช่นนั้นทำให้เกิดการหยุดชะงัก - การใช้ open descriptor กับสำเนา ramdisk ของ
snapuserd
init
จะเปิดใช้ daemon อีกครั้งด้วยบริบท selinux ที่ถูกต้อง ตาราง Device-mapper สำหรับอุปกรณ์สแน็ปช็อตถูกเปิดใช้งานอีกครั้ง - 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