Chốt kiểm tra dữ liệu người dùng

Android 10 ra mắt Điểm kiểm tra dữ liệu người dùng (UDC), cho phép Android quay lại trạng thái trước đó khi bản cập nhật Android qua mạng không dây (OTA) không thành công. Với UDC, nếu bản cập nhật Android OTA không thành công, thiết bị có thể khôi phục về trạng thái trước đó một cách an toàn. Mặc dù Bản cập nhật A/B giải quyết sự cố này để khởi động sớm, khôi phục không được hỗ trợ khi phân vùng dữ liệu người dùng (được gắn trên /data) được sửa đổi.

UDC cho phép thiết bị khôi phục phân vùng dữ liệu người dùng ngay cả sau khi được sửa đổi. Tính năng UDC thực hiện điều này bằng cách sử dụng các chức năng điểm kiểm tra để hệ thống tệp, phương thức triển khai thay thế khi hệ thống tệp không hỗ trợ điểm kiểm tra, tích hợp với cơ chế A/B của trình tải khởi động đồng thời hỗ trợ các bản cập nhật không phải A/B và hỗ trợ liên kết phiên bản phím và khôi phục phím phòng ngừa.

Tác động đối với người dùng

Tính năng UDC cải thiện trải nghiệm cập nhật OTA cho người dùng vì ít người dùng bị mất dữ liệu hơn khi cập nhật OTA không thành công. Việc này có thể làm giảm số lượng cuộc gọi hỗ trợ từ những người dùng gặp sự cố trong quá trình cập nhật. Tuy nhiên, khi một OTA không cập nhật được, người dùng có thể nhận thấy thiết bị khởi động lại nhiều lần.

Cách hoạt động

Chức năng điểm kiểm tra trong nhiều hệ thống tệp

Đối với hệ thống tệp F2FS, UDC thêm chức năng điểm kiểm tra vào luồng ngược 4.20 Nhân Linux và điều chỉnh cho phiên bản cũ cho tất cả các nhân phổ biến mà thiết bị hỗ trợ chạy Android 10.

Đối với các hệ thống tệp khác, UDC sử dụng một thiết bị ảo của trình ánh xạ thiết bị có tên là dm_bow cho chức năng điểm kiểm tra. dm_bow nằm giữa thiết bị và hệ thống tệp. Khi phân vùng được gắn kết, quá trình cắt sẽ được phát hành, khiến hệ thống tệp đưa ra lệnh cắt trên tất cả các khối miễn phí. dm_bow sẽ chặn các phần cắt này và sử dụng chúng để thiết lập danh sách khối miễn phí. Sau đó, các lệnh đọc và ghi sẽ được gửi đến thiết bị mà không bị sửa đổi, nhưng trước khi cho phép ghi, dữ liệu cần thiết để khôi phục sẽ được sao lưu vào một khối trống.

Quy trình tại điểm kiểm tra

Khi một phân vùng có cờ checkpoint=fs/block được gắn, Android sẽ gọi restoreCheckpoint trên ổ đĩa để cho phép thiết bị khôi phục mọi điểm kiểm tra hiện tại. Sau đó, init sẽ gọi hàm needsCheckpoint để xác định xem thiết bị có ở trạng thái trình tải khởi động A/B hay đã đặt số lần thử lại cập nhật hay không. Nếu đúng, Android sẽ gọi createCheckpoint để thêm giá trị gắn kết gắn cờ hoặc tạo một thiết bị dm_bow.

Sau khi phân vùng được gắn, mã điểm kiểm tra sẽ được gọi để phát hành các phần cắt. Sau đó, quá trình khởi động sẽ tiếp tục như bình thường. Tại LOCKED_BOOT_COMPLETE, Android gọi commitCheckpoint để xác nhận điểm kiểm tra hiện tại và bản cập nhật sẽ tiếp tục như bình thường.

Quản lý khoá keymaster

Khoá Keymaster được dùng để mã hoá thiết bị hoặc cho các mục đích khác. Để quản lý các đề xuất này Android sẽ trì hoãn các lệnh gọi xoá phím cho đến khi điểm kiểm tra được cam kết.

Theo dõi tình trạng

Trình nền sức khoẻ xác minh rằng có đủ dung lượng ổ đĩa để tạo điểm kiểm tra. Trình nền sức khoẻ nằm trong cp_healthDaemon trong Checkpoint.cpp.

Bạn có thể định cấu hình các hành vi sau đây cho trình nền trạng thái:

  • ro.sys.cp_msleeptime: Kiểm soát tần suất thiết bị kiểm tra mức sử dụng ổ đĩa.
  • ro.sys.cp_min_free_bytes: Kiểm soát giá trị tối thiểu mà trình nền sức khoẻ tìm kiếm.
  • ro.sys.cp_commit_on_full: Kiểm soát việc trình nền sức khoẻ có khởi động lại thiết bị hay không hoặc xác nhận điểm kiểm tra này và tiếp tục khi ổ đĩa đầy.

