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

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

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

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

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

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

Device-mapper เป็นเลเยอร์บล็อกเสมือนของ Linux ที่ใช้บ่อยใน Android ด้วย dynamic partitions พาร์ติชั่นเช่น /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

รูปที่ 1 แสดงให้เห็นว่าสแต็กใต้จุดเมานต์ /system มีลักษณะอย่างไร

Partition stacking underneath system

รูปที่ 1 สแต็กภายใต้จุดเมานต์ /system

DM-สแนปชอต

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

  • อุปกรณ์ ฐาน คืออุปกรณ์ที่ถูกสแนปช็อต ในเพจนี้ อุปกรณ์พื้นฐานจะเป็นพาร์ติชันแบบไดนามิกเสมอ เช่น ระบบหรือผู้จำหน่าย
  • อุปกรณ์ copy-on-write (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 ซึ่งเป็นภูตผู้ใช้เพื่อใช้รูปแบบสแน็ปช็อตใหม่

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

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

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

  • Copy : Block X ในอุปกรณ์ฐานควรถูกแทนที่ด้วยบล็อก Y ในอุปกรณ์ฐาน
  • แทนที่ : ควรแทนที่ Block X ในอุปกรณ์ฐานด้วยเนื้อหาของบล็อก Y ในสแน็ปช็อต แต่ละบล็อกเหล่านี้ถูกบีบอัด gz
  • ศูนย์ : ควรแทนที่ Block X ในอุปกรณ์ฐานด้วยเลขศูนย์ทั้งหมด
  • XOR : อุปกรณ์ COW เก็บไบต์ XOR ที่บีบอัดไว้ระหว่างบล็อก X และบล็อก Y (ใช้งานได้ใน Android 13 ขึ้นไป)

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

ผู้ใช้ dm ใน Android 12

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

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

snapuserd

คอมโพเนนต์พื้นที่ผู้ใช้ snapuserd ถึง 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

การบีบอัดแฮคเกอร์

สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 13 ขึ้นไป ฟีเจอร์การบีบอัด XOR ซึ่งเปิดใช้โดยค่าเริ่มต้น จะทำให้สแนปชอตพื้นที่ผู้ใช้จัดเก็บไบต์ที่บีบอัด XOR ระหว่างบล็อกเก่าและบล็อกใหม่ เมื่อมีการเปลี่ยนแปลงเพียงไม่กี่ไบต์ในบล็อกในการอัพเดต Virtual A/B รูปแบบการจัดเก็บข้อมูลแบบบีบอัด XOR จะใช้พื้นที่น้อยกว่ารูปแบบการจัดเก็บข้อมูลเริ่มต้น เนื่องจากสแน็ปช็อตไม่ได้จัดเก็บไบต์ 4K เต็ม การลดขนาดสแนปช็อตนี้เป็นไปได้เนื่องจากข้อมูล XOR มีศูนย์จำนวนมากและบีบอัดได้ง่ายกว่าข้อมูลบล็อกดิบ บนอุปกรณ์ Pixel การบีบอัด XOR จะลดขนาดสแนปช็อตลง 25% ถึง 40%

สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 13 ขึ้นไป ต้องเปิดใช้การบีบอัด XOR สำหรับรายละเอียด โปรดดูที่ การบีบอัด XOR

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

ส่วนนี้ให้รายละเอียดเกี่ยวกับกระบวนการบีบอัด A/B เสมือนที่ใช้ใน Android 13 และ Android 12

การอ่านข้อมูลเมตา (Android 12)

ข้อมูลเมตาถูกสร้างขึ้นโดย snapuserd daemon ข้อมูลเมตาคือการแมป ID สองตัว โดยแต่ละ ID มีขนาด 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 ในการสร้างข้อมูลเมตา

การผสาน (Android 12)

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

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

Merge IO path

รูปที่ 5 รวมภาพรวมเส้นทาง IO

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

การแบ่งชั้นอุปกรณ์-ผู้ทำแผนที่

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

ข้อมูลต่อไปนี้จะอธิบายกระบวนการบีบอัด A/B เสมือน:

  1. เฟรมเวิร์กจะเมาท์พาร์ติชัน /system ออกจากอุปกรณ์ dm-verity ซึ่งซ้อนกันอยู่ด้านบนของอุปกรณ์ dm-user ซึ่งหมายความว่าทุก I/O จากระบบไฟล์รูทจะถูกส่งไปที่ dm-user
  2. dm-user กำหนดเส้นทาง I/O ไปยังพื้นที่ผู้ใช้ snapuserd daemon ซึ่งจัดการคำขอ I/O
  3. เมื่อการดำเนินการผสานเสร็จสมบูรณ์ เฟรมเวิร์กจะยุบ dm-verity ที่ด้านบนของ dm-linear ( system_base ) และลบ dm-user ออก

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

รูปที่ 6 กระบวนการบีบอัด A/B เสมือน

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

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

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

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

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

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

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

ขนาดผลกระทบ ไม่ใช่ A/B เอ/บี A/B เสมือน A/B เสมือน (บีบอัด)
ภาพโรงงานดั้งเดิม 4.5GB ซุปเปอร์ (ภาพ 3.8G + สำรอง 700M) 9GB super (สงวน 3.8G + 700M สำหรับสองช่อง) 4.5GB ซุปเปอร์ (ภาพ 3.8G + สำรอง 700M) 4.5GB ซุปเปอร์ (ภาพ 3.8G + สำรอง 700M)
พาร์ติชันแบบคงที่อื่น ๆ /แคช ไม่มี ไม่มี ไม่มี
พื้นที่เก็บข้อมูลเพิ่มเติม ในช่วง OTA (พื้นที่คืนหลังจากสมัคร OTA) 1.4GB บน /data 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

,

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

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

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

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

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

Device-mapper เป็นเลเยอร์บล็อกเสมือนของ Linux ที่ใช้บ่อยใน Android ด้วย dynamic partitions พาร์ติชั่นเช่น /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

รูปที่ 1 แสดงให้เห็นว่าสแต็กใต้จุดเมานต์ /system มีลักษณะอย่างไร

Partition stacking underneath system

รูปที่ 1 สแต็กภายใต้จุดเมานต์ /system

DM-สแนปชอต

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

  • อุปกรณ์ ฐาน คืออุปกรณ์ที่ถูกสแนปช็อต ในเพจนี้ อุปกรณ์พื้นฐานจะเป็นพาร์ติชันแบบไดนามิกเสมอ เช่น ระบบหรือผู้จำหน่าย
  • อุปกรณ์ copy-on-write (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 ซึ่งเป็นภูตผู้ใช้เพื่อใช้รูปแบบสแน็ปช็อตใหม่

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

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

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

  • Copy : Block X ในอุปกรณ์ฐานควรถูกแทนที่ด้วยบล็อก Y ในอุปกรณ์ฐาน
  • แทนที่ : ควรแทนที่ Block X ในอุปกรณ์ฐานด้วยเนื้อหาของบล็อก Y ในสแน็ปช็อต แต่ละบล็อกเหล่านี้ถูกบีบอัด gz
  • ศูนย์ : ควรแทนที่ Block X ในอุปกรณ์ฐานด้วยเลขศูนย์ทั้งหมด
  • XOR : อุปกรณ์ COW เก็บไบต์ XOR ที่บีบอัดไว้ระหว่างบล็อก X และบล็อก Y (ใช้งานได้ใน Android 13 ขึ้นไป)

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

ผู้ใช้ dm ใน Android 12

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

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

snapuserd

คอมโพเนนต์พื้นที่ผู้ใช้ snapuserd ถึง 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

การบีบอัดแฮคเกอร์

สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 13 ขึ้นไป ฟีเจอร์การบีบอัด XOR ซึ่งเปิดใช้โดยค่าเริ่มต้น จะทำให้สแนปชอตพื้นที่ผู้ใช้จัดเก็บไบต์ที่บีบอัด XOR ระหว่างบล็อกเก่าและบล็อกใหม่ เมื่อมีการเปลี่ยนแปลงเพียงไม่กี่ไบต์ในบล็อกในการอัพเดต Virtual A/B รูปแบบการจัดเก็บข้อมูลแบบบีบอัด XOR จะใช้พื้นที่น้อยกว่ารูปแบบการจัดเก็บข้อมูลเริ่มต้น เนื่องจากสแน็ปช็อตไม่ได้จัดเก็บไบต์ 4K เต็ม การลดขนาดสแนปช็อตนี้เป็นไปได้เนื่องจากข้อมูล XOR มีศูนย์จำนวนมากและบีบอัดได้ง่ายกว่าข้อมูลบล็อกดิบ บนอุปกรณ์ Pixel การบีบอัด XOR จะลดขนาดสแนปช็อตลง 25% ถึง 40%

สำหรับอุปกรณ์ที่อัปเกรดเป็น Android 13 ขึ้นไป ต้องเปิดใช้การบีบอัด XOR สำหรับรายละเอียด โปรดดูที่ การบีบอัด XOR

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

ส่วนนี้ให้รายละเอียดเกี่ยวกับกระบวนการบีบอัด A/B เสมือนที่ใช้ใน Android 13 และ Android 12

การอ่านข้อมูลเมตา (Android 12)

ข้อมูลเมตาถูกสร้างขึ้นโดย snapuserd daemon ข้อมูลเมตาคือการแมป ID สองตัว โดยแต่ละ ID มีขนาด 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 ในการสร้างข้อมูลเมตา

การผสาน (Android 12)

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

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

Merge IO path

รูปที่ 5 รวมภาพรวมเส้นทาง IO

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

การแบ่งชั้นอุปกรณ์-ผู้ทำแผนที่

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

ข้อมูลต่อไปนี้จะอธิบายกระบวนการบีบอัด A/B เสมือน:

  1. เฟรมเวิร์กจะเมาท์พาร์ติชัน /system ออกจากอุปกรณ์ dm-verity ซึ่งซ้อนกันอยู่ด้านบนของอุปกรณ์ dm-user ซึ่งหมายความว่าทุก I/O จากระบบไฟล์รูทจะถูกส่งไปที่ dm-user
  2. dm-user กำหนดเส้นทาง I/O ไปยังพื้นที่ผู้ใช้ snapuserd daemon ซึ่งจัดการคำขอ I/O
  3. เมื่อการดำเนินการผสานเสร็จสมบูรณ์ เฟรมเวิร์กจะยุบ dm-verity ที่ด้านบนของ dm-linear ( system_base ) และลบ dm-user ออก

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

รูปที่ 6 กระบวนการบีบอัด A/B เสมือน

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

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

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

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

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

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

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

ขนาดผลกระทบ ไม่ใช่ A/B เอ/บี A/B เสมือน A/B เสมือน (บีบอัด)
ภาพโรงงานดั้งเดิม 4.5GB ซุปเปอร์ (ภาพ 3.8G + สำรอง 700M) 9GB super (สงวน 3.8G + 700M สำหรับสองช่อง) 4.5GB ซุปเปอร์ (ภาพ 3.8G + สำรอง 700M) 4.5GB ซุปเปอร์ (ภาพ 3.8G + สำรอง 700M)
พาร์ติชันแบบคงที่อื่น ๆ /แคช ไม่มี ไม่มี ไม่มี
พื้นที่เก็บข้อมูลเพิ่มเติมในช่วง OTA (พื้นที่คืนหลังจากสมัคร OTA) 1.4GB บน /data 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