cầu chì thông qua

Android 12 hỗ trợ tính năng truyền qua FUSE, giúp giảm thiểu chi phí sử dụng FUSE để đạt được hiệu suất tương đương với khả năng truy cập trực tiếp vào hệ thống tệp thấp hơn. Truyền qua FUSE được hỗ trợ trong hạt nhân android12-5.4 , android12-5.10android-mainline (chỉ dành cho thử nghiệm), điều đó có nghĩa là việc hỗ trợ cho tính năng này phụ thuộc vào hạt nhân được thiết bị sử dụng và phiên bản Android mà thiết bị đang chạy:

  • Các thiết bị nâng cấp từ Android 11 lên Android 12 không thể hỗ trợ chuyển qua FUSE vì hạt nhân của các thiết bị này bị đóng băng và chúng không thể chuyển sang hạt nhân đã được nâng cấp chính thức với các thay đổi về chuyển qua FUSE.

  • Các thiết bị chạy Android 12 có thể hỗ trợ chuyển FUSE khi sử dụng kernel chính thức. Đối với các thiết bị như vậy, mã khung Android triển khai tính năng truyền qua FUSE được nhúng trong mô-đun dòng chính MediaProvider và được nâng cấp tự động. Các thiết bị không triển khai MediaProvider làm mô-đun chính (ví dụ: thiết bị Android Go) cũng có thể truy cập các thay đổi của MediaProvider khi chúng được chia sẻ công khai.

FUSE so với SDCardFS

Hệ thống tệp trong Không gian người dùng (FUSE) là một cơ chế cho phép các hoạt động được thực hiện trên hệ thống tệp FUSE được kernel (trình điều khiển FUSE) gia công cho chương trình không gian người dùng (FUSE daemon), chương trình này thực hiện các hoạt động. Android 11 đã ngừng sử dụng SDCardFS và đặt FUSE làm giải pháp mặc định để mô phỏng bộ nhớ. Là một phần của thay đổi này, Android đã triển khai trình nền FUSE của riêng mình để chặn quyền truy cập tệp, thực thi các tính năng bảo mật và quyền riêng tư bổ sung cũng như thao tác các tệp trong thời gian chạy.

Mặc dù FUSE hoạt động tốt khi xử lý thông tin có thể lưu trong bộ nhớ đệm như trang hoặc thuộc tính, nhưng nó gây ra hiện tượng hồi quy hiệu suất khi truy cập bộ nhớ ngoài, đặc biệt dễ thấy ở các thiết bị cấp trung và cấp thấp. Những sự hồi quy này là do một chuỗi các thành phần hợp tác trong việc triển khai hệ thống tệp FUSE, cũng như nhiều chuyển đổi từ không gian hạt nhân sang không gian người dùng trong giao tiếp giữa trình điều khiển FUSE và daemon FUSE (so với truy cập trực tiếp vào tệp thấp hơn). hệ thống gọn gàng hơn và được triển khai hoàn toàn trong kernel).

Để giảm thiểu những hiện tượng hồi quy này, các ứng dụng có thể sử dụng tính năng ghép nối để giảm việc sao chép dữ liệu và sử dụng API ContentProvider để có quyền truy cập trực tiếp vào các tệp hệ thống tệp thấp hơn. Ngay cả với những tối ưu hóa này và các tối ưu hóa khác , các hoạt động đọc và ghi có thể bị giảm băng thông khi sử dụng FUSE khi so sánh với truy cập trực tiếp vào hệ thống tệp thấp hơn — đặc biệt là với các hoạt động đọc ngẫu nhiên, trong đó không có bộ nhớ đệm hoặc đọc trước nào có thể trợ giúp. Và các ứng dụng truy cập trực tiếp vào bộ nhớ thông qua đường dẫn /sdcard/ cũ tiếp tục bị giảm hiệu suất rõ rệt, đặc biệt là khi thực hiện các thao tác đòi hỏi nhiều IO.

Yêu cầu không gian người dùng SDcardFS

Việc sử dụng SDcardFS có thể tăng tốc quá trình mô phỏng lưu trữ và kiểm tra quyền của FUSE bằng cách xóa lệnh gọi không gian người dùng khỏi kernel. Yêu cầu không gian người dùng đi theo đường dẫn: Không gian người dùng → VFS → sdcardfs → VFS → ext4 → Bộ đệm trang/Bộ lưu trữ.

FUSE Passthrough SDcardFS

Hình 1. Yêu cầu không gian người dùng SDcardFS

Yêu cầu không gian người dùng FUSE

FUSE ban đầu được sử dụng để kích hoạt mô phỏng bộ nhớ và cho phép các ứng dụng sử dụng bộ nhớ trong hoặc thẻ sdcard bên ngoài một cách minh bạch. Việc sử dụng FUSE sẽ gây ra một số chi phí vì mỗi yêu cầu không gian người dùng đều tuân theo đường dẫn: Không gian người dùng → VFS → trình điều khiển FUSE → daemon FUSE → VFS → ext4 → Bộ đệm trang/Bộ lưu trữ.

FUSE Truyền qua FUSE

Hình 2. Yêu cầu không gian người dùng FUSE

Yêu cầu chuyển qua FUSE

Hầu hết các quyền truy cập tệp đều được kiểm tra tại thời điểm mở tệp, với các kiểm tra quyền bổ sung xảy ra khi đọc và ghi vào tệp đó. Trong một số trường hợp, có thể biết tại thời điểm mở tệp rằng ứng dụng yêu cầu có toàn quyền truy cập vào tệp được yêu cầu, do đó hệ thống không cần tiếp tục chuyển tiếp các yêu cầu đọc và ghi từ trình điều khiển FUSE tới daemon FUSE (vì điều đó sẽ chỉ di chuyển dữ liệu từ nơi này sang nơi khác).

