Tổng quan về A/B ảo

A/B ảo là cơ chế cập nhật chính của Android. A/B ảo được xây dựng dựa trên các bản cập nhật A/B cũ (xem phần Bản cập nhật hệ thống A/B) và không phải A/B (không dùng nữa trong phiên bản 15) để giảm mức sử dụng bộ nhớ của các bản cập nhật.

Phân vùng ảo A/B không có thêm một khe cắm cho phân vùng động, hãy xem phân vùng động. Thay vào đó, delta được ghi vào một bản chụp nhanh, sau đó hợp nhất vào phân vùng cơ sở sau khi xác nhận khởi động thành công. Thử nghiệm A/B ảo sử dụng một định dạng ảnh chụp nhanh dành riêng cho Android. Hãy xem định dạng COW cho ảnh chụp nhanh nén. Định dạng này cho phép nén ảnh chụp nhanh và giảm thiểu mức sử dụng dung lượng ổ đĩa. Trên OTA đầy đủ, kích thước của ảnh chụp nhanh giảm khoảng 45% khi nén và kích thước của ảnh chụp nhanh OTA gia tăng giảm khoảng 55%.

Android 12 cung cấp lựa chọn nén A/B ảo để nén các phân vùng được chụp nhanh. Thử nghiệm A/B ảo cung cấp những thông tin sau

  • Bản cập nhật A/B ảo diễn ra liền mạch (quá trình cập nhật diễn ra hoàn toàn ở chế độ nền trong khi thiết bị đang hoạt động) giống như bản cập nhật A/B. Bản cập nhật A/B ảo giúp giảm thiểu thời gian thiết bị không kết nối mạng và không sử dụng được.
  • Bạn có thể quay lại các bản cập nhật A/B ảo. Nếu không khởi động được hệ điều hành mới, thiết bị sẽ tự động quay về phiên bản trước đó.
  • Các bản cập nhật A/B ảo sử dụng không gian bổ sung tối thiểu bằng cách chỉ sao chép những phân vùng mà trình tải khởi động sử dụng. Các phân vùng có thể cập nhật khác được tạo bản sao nhanh.

Thông tin khái quát và thuật ngữ

Phần này định nghĩa thuật ngữ và mô tả công nghệ hỗ trợ thử nghiệm A/B ảo. Trong quá trình cài đặt OTA, dữ liệu hệ điều hành mới sẽ được ghi vào khe cắm mới cho các phân vùng thực hoặc một thiết bị COW dành riêng cho Android. Sau khi thiết bị khởi động lại, dữ liệu phân vùng động sẽ được hợp nhất trở lại thiết bị cơ sở thông qua việc sử dụng trình nền dm-user và snapuserd. Quá trình này diễn ra hoàn toàn trong không gian người dùng.

Device-mapper

Device-mapper là một lớp khối ảo Linux thường được dùng trong Android. Với phân vùng động, các phân vùng như /system là một ngăn xếp các thiết bị theo lớp:

  • Ở dưới cùng của ngăn xếp là phân vùng siêu vật lý (ví dụ: /dev/block/by-name/super).
  • Ở giữa là thiết bị dm-linear, chỉ định những khối trong siêu phân vùng tạo thành phân vùng động đã cho. Thư mục này xuất hiện dưới dạng /dev/block/mapper/system_[a|b] trên thiết bị A/B hoặc /dev/block/mapper/system trên thiết bị không phải A/B.
  • Ở trên cùng là thiết bị dm-verity, được tạo cho các phân vùng đã xác minh. Thiết bị này xác minh rằng các khối trên thiết bị dm-linear được ký đúng cách. Thư mục này xuất hiện dưới dạng /dev/block/mapper/system-verity và là nguồn của điểm gắn /system.

Hình 1 minh hoạ ngăn xếp trong điểm gắn /system.

Phân vùng xếp chồng bên dưới hệ thống

Hình 1. Ngăn xếp trong điểm gắn /system

Ảnh chụp nhanh đã nén

Trong Android 12 trở lên, vì yêu cầu về không gian trên phân vùng /data có thể cao, nên bạn có thể bật các ảnh chụp nhanh được nén trong bản dựng để đáp ứng yêu cầu cao hơn về không gian của phân vùng /data.

Ảnh chụp nhanh nén A/B ảo được xây dựng dựa trên các thành phần sau đây có trong Android 12 trở lên:

  • dm-user, một mô-đun nhân tương tự như FUSE, cho phép không gian người dùng triển khai các thiết bị khối.
  • snapuserd, một trình nền không gian người dùng để triển khai định dạng ảnh chụp nhanh mới.

Các thành phần này cho phép nén. Những thay đổi cần thiết khác được thực hiện để triển khai các chức năng ảnh chụp nhanh nén được trình bày trong các phần tiếp theo: Định dạng COW cho ảnh chụp nhanh nén, dm-usersnapuserd.

Định dạng COW cho ảnh chụp nhanh nén

Trong Android 12 trở lên, ảnh chụp nhanh nén sử dụng định dạng COW dành riêng cho Android. Định dạng COW chứa siêu dữ liệu về OTA và có các vùng đệm riêng biệt chứa các thao tác COW và dữ liệu hệ điều hành mới. So với định dạng ảnh chụp nhanh của nhân chỉ cho phép các thao tác thay thế (Thay thế khối X trong hình ảnh cơ sở bằng nội dung của khối Y trong ảnh chụp nhanh), định dạng COW ảnh chụp nhanh nén của Android có tính biểu đạt cao hơn và hỗ trợ các thao tác sau:

  • Sao chép: Khối X trong thiết bị cơ sở phải được thay thế bằng khối Y trong thiết bị cơ sở.
  • Thay thế: Khối X trong thiết bị cơ sở cần được thay thế bằng nội dung của khối Y trong ảnh chụp nhanh. Mỗi khối này đều được nén bằng gz.
  • Zero: Khối X trong thiết bị cơ sở phải được thay thế bằng tất cả các số 0.
  • XOR: Thiết bị COW lưu trữ các byte được nén XOR giữa khối X và khối Y. (Có trong Android 13 trở lên.)

Bản cập nhật OTA đầy đủ chỉ bao gồm các thao tác thay thếzero. Các bản cập nhật OTA gia tăng cũng có thể có các thao tác sao chép.

Bố cục ảnh chụp nhanh đầy đủ trên đĩa có dạng như sau:

định dạng cow

Hình 2. Định dạng COW của Android trên ổ đĩa

dm-user

Mô-đun nhân dm-user cho phép userspace triển khai các thiết bị chặn device-mapper. Một mục trong bảng dm-user sẽ tạo ra một thiết bị khác trong /dev/dm-user/<control-name>. Quy trình userspace có thể thăm dò thiết bị để nhận các yêu cầu đọc và ghi từ nhân. Mỗi yêu cầu đều có một vùng đệm liên kết để không gian người dùng điền (để đọc) hoặc truyền (để ghi).

Mô-đun hạt nhân dm-user cung cấp một giao diện mới mà người dùng có thể thấy cho hạt nhân, không thuộc cơ sở mã nguồn upstream kernel.org. Cho đến khi đó, Google giữ quyền sửa đổi giao diện dm-user trên Android.

snapuserd

Thành phần snapuserd userspace đến dm-user triển khai tính năng nén A/B ảo. Snapuserd là một trình nền không gian người dùng chịu trách nhiệm ghi và đọc các thiết bị COW của Android. Tất cả hoạt động I/O đến ảnh chụp nhanh đều phải thông qua dịch vụ này. Trong quá trình cài đặt OTA, dữ liệu hệ điều hành mới sẽ được snapuserd ghi vào bản chụp nhanh (có nén). Quá trình phân tích cú pháp siêu dữ liệu và giải nén dữ liệu khối mới cũng được xử lý tại đây.

Nén XOR

Đối với các thiết bị chạy Android 13 trở lên, tính năng nén XOR (được bật theo mặc định) cho phép các ảnh chụp nhanh không gian người dùng lưu trữ các byte được nén XOR giữa các khối cũ và khối mới. Khi chỉ một vài byte trong một khối được thay đổi trong bản cập nhật A/B ảo, lược đồ lưu trữ nén XOR sẽ sử dụng ít dung lượng hơn lược đồ lưu trữ mặc định vì các ảnh chụp nhanh không lưu trữ đầy đủ 4K byte. Có thể giảm kích thước của ảnh chụp nhanh vì dữ liệu XOR chứa nhiều số 0 và dễ nén hơn dữ liệu khối thô. Trên các thiết bị Pixel, tính năng nén XOR giúp giảm kích thước ảnh chụp nhanh từ 25% đến 40%.

Đối với các thiết bị nâng cấp lên Android 13 trở lên, bạn phải bật tính năng nén XOR. Để biết thông tin chi tiết, hãy xem phần Nén XOR.

Hợp nhất ảnh chụp nhanh

Đối với các thiết bị chạy Android 13 trở lên, các quy trình hợp nhất và chụp nhanh trong quá trình nén A/B ảo sẽ được thực hiện bằng thành phần không gian người dùng snapuserd. Đối với các thiết bị nâng cấp lên Android 13 trở lên, bạn phải bật tính năng này. Để biết thông tin chi tiết, hãy xem phần Hợp nhất không gian người dùng.

Sau đây là quy trình nén A/B ảo:

  1. Khung này gắn phân vùng /system trên thiết bị dm-verity, được xếp chồng lên trên thiết bị dm-user. Điều này có nghĩa là mọi hoạt động đầu vào/đầu ra từ hệ thống tệp gốc đều được chuyển đến dm-user.
  2. dm-user định tuyến I/O đến trình nền snapuserd của không gian người dùng, trình nền này xử lý yêu cầu I/O.
  3. Khi thao tác hợp nhất hoàn tất, khung sẽ thu gọn dm-verity ở trên cùng của dm-linear (system_base) và xoá dm-user.

