Điểm 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 OTA của Android không thành công, thiết bị có thể rollback một cách an toàn về trạng thái trước đó. Mặc dù các bản cập nhật A/B giải quyết vấn đề này đối với quá trình khởi động sớm, nhưng tính năng 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) bị 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ác chức năng điểm kiểm tra cho hệ thống tệp, một cách 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ập nhật không phải A/B và hỗ trợ liên kết phiên bản phím và ngăn chặn thao tác khôi phục phím.

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. Điều 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 vấn đề trong quá trình cập nhật. Tuy nhiên, khi bản cập nhật OTA không thành công, 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 các hệ thống tệp khác nhau

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

Đố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 một phân vùng được gắn, một lệnh cắt sẽ được đưa ra khiến hệ thống tệp phát lệnh cắt trên tất cả các khối trống. 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 đó, hoạt động đọ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 miễn phí.

Quy trình 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 một trong hai giá trị này là true, Android sẽ gọi createCheckpoint để thêm cờ gắn hoặc tạo 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à quá trình 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 các mục đích khác. Để quản lý các khoá này, Android sẽ trì hoãn các lệnh gọi xoá khoá cho đến khi điểm kiểm tra được xác nhận.

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ẻ sẽ khởi động lại thiết bị hay xác nhận điểm kiểm tra 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 điểm kiểm tra. Đối với các API khác mà UDC sử dụng, hãy xem IVold.aidl.

khoảng trống startCheckpoint(số lần thử lại int)

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 thực hiện cập nhật A/B thông thường.

void commitChanges()

Xác nhận các 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 nào được đánh dấu kiểm tra đang hoạt động, 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ả nội dung sửa đổi userdata 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ó cần khôi phục hay không.

Trên các thiết bị không có điểm kiểm tra, 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 các hệ thống sử dụng F2FS để định dạng dữ liệu, hãy đảm bảo rằng phiên bản F2FS của bạn hỗ trợ các đ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 thiết bị được gắn tại /data.

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ý

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 kiểm thử VTS VtsKernelCheckpointTest.