Với tính năng truyền qua FUSE, trình nền FUSE xử lý yêu cầu mở có thể thông báo cho trình điều khiển FUSE rằng thao tác đó được cho phép và tất cả các yêu cầu đọc và ghi tiếp theo có thể được chuyển tiếp trực tiếp đến hệ thống tệp thấp hơn. Điều này tránh được chi phí bổ sung khi chờ đợi daemon FUSE của không gian người dùng trả lời các yêu cầu của trình điều khiển FUSE.

Dưới đây là so sánh các yêu cầu chuyển qua FUSE và FUSE.

So sánh thông qua cầu chì

Hình 3. Yêu cầu FUSE so với yêu cầu chuyển qua FUSE

Khi một ứng dụng thực hiện quyền truy cập hệ thống tệp FUSE, các thao tác sau sẽ xảy ra:

  1. Trình điều khiển FUSE xử lý và xếp hàng yêu cầu, sau đó trình bày yêu cầu đó đến trình nền FUSE xử lý hệ thống tệp FUSE đó thông qua một phiên bản kết nối cụ thể trên tệp /dev/fuse mà trình nền FUSE bị chặn đọc.

  2. Khi trình nền FUSE nhận được yêu cầu mở một tệp, nó sẽ quyết định xem liệu có sẵn thông qua FUSE cho tệp cụ thể đó hay không. Nếu nó có sẵn, daemon:

    1. Thông báo cho trình điều khiển FUSE về yêu cầu này.

    2. Cho phép truyền qua FUSE cho tệp bằng cách sử dụng FUSE_DEV_IOC_PASSTHROUGH_OPEN ioctl, thao tác này phải được thực hiện trên bộ mô tả tệp của /dev/fuse đã mở.

  3. Ioctl nhận (dưới dạng tham số) cấu trúc dữ liệu có chứa các mục sau:

    • Bộ mô tả tệp của tệp hệ thống tệp thấp hơn là mục tiêu cho tính năng chuyển qua.

    • Mã định danh duy nhất của yêu cầu FUSE hiện đang được xử lý (phải mở hoặc tạo và mở).

    • Các trường bổ sung có thể để trống và dùng để triển khai trong tương lai.

  4. Nếu ioctl thành công, daemon FUSE sẽ hoàn thành yêu cầu mở, trình điều khiển FUSE xử lý phản hồi daemon FUSE và tham chiếu đến tệp hệ thống tệp thấp hơn sẽ được thêm vào tệp FUSE trong kernel. Khi một ứng dụng yêu cầu thao tác đọc/ghi trên tệp FUSE, trình điều khiển FUSE sẽ kiểm tra xem có tham chiếu đến tệp hệ thống tệp thấp hơn hay không.

    • Nếu có sẵn tham chiếu, trình điều khiển sẽ tạo một yêu cầu Hệ thống tệp ảo (VFS) mới với cùng tham số nhắm mục tiêu tệp hệ thống tệp thấp hơn.

    • Nếu không có tham chiếu, trình điều khiển sẽ chuyển tiếp yêu cầu tới trình nền FUSE.

Các thao tác trên xảy ra đối với các thao tác đọc/ghi và đọc/ghi trên các tệp chung và các thao tác đọc/ghi trên các tệp được ánh xạ bộ nhớ. Thông qua FUSE cho một tệp nhất định tồn tại cho đến khi tệp đó được đóng.

Triển khai thông qua FUSE

Để bật tính năng truyền qua FUSE trên các thiết bị chạy Android 12, hãy thêm các dòng sau vào tệp $ANDROID_BUILD_TOP/device/…/device.mk của thiết bị mục tiêu.

# Use FUSE passthrough
PRODUCT_PRODUCT_PROPERTIES += \
    persist.sys.fuse.passthrough.enable=true

Để tắt tính năng truyền qua FUSE, hãy bỏ qua thay đổi cấu hình ở trên hoặc đặt persist.sys.fuse.passthrough.enable thành false . Nếu trước đó bạn đã bật tính năng truyền qua FUSE, việc tắt tính năng này sẽ ngăn thiết bị sử dụng tính năng truyền qua FUSE nhưng thiết bị vẫn hoạt động.

Để bật/tắt tính năng truyền qua FUSE mà không cần flash thiết bị, hãy thay đổi thuộc tính hệ thống bằng lệnh ADB. Một ví dụ đã được biểu diễn ở dưới.

adb root
adb shell setprop persist.sys.fuse.passthrough.enable {true,false}
adb reboot

Để được trợ giúp thêm, hãy tham khảo cách triển khai tham khảo .

Xác thực thông qua FUSE

Để xác thực rằng MediaProvider đang sử dụng tính năng truyền qua FUSE, hãy kiểm tra logcat để biết thông báo gỡ lỗi. Ví dụ:

adb logcat FuseDaemon:V \*:S
--------- beginning of main
03-02 12:09:57.833  3499  3773 I FuseDaemon: Using FUSE passthrough
03-02 12:09:57.833  3499  3773 I FuseDaemon: Starting fuse...

FuseDaemon: Using FUSE passthrough trong nhật ký sẽ đảm bảo rằng chuyển tiếp FUSE đang được sử dụng.

Android 12 CTS bao gồm CtsStorageTest , bao gồm các thử nghiệm kích hoạt chuyển qua FUSE. Để chạy thử nghiệm theo cách thủ công, hãy sử dụng atest như dưới đây:

atest CtsStorageTest