Quy trình nén A/B ảo

Hình 3. Quy trình nén A/B ảo

Quá trình hợp nhất ảnh chụp nhanh có thể bị gián đoạn. Nếu thiết bị khởi động lại trong quá trình hợp nhất, thì quá trình hợp nhất sẽ tiếp tục sau khi khởi động lại.

Chuyển đổi khi khởi động

Khi khởi động bằng ảnh chụp nhanh đã nén, quy trình khởi động giai đoạn đầu phải bắt đầu snapuserd để gắn các phân vùng. Điều này gây ra một vấn đề: Khi sepolicy được tải và thực thi, snapuserd sẽ được đặt trong ngữ cảnh không chính xác và các yêu cầu đọc của nó sẽ không thành công, với các lệnh từ chối selinux.

Để giải quyết vấn đề này, snapuserd sẽ chuyển đổi đồng thời với init, như sau:

  1. Giai đoạn đầu tiên init khởi chạy snapuserd từ ramdisk và lưu một tệp mô tả mở vào đó trong một biến môi trường.
  2. init giai đoạn đầu chuyển hệ thống tệp gốc sang phân vùng hệ thống, sau đó thực thi bản sao hệ thống của init.
  3. Bản sao hệ thống của init sẽ đọc sepolicy kết hợp thành một chuỗi.
  4. Init sẽ gọi mlock() trên tất cả các trang được hỗ trợ bởi ext4. Sau đó, nó sẽ huỷ kích hoạt tất cả các bảng device-mapper cho thiết bị chụp nhanh và dừng snapuserd. Sau bước này, bạn không được phép đọc từ các phân vùng vì việc này sẽ gây ra tình trạng bế tắc.
  5. Sử dụng bộ mô tả mở cho bản sao ramdisk của snapuserd, init sẽ khởi động lại trình nền với ngữ cảnh selinux chính xác. Các bảng device-mapper cho thiết bị chụp nhanh sẽ được kích hoạt lại.
  6. Init gọi munlockall() – bạn có thể thực hiện lại IO một cách an toàn.

Mức sử dụng bộ nhớ

Bảng sau đây so sánh mức sử dụng dung lượng cho các cơ chế OTA khác nhau bằng cách sử dụng kích thước hệ điều hành và OTA của Pixel.

Mức tác động đến kích thước không phải A/B A/B Thử nghiệm A/B ảo Thử nghiệm A/B ảo (được nén)
Hình ảnh gốc của nhà máy 4,5 GB siêu lớn (ảnh 3,8 GB + 700 MB dành riêng)1 9 GB siêu lớn (3, 8 GB + 700 MB dành riêng cho 2 khe cắm) 4,5 GB siêu lớn (ảnh 3,8 GB + 700 MB dành riêng) 4,5 GB siêu lớn (ảnh 3,8 GB + 700 MB dành riêng)
Các phân vùng tĩnh khác /cache Không có Không có Không có
Bộ nhớ bổ sung trong quá trình cập nhật qua mạng (OTA) (dung lượng được trả lại sau khi áp dụng OTA) 1,4 GB trên /data 0 3,8 GB2 trên /data 2,1 GB2 trên /data
Tổng bộ nhớ cần thiết để áp dụng OTA 5,9 GB3 (siêu dữ liệu và dữ liệu) 9 GB (siêu lớn) 8,3 GB3 (siêu dữ liệu và dữ liệu) 6,6 GB3 (siêu và dữ liệu)

1Cho biết bố cục giả định dựa trên việc liên kết Pixel.

2Giả định rằng hình ảnh hệ thống mới có cùng kích thước với hình ảnh gốc.

3Yêu cầu về dung lượng trống chỉ là tạm thời cho đến khi khởi động lại.

Android 11 Virtual A/B

Android 11 của Virtual A/B đã ghi vào phân vùng động bằng cách sử dụng định dạng COW của Kernel. Định dạng này cuối cùng đã bị ngừng sử dụng vì định dạng COW của Kernel không hỗ trợ tính năng nén.

Android 12 Virtual A/B

Trong Android 12, hoạt động nén được hỗ trợ dưới dạng định dạng COW dành riêng cho Android. Phiên bản Virtual A/B này yêu cầu dịch COW dành riêng cho Android sang định dạng COW của Kernel. Cuối cùng, phương thức này đã được thay thế trong Android 13. Android 13 đã loại bỏ sự phụ thuộc vào định dạng COW của Kernel và cả dm-snapshot.

Để triển khai Virtual A/B hoặc sử dụng các chức năng chụp nhanh nén, hãy xem phần Triển khai Virtual A/B