API điểm kiểm tra

Tính năng UDC sử dụng các API của điểm kiểm tra. Đối với các API khác mà UDC sử dụng, hãy xem IVold.aidl.

void startCheckpoint(int retry)

Tạo một điểm kiểm tra.

Khung sẽ gọi phương thức này khi đã sẵn sàng bắt đầu cập nhật. Điểm kiểm tra được tạo trước khi các hệ thống tệp được kiểm tra điểm như userdata được gắn R/W sau khi khởi động lại. Nếu số lần thử lại là số dương, API sẽ xử lý việc theo dõi các lần thử lại và trình cập nhật sẽ gọi needsRollback để kiểm tra xem có cần khôi phục bản cập nhật hay không. Nếu số lần thử lại là -1, API sẽ trì hoãn quyết định của trình tải khởi động A/B.

Phương thức này không được gọi khi cập nhật A/B thông thường.

trống cam kếtChanges()

Xác nhận nội dung thay đổi.

Khung này gọi phương thức này sau khi khởi động lại khi các thay đổi đã sẵn sàng được thực hiện. Phương thức này được gọi trước khi dữ liệu (chẳng hạn như ảnh, video, tin nhắn SMS, biên nhận nhận của máy chủ) được ghi vào userdata và trước BootComplete.

Nếu không có bản cập nhật điểm kiểm tra đang hoạt động nào, thì phương thức này sẽ không có hiệu lực.

huỷ bỏ()

Buộc khởi động lại và quay lại điểm kiểm tra. Bỏ tất cả sửa đổi dữ liệu người dùng kể từ lần khởi động lại đầu tiên.

Khung này gọi phương thức này sau khi khởi động lại nhưng trước commitChanges. retry_counter giảm khi phương thức này được gọi. Các mục nhập nhật ký được tạo.

bool cầnRollback()

Xác định xem có bắt buộc khôi phục hay không.

Trên các thiết bị không có điểm kiểm tra, hàm sẽ trả về false. Trên các thiết bị điểm kiểm tra, trả về true trong quá trình khởi động không có điểm kiểm tra.

Triển khai UDC

Triển khai tham chiếu

Để biết ví dụ về cách triển khai UDC, hãy xem dm-bow.c. Để biết thêm tài liệu về tính năng này, hãy xem dm-bow.txt.

Thiết lập

Trong on fs trong tệp init.hardware.rc, hãy đảm bảo bạn có:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early

Trong on late-fs trong tệp init.hardware.rc, hãy đảm bảo bạn có:

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

Trong tệp fstab.hardware, hãy đảm bảo /data được gắn thẻ là latemount.

/dev/block/bootdevice/by-name/userdata              /data              f2fs
noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs

Thêm phân vùng siêu dữ liệu

UDC yêu cầu một phân vùng siêu dữ liệu để lưu trữ số lần thử lại và khoá không phải trình tải khởi động. Thiết lập một phân vùng siêu dữ liệu và gắn sớm phân vùng đó tại /metadata.

Trong tệp fstab.hardware, hãy đảm bảo /metadata được gắn thẻ là earlymount hoặc first_stage_mount.

/dev/block/by-name/metadata           /metadata           ext4
noatime,nosuid,nodev,discard,sync
wait,formattable,first_stage_mount

Khởi tạo phân vùng thành tất cả số 0.

Thêm các dòng sau vào BoardConfig.mk:

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Cập nhật hệ thống

Hệ thống F2FS

Đối với những hệ thống sử dụng F2FS để định dạng dữ liệu, hãy đảm bảo rằng bạn dùng phiên bản F2FS hỗ trợ điểm kiểm tra. Để biết thêm thông tin, hãy xem phần Chức năng điểm kiểm tra trong các hệ thống tệp khác nhau.

Thêm cờ checkpoint=fs vào phần <fs_mgr_flags> của fstab cho phần tử thiết bị được gắn lúc /data.

Các hệ thống không phải F2FS

Đối với các hệ thống không phải F2FS, bạn phải bật dm-bow trong cấu hình hạt nhân.

Thêm cờ checkpoint=block vào phần <fs_mgr_flags> của fstab cho thiết bị được gắn tại /data.

Kiểm tra nhật ký

Các mục nhập nhật ký được tạo khi các API Checkpoint được gọi.

Xác nhận kết quả

Để kiểm thử việc triển khai UDC, hãy chạy tập hợp các bài kiểm thử VTS VtsKernelCheckpointTest.