External Storage Technical Information

来源:互联网 发布:采集软件靠谱吗 编辑:程序博客网 时间:2024/05/23 12:05
出处:

http://source.android.com/tech/storage/

External Storage Technical Information

Android supports devices with external storage, which is defined to be acase-insensitive and permissionless filesystem. External storage can beprovided by physical media (such as an SD card), or by an emulation layer backedby internal storage. Devices may contain multiple instances of externalstorage, but currently only the primary external storage is exposed todevelopers through API.

外置sdcard可以是物理的也可以是模拟的;也可以多个,但只有 主外置sdcard可以通过api访问。

Device specific configuration

External storage is managed by a combination of the vold init service andMountService system service.

Mounting of physical external storage volumes is handled by vold, whichperforms staging operations to prepare the media before exposing it to apps.The device-specificvold.fstab configuration file defines mappings from sysfsdevices to filesystem mount points, and each line follows this format:

dev_mount <label> <mount_point> <partition> <sysfs_path> [flags]
  • label: Label for the volume.
  • mount_point: Filesystem path where the volume should be mounted.
  • partition: Partition number (1 based), or 'auto' for first usable partition.
  • sysfs_path: One or more sysfs paths to devices that can provide this mountpoint. Separated by spaces, and each must start with/.
  • flags: Optional comma separated list of flags, must not contain /.Possible values include nonremovable and encryptable.

External storage interactions at and above the framework level are handledthroughMountService. The device-specific storage_list.xml configurationfile, typically provided through aframeworks/base overlay, defines theattributes and constraints of storage devices. The<StorageList> elementcontains one or more <storage> elements, exactly one of which should be markedprimary.<storage> attributes include:

  • mountPoint: filesystem path of this mount.
  • storageDescription: string resource that describes this mount.
  • primary: true if this mount is the primary external storage.
  • removable: true if this mount has removable media, such as a physical SDcard.
  • emulated: true if this mount is emulated and is backed by internal storage,possibly using a FUSE daemon.
  • mtp-reserve: number of MB of storage that MTP should reserve for freestorage. Only used when mount is marked as emulated.
  • allowMassStorage: true if this mount can be shared via USB mass storage.
  • maxFileSize: maximum file size in MB.

Devices may provide external storage by emulating a case-insensitive,permissionless filesystem backed by internal storage. One possibleimplementation is provided by the FUSE daemon insystem/core/sdcard, which canbe added as a device-specific init.rc service:

# virtual sdcard daemon running as media_rw (1023)service sdcard /system/bin/sdcard <source_path> <dest_path> 1023 1023    class late_start

Where source_path is the backing internal storage and dest_path is thetarget mount point.


通过内置存储器可以模拟出一个大小写敏感的有权限管理的外置存储器,通过FUSE daemon实现,如上代码可以添加到  init_xxx.rc服务中,source_path 是backing internal storage(?内部存储的部分空间),dest_path是目标挂载点。

When configuring a device-specific init.rc script, the EXTERNAL_STORAGEenvironment variable must be defined as the path to the primary externalstorage. The/sdcard path must also resolve to the same location, possiblythrough a symlink. If a device adjusts the location of external storage betweenplatform updates, symlinks should be created so that old paths continue working.

As an example, here’s the storage configuration for Xoom, which uses a FUSEdaemon to provide primary external storage, and includes a physical SD card assecondary external storage:

  • vold.fstab
  • storage_list.xml

Access to external storage is protected by various Android permissions.Starting in Android 1.0, write access is protected with theWRITE_EXTERNAL_STORAGE permission, implemented using thesdcard_rw GID.Starting in Android 4.1, read access is protected with the newREAD_EXTERNAL_STORAGE permission, implemented using thesdcard_r GID. Toimplement the read permission, a new top-level /storage directory was created such that processes must hold the sdcard_r GID to traverse into it.

Since external storage offers no support for traditional POSIX filesystempermissions, system code should not store sensitive data on external storage.Specifically, configuration and log files should only be stored on internalstorage where they can be effectively protected.

访问外置存储器是被android保护的,但各个版本都不同。自android1.0是用WRITE_EXTERNAL_STORAGE权限,实现是用sdcard_rd组权限。从android4.1起 读权限是用READ_EXTERNAL_STORAGE保护,使用sdcard_r组权限包含。为了实现这个权限管理,新的顶层目录/storage被创建出来,进程必须具有sdcard_r GID才能遍历它。

因为外置存储器无法对 传统的POSIX文件系统提供权限管理等机制,所以系统代码不该存储敏感数据在上面。特别是配置和log文件等应该只存储在内部存储器上,它们能被有效保护。

Multi-user external storage

Starting in Android 4.2, devices can support multiple users, and externalstorage must meet the following constraints:

  • Each user must have their own isolated primary external storage, and must nothave access to the primary external storage of other users.
  • The /sdcard path must resolve to the correct user-specific primary externalstorage based on the user a process is running as.
  • Storage for large OBB files in the Android/obb directory may be sharedbetween multiple users as an optimization.
  • Secondary external storage must not be writable by apps.

The default platform implementation of this feature leverages Linux kernel namespaces to create isolated mount tables for each Zygote-forked process, and then uses bind mounts to offer the correct user-specific primary external storage into that private namespace.

At boot, the system mounts a single emulated external storage FUSE daemon atEMULATED_STORAGE_SOURCE, which is hidden from apps. After the Zygote forks,it bind mounts the appropriate user-specific subdirectory from under the FUSEdaemon toEMULATED_STORAGE_TARGET so that external storage paths resolve correctly for the app. Because an app lacks accessible mount points for other users’ storage, they can only access storage for the user it was started as.

This implementation also uses the shared subtree kernel feature to propagate mount events from the default root namespace into app namespaces, which ensures that features like ASEC containers and OBB mounting continue working correctly.It does this by mounting the rootfs as shared, and then remounting it as slave after each Zygote namespace is created.


自4.2起,设备可能支持多用户,外置存储必须满足如下条件:

1)每个用户有独立的主外置存储器,并且相互不能访问;

2)/sdcard路径 必须解决 更加不同用户进程访问不同用户的主外置存储。

3)安装到外部的apk的lib等文件在不同用户间能共享,以作优化。

4)第二个外置存储必须不能被app写。(包含敏感数据)。


默认平台实现此功能利用Linux内核的命名空间为每个zygote的子进程创建独立的挂载,利用bind mounts给每个用户的主外部储存空间挂载到私有空间上。??


在启动间段,系统挂载一个独立的虚拟的外部存储空间EMULATED_STORAGE_SOURCE,这个对apps是不可见的。当zygote开始创建子进程,他开始从FUSE daemon下bind mounts相应用户的子文件夹到EMULATED_STORAGE_TARGET,这样解决了对于app来说外部存储路径是对的了。而且app只能访问自己用户的存储空间


这个实现使用共享子树内核功能,来广播从默认的根namespace事件挂载应用程序的namespace确保ASEC容器OBB安装的功能,继续正常工作

它通过开始时挂载rootfs作为共用的,在Zygote的namespace创建后,将其重新挂载作为slave




原创粉丝点击