Android 12 תומך ב-FUSE passthrough, שמצמצם את התקורה של FUSE כדי להשיג ביצועים שדומים לגישה ישירה למערכת הקבצים התחתונה. העברת FUSE נתמכת בקרנלים android12-5.4
, android12-5.10
ו-android-mainline
(בדיקה בלבד), כלומר התמיכה בתכונה הזו תלויה בקרנל שבו המכשיר משתמש ובגרסת Android שפועלת במכשיר:
מכשירים שמשדרגים מ-Android 11 ל-Android 12 לא יכולים לתמוך ב-FUSE passthrough, כי ליבות המערכת של המכשירים האלה קפואות ואי אפשר להעביר אותן לליבה ששודרגה באופן רשמי עם השינויים של FUSE passthrough.
מכשירים שמופעלים עם Android 12 יכולים לתמוך ב-FUSE passthrough כשמשתמשים בליבה רשמית. במכשירים כאלה, קוד המסגרת של Android שמטמיע את FUSE passthrough מוטמע במודול הראשי MediaProvider, שעובר שדרוג אוטומטי. מכשירים שלא מטמיעים את MediaProvider כמודול ראשי (לדוגמה, מכשירי Android Go), יכולים גם לגשת לשינויים ב-MediaProvider כי הם משותפים באופן ציבורי.
FUSE לעומת SDCardFS
File system in Userspace (FUSE) הוא מנגנון שמאפשר לליבה (kernel) (מנהל ההתקן של FUSE) להעביר לתוכנה במרחב המשתמש (FUSE daemon) פעולות שמתבצעות במערכת קבצים של FUSE, והתוכנה הזו מבצעת את הפעולות. ב-Android 11, SDCardFS הוצא משימוש ו-FUSE הפך לפתרון ברירת המחדל לאמולציית אחסון. במסגרת השינוי הזה, מערכת Android הטמיעה דמון FUSE משלה כדי ליירט גישות לקבצים, לאכוף תכונות אבטחה ופרטיות נוספות ולשנות קבצים בזמן ריצה.
FUSE פועל היטב כשמדובר במידע שאפשר לשמור במטמון, כמו דפים או מאפיינים, אבל הוא גורם לירידה בביצועים כשניגשים לאחסון חיצוני, והירידה הזו בביצועים בולטת במיוחד במכשירים בינוניים ובמכשירים ברמת כניסה. הנסיגות האלה נגרמות כתוצאה משרשרת של רכיבים שפועלים יחד בהטמעה של מערכת הקבצים FUSE, וגם כתוצאה ממעברים רבים ממרחב הליבה למרחב המשתמש בתקשורת בין מנהל ההתקן FUSE לבין דמון FUSE (לעומת גישה ישירה למערכת הקבצים התחתונה שהיא רזה יותר ומוטמעת לחלוטין בליבה).
כדי לצמצם את הרגרסיות האלה, אפשר להשתמש בשילוב באפליקציות כדי לצמצם את העתקת הנתונים, ולהשתמש ב-ContentProvider API כדי לקבל גישה ישירה לקבצים נמוכים יותר במערכת הקבצים. גם עם האופטימיזציות האלה ואופטימיזציות אחרות, רוחב הפס של פעולות קריאה וכתיבה עשוי להיות נמוך יותר כשמשתמשים ב-FUSE בהשוואה לגישה ישירה למערכת הקבצים התחתונה – במיוחד בפעולות קריאה אקראיות, שבהן לא ניתן להשתמש במטמון או בקריאה מראש. אפליקציות שניגשות ישירות לאחסון דרך הנתיב מדור קודם /sdcard/
ממשיכות לחוות ירידות משמעותיות בביצועים, במיוחד כשמבצעים פעולות שדורשות הרבה קלט/פלט.
בקשות במרחב המשתמש של SDcardFS
שימוש ב-SDcardFS יכול להאיץ את האמולציה של האחסון ואת בדיקות ההרשאות של FUSE, כי הוא מסיר את הקריאה למרחב המשתמש מהליבה. בקשות במרחב המשתמשים עוברות בנתיב הבא: מרחב המשתמשים ← VFS ← sdcardfs ← VFS ← ext4 ← מטמון דפים/אחסון.
איור 1. בקשות במרחב המשתמש של SDcardFS
בקשות של מרחב משתמש FUSE
בתחילה, FUSE שימש להפעלת אמולציית אחסון ולאפשר לאפליקציות להשתמש באופן שקוף באחסון הפנימי או בכרטיס SD חיצוני. השימוש ב-FUSE מוסיף תקורה מסוימת, כי כל בקשה במרחב המשתמשים עוברת בנתיב הבא: מרחב המשתמשים ← VFS ← מנהל התקן של FUSE ← דמון של FUSE ← VFS ← ext4 ← מטמון דפים/אחסון.
איור 2. בקשות של מרחב משתמש FUSE
בקשות FUSE passthrough
רוב ההרשאות לגישה לקבצים נבדקות בזמן פתיחת הקובץ, ובדיקות הרשאות נוספות מתבצעות בזמן קריאה מהקובץ וכתיבה בו. במקרים מסוימים, אפשר לדעת בזמן פתיחת הקובץ שלאפליקציה ששולחת את הבקשה יש גישה מלאה לקובץ המבוקש, ולכן המערכת לא צריכה להמשיך להעביר את בקשות הקריאה והכתיבה ממנהל ההתקן של FUSE אל דמון FUSE (כי זה רק יעביר נתונים ממקום אחד למקום אחר).
באמצעות FUSE passthrough, דמון FUSE שמטפל בבקשת פתיחה יכול להודיע למנהל ההתקן של FUSE שהפעולה מותרת ושאפשר להעביר ישירות את כל בקשות הקריאה והכתיבה הבאות למערכת הקבצים התחתונה. כך נמנעים מהתקורה הנוספת של המתנה לתגובה של דמון FUSE במרחב המשתמש לבקשות של מנהל ההתקן FUSE.
בהמשך מוצגת השוואה בין בקשות FUSE לבין בקשות FUSE passthrough.
איור 3. בקשת FUSE לעומת בקשת FUSE passthrough
כשמבצעים גישה למערכת קבצים של FUSE דרך אפליקציה, מתבצעות הפעולות הבאות:
מנהל ההתקן של FUSE מטפל בבקשה ומכניס אותה לתור, ואז מציג אותה לדמון של FUSE שמטפל במערכת הקבצים של FUSE דרך מופע חיבור ספציפי בקובץ
/dev/fuse
, שהדמון של FUSE חסום מקריאה שלו.כשדמון FUSE מקבל בקשה לפתוח קובץ, הוא מחליט אם FUSE passthrough צריך להיות זמין לקובץ הספציפי הזה. אם הוא זמין, הדמון:
הודעה על הבקשה הזו נשלחת ל-FUSE driver.
ההגדרה הזו מאפשרת העברה של FUSE לקובץ באמצעות
FUSE_DEV_IOC_PASSTHROUGH_OPEN
ioctl, שצריך להתבצע בתיאור הקובץ של/dev/fuse
שנפתח.
ה-ioctl מקבל (כפרמטר) מבנה נתונים שמכיל את הפרטים הבאים:
מתאר קובץ של קובץ במערכת הקבצים התחתונה, שמוגדר כיעד לתכונת ההעברה.
מזהה ייחודי של בקשת FUSE שמטופלת כרגע (צריך להיות פתוח או ליצור ולפתוח).
שדות נוספים שאפשר להשאיר ריקים ומיועדים להטמעה עתידית.
אם הפקודה ioctl מצליחה, דמון FUSE משלים את בקשת הפתיחה, מנהל ההתקן של FUSE מטפל בתשובה של דמון FUSE, והפניה לקובץ במערכת הקבצים התחתונה מתווספת לקובץ FUSE בתוך ליבת המערכת. כשאפליקציה מבקשת פעולת קריאה או כתיבה בקובץ FUSE, מנהל ההתקן של FUSE בודק אם ההפניה לקובץ במערכת קבצים נמוכה יותר זמינה.
אם יש הפניה זמינה, מנהל ההתקן יוצר בקשה חדשה של מערכת קבצים וירטואלית (VFS) עם אותם פרמטרים שמכוונת לקובץ של מערכת הקבצים התחתונה.
אם אין הפניה זמינה, הנהג מעביר את הבקשה לדמון FUSE.
הפעולות שלמעלה מתרחשות בקריאה/כתיבה ובקריאה-איטרציה/כתיבה-איטרציה בקבצים גנריים, ובפעולות קריאה/כתיבה בקבצים עם מיפוי זיכרון. העברת FUSE לקובץ מסוים קיימת עד שהקובץ נסגר.
הטמעה של העברת FUSE
כדי להפעיל העברה של FUSE במכשירים עם Android 12, מוסיפים את השורות הבאות לקובץ $ANDROID_BUILD_TOP/device/…/device.mk
של מכשיר היעד.
# Use FUSE passthrough
PRODUCT_PRODUCT_PROPERTIES += \
persist.sys.fuse.passthrough.enable=true
כדי להשבית את העברת הנתונים של FUSE, משמיטים את שינוי ההגדרה שלמעלה או מגדירים את persist.sys.fuse.passthrough.enable
ל-false
. אם הפעלתם בעבר את FUSE passthrough, השבתתו תמנע מהמכשיר להשתמש ב-FUSE passthrough, אבל המכשיר ימשיך לפעול.
כדי להפעיל או להשבית את FUSE passthrough בלי להפעיל את המכשיר, משנים את מאפיין המערכת באמצעות פקודות ADB. דוגמה:
adb root
adb shell setprop persist.sys.fuse.passthrough.enable {true,false}
adb reboot
לקבלת עזרה נוספת, אפשר לעיין בהטמעה לדוגמה.
אימות של העברת FUSE
כדי לוודא ש-MediaProvider משתמש ב-FUSE passthrough, בודקים את logcat
כדי לראות הודעות ניפוי באגים. לדוגמה:
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
ביומן מוודא שנעשה שימוש ב-FUSE passthrough.
Android 12 CTS כולל את CtsStorageTest
, שכולל בדיקות שמפעילות העברה של FUSE. כדי להריץ את הבדיקה באופן ידני, משתמשים בפקודה atest כמו בדוגמה הבאה:
atest CtsStorageTest