/storage/emulated/0/
ถูก/data/media/0/
เปิดเผยผ่านระบบไฟล์จำลอง / เสมือนไม่ใช่ระบบจริง
นี่คือการอ้างอิงถึงคำตอบก่อนหน้าของฉันที่นี่แต่มีรายละเอียดที่เกี่ยวข้องมากขึ้น
เก็บหุ่นยนต์:
บนAndroid 5 :
/sdcard >S> /storage/emulated/legacy >S> /mnt/shell/emulated/0
/mnt/shell/emulated >E> /data/media
บนAndroid 6+ :
# for (Java) Android apps (running inside zygote virtual machine)
# "/storage to VIEW" bind mount is inside a separate mount namespace for every app
/sdcard >S> /storage/self/primary
/storage/self >B> /mnt/user/USER-ID
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/VIEW/emulated
/mnt/runtime/VIEW/emulated >E> /data/media
# for services/daemons/processes in root/global namespace (VIEW = default)
/sdcard >S> /storage/self/primary
/storage >B> /mnt/runtime/default
/mnt/runtime/default/self/primary >S> /mnt/user/USER-ID/primary
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/default/emulated
/mnt/runtime/default/emulated >E> /data/media
* >S>
สำหรับ symlink, >E>
สำหรับเทิดทูนและ>B>
สำหรับผูกติด
* USER-ID
ของผู้ใช้ปัจจุบันในกรณีของMultiple Users
หรือWork Profile
ตามปกติ0
เช่นว่าเจ้าของอุปกรณ์
* VIEW
เป็นหนึ่งread
(สำหรับแอปกับ permission.READ_EXTERNAL_STORAGE) หรือwrite
(permission.WRITE_EXTERNAL_STORAGE) หรือdefault
(สำหรับกระบวนการทำงานในราก / โกลบอลเมานต์เนมสเปซเช่นนอก zygote)
* มีความแตกต่างเล็กน้อยในเวอร์ชั่น Android ก่อนหน้านี้ แต่แนวคิดของการจำลองเหมือนเดิมนับตั้งแต่มีการใช้งาน
* สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการติดตั้งเนมสเปซของ Android โปรดดูคำตอบนี้
ในระยะสั้น/sdcard
และ/storage/emulated/0
- ซึ่งเป็นตัวแทนของระบบไฟล์ FAT / vFAT / FAT32 ชี้ไปที่/data/media/0
(หรือ/mnt/expand/[UUID]/media/0
ในกรณีของAdoptable Storage ) ผ่านFUSE
หรือsdcardfs
จำลอง
ไม่ใช่เฉพาะ Android แต่โดยทั่วไปเกี่ยวข้องกับ Linux, symlinkและbind mount (ดู "การสร้างการเชื่อมต่อ bind") อยู่นอกขอบเขตของคำถามนี้เนื่องจากคำถามส่วนใหญ่เกี่ยวกับการเลียนแบบ
EMULATION:
ทำไมการจำลองอยู่ที่นี่ ระบบไฟล์ที่จำลองเป็นเลเยอร์นามธรรมในระบบไฟล์จริง ( ext4
หรือf2fs
) ที่ทำหน้าที่สองวัตถุประสงค์โดยทั่วไป:
- รักษาการเชื่อมต่อ USB ของอุปกรณ์ Android กับพีซี (ใช้งานผ่าน MTP ได้แล้ววันนี้)
- จำกัด การเข้าถึงแอพ / กระบวนการโดยไม่ได้รับอนุญาตไปยังข้อมูลส่วนตัวของผู้ใช้และแอพอื่น ๆ ของการ์ด SD
อ่านStorage Journey ของ Androidเพื่อดูรายละเอียดสรุปคือ:
อุปกรณ์ Android รุ่นแรกนั้นสั้นเกี่ยวกับที่เก็บข้อมูลภายในและใช้การ์ด SD ภายนอก (ที่มีอยู่จริง) ที่ใช้ระบบไฟล์ตระกูล FAT เพื่อให้แน่ใจว่าสามารถใช้งานร่วมกับพีซีส่วนใหญ่ได้
เมื่อที่จัดเก็บข้อมูลมีขนาดใหญ่ขึ้นระบบไฟล์เดียวกันก็เปลี่ยนเป็นการ์ด SD ภายใน (ยังคงเรียกว่า "ภายนอก")
แต่การนำ FAT / vFAT ไปใช้นั้นมีสองประเด็นหลักที่ Google ได้รับการแก้ไข:
- อุปกรณ์ Android เชื่อมต่อกับพีซีโดยตรง ( USB Mass Storage ) เช่นเดียวกับที่เราเชื่อมต่อไดรฟ์ USB ในปัจจุบัน UMS ทำให้อุปกรณ์อยู่ในระดับบล็อกและตัดการเชื่อมต่อการ์ด SD จากกรอบงาน Android (ยกเลิกการติดตั้ง) ทำให้ข้อมูลทั้งหมดไม่สามารถใช้งานกับแอพและอาจทำลายฟังก์ชั่นมากมาย
- FAT (เป็นที่ชื่นชอบของ Windows ในวันที่พัฒนา) ไม่เคยถูกออกแบบมาเพื่อบังคับใช้สิทธิ์ UNIX (โหมด uid, gid และsymlinkเหมือนกันและอื่น
ioctls
ๆFS_IOC_FIEMAP
) ดังนั้นข้อมูลทั้งหมดในการ์ด SD จึงสามารถใช้งานได้กับทุกแอป (เนื่องจากแอพ Android ทุกตัวเป็นผู้ใช้ UNIX / Linux และมี uid) โดยไม่มีข้อ จำกัด ดังนั้นจึงทำให้เกิดความกังวลด้านความปลอดภัยและความเป็นส่วนตัว
ปัญหาทั้งสองนี้ได้รับการแก้ไขผ่านการจำลอง:
- ที่เก็บข้อมูล SD การ์ดที่แท้จริงถูกย้ายไปที่
/data
พาร์ติชัน (หรือพาร์ติชันอิสระ / sdcard บนอุปกรณ์บางรุ่นก่อนหน้านี้) ซึ่งเก็บext4
ระบบไฟล์ (ค่อยๆถูกแทนที่ด้วยf2fs
) โดยใช้สิทธิ์ UNIX อย่างเต็มที่
- การออกแบบนี้ทำให้การใช้ UMS เป็นไปไม่ได้เพราะทั้ง
/data
พาร์ติชันไม่สามารถสัมผัสกับพีซีด้วยเหตุผลอีก 2 ประการ: (1)
มีการตั้งค่าและข้อมูลแอพจำนวนมากซึ่งได้รับการปกป้องจากแอพอื่น ๆ รวมถึงผู้ใช้ที่เป็นมนุษย์ (2)
Windows ไม่รองรับระบบไฟล์ Linux
ดังนั้น UMS จึงถูกแทนที่ด้วย Media Transfer Protocol ซึ่งเป็นส่วนขยายประเภทไคลเอนต์ - เซิร์ฟเวอร์ไปยัง PTP - โปรโตคอลที่กำหนดไว้แล้ว MTPไม่เปิดเผยอุปกรณ์บล็อค แต่ทำงานผ่านซอฟต์แวร์สแต็ค โฮสต์ MTP ทำงานบน Android เป็นแอป ( android.process.media
) แซนด์บ็อกซ์ในกรอบ Android อย่างเต็มที่ไม่สามารถทำงานที่เพิ่มขึ้นใด ๆ ได้
ตอนนี้แอพ (และ MTP ซึ่งเป็นแอพ) โต้ตอบกับที่เก็บข้อมูลจำลองแทนที่จะ/data/media
บรรลุวัตถุประสงค์ทั้งสองอย่างในเวลาเดียวกันนั่นคือบังคับให้มีการตรวจสอบการอนุญาตภายใต้และดูเหมือนระบบไฟล์ FAT บนพื้นผิวด้านบน
Google อยู่ในขณะนี้การดำเนินการจำลองผ่านsdcardfsจะเอาชนะข้อบกพร่องของฟิวส์ ; หลักอย่างหนึ่งคือโอเวอร์เฮดของอินพุต / เอาต์พุตเช่นเพื่อปรับปรุงความเร็วในการอ่าน / เขียน
สิทธิ์การจัดเก็บภายนอก:
แนวคิดของไฟล์สาธารณะและส่วนตัวในการจัดเก็บข้อมูลภายนอกสามารถแสดงให้เห็นได้โดยใช้ตัวอย่าง:
ติดตั้งแอพ Termux
สร้างไดเรกทอรีและ/sdcard/Android/data/com.termux/test_dir
สร้างไฟล์และ
ดำเนินการคำสั่งต่อไปนี้:/sdcard/test_dir
/sdcard/Android/data/com.termux/test_file
/sdcard/Android/data/com.termux/test_file
* คุณควรติดตั้ง WhatsApp หรือเลือกโฟลเดอร์ส่วนตัวของแอพอื่น ๆ
ตอนนี้กองทัพหยุด Termux แอปและให้ได้รับอนุญาตการจัดเก็บข้อมูล ดำเนินการคำสั่งอีกครั้ง:
ดูความแตกต่างในการอนุญาตของไฟล์และไดเรกทอรีเดียวกัน สิ่งนี้ดูเหมือนจะเป็นไปไม่ได้เลยหากไม่มีการจำลองระบบไฟล์ดั้งเดิมของ Linux เมื่อมีแอพ (ผู้ใช้) นับร้อยที่ต้องจัดการพร้อมกัน นี่คือการจำลองระบบไฟล์ที่อนุญาตให้ไฟล์เดียวกันสัมผัสกับชุดของการอนุญาตที่แตกต่างกันสามชุดในเวลาเดียวกันโดยไม่ขึ้นกับการอนุญาตดั้งเดิมของระบบไฟล์จริง:
# touch /data/media/0/test_file
# stat -c '%a %u %g %n' /data/media/0/test_file
644 1023 1023 /data/media/0/test_file
# stat -c '%a %u %g %n' /mnt/runtime/*/emulated/0/test_file
660 0 1015 /mnt/runtime/default/emulated/0/test_file
640 0 9997 /mnt/runtime/read/emulated/0/test_file
660 0 9997 /mnt/runtime/write/emulated/0/test_file
โปรดดูเพิ่มเติม"u # _everybody" UID คืออะไร
ที่เกี่ยวข้อง: