Home | History | Annotate | Download | only in storage
      1 page.title=External Storage Technical Information
      2 @jd:body
      3 
      4 <!--
      5     Copyright 2010 The Android Open Source Project
      6 
      7     Licensed under the Apache License, Version 2.0 (the "License");
      8     you may not use this file except in compliance with the License.
      9     You may obtain a copy of the License at
     10 
     11         http://www.apache.org/licenses/LICENSE-2.0
     12 
     13     Unless required by applicable law or agreed to in writing, software
     14     distributed under the License is distributed on an "AS IS" BASIS,
     15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16     See the License for the specific language governing permissions and
     17     limitations under the License.
     18 -->
     19 <p>Android supports devices with external storage, which is defined to be a
     20 case-insensitive and permissionless filesystem.  External storage can be
     21 provided by physical media (such as an SD card), or by an emulation layer backed
     22 by internal storage.  Devices may contain multiple instances of external
     23 storage, but currently only the primary external storage is exposed to
     24 developers through API.</p>
     25 <h2 id="device-specific-configuration">Device specific configuration</h2>
     26 <p>External storage is managed by a combination of the <code>vold</code> init service and
     27 <code>MountService</code> system service.</p>
     28 <p>Mounting of physical external storage volumes is handled by <code>vold</code>, which
     29 performs staging operations to prepare the media before exposing it to apps.</p>
     30 
     31 <p>For Android 4.2.2 and earlier, the device-specific <code>vold.fstab</code>
     32 configuration file defines mappings from sysfs
     33 devices to filesystem mount points, and each line follows this format:</p>
     34 <pre><code>dev_mount &lt;label&gt; &lt;mount_point&gt; &lt;partition&gt; &lt;sysfs_path&gt; [flags]
     35 </code></pre>
     36 <ul>
     37 <li><code>label</code>: Label for the volume.</li>
     38 <li><code>mount_point</code>: Filesystem path where the volume should be mounted.</li>
     39 <li><code>partition</code>: Partition number (1 based), or 'auto' for first usable partition.</li>
     40 <li><code>sysfs_path</code>: One or more sysfs paths to devices that can provide this mount
     41 point.  Separated by spaces, and each must start with <code>/</code>.</li>
     42 <li><code>flags</code>: Optional comma separated list of flags, must not contain <code>/</code>.
     43 Possible values include <code>nonremovable</code> and <code>encryptable</code>.</li>
     44 </ul>
     45 <p>For Android releases 4.3 and later, the various fstab files used by init, vold and
     46 recovery were unified in the <code>/fstab.&lt;device&gt;</code> file.  For external
     47 storage volumes that are managed by <code>vold</code>, the entries should have the
     48 following format:</p>
     49 <pre><code>&lt;src&gt; &lt;mnt_point&gt; &lt;type&gt; &lt;mnt_flags&gt; &lt;fs_mgr_flags&gt;
     50 </code></pre>
     51 <ul>
     52 <li><code>src</code>: A path under sysfs (usually mounted at /sys) to the device that
     53 can provide the mount point.  The path must start with <code>/</code>.</li> <li><code>mount_point</code>: Filesystem path where the volume should be mounted.</li>
     54 <li><code>type</code>: The type of the filesystem on the volume.  For external cards,
     55 this is usually <code>vfat</code>.</li>
     56 <li><code>mnt_flags</code>: <code>Vold</code> ignores this field and it should be set
     57 to <code>defaults</code></li>
     58 <li><code>fs_mgr_flags</code>: <code>Vold</code> ignores any lines in the unified fstab
     59 that do not include the <code>voldmanaged=</code> flag in this field.  This flag must
     60 be followed by a label describing the card, and a partition number or the word
     61 <code>auto</code>.  Here is an example: <code>voldmanaged=sdcard:auto</code>.
     62 Other possible flags are <code>nonremovable</code> and <code>encryptable=sdcard</code>.
     63 </ul>
     64 <p>External storage interactions at and above the framework level are handled
     65 through <code>MountService</code>.  The device-specific <code>storage_list.xml</code> configuration
     66 file, typically provided through a <code>frameworks/base</code> overlay, defines the
     67 attributes and constraints of storage devices.  The <code>&lt;StorageList&gt;</code> element
     68 contains one or more <code>&lt;storage&gt;</code> elements, exactly one of which should be marked
     69 primary.  <code>&lt;storage&gt;</code> attributes include:</p>
     70 <ul>
     71 <li><code>mountPoint</code>: filesystem path of this mount.</li>
     72 <li><code>storageDescription</code>: string resource that describes this mount.</li>
     73 <li><code>primary</code>: true if this mount is the primary external storage.</li>
     74 <li><code>removable</code>: true if this mount has removable media, such as a physical SD
     75 card.</li>
     76 <li><code>emulated</code>: true if this mount is emulated and is backed by internal storage,
     77 possibly using a FUSE daemon.</li>
     78 <li><code>mtp-reserve</code>: number of MB of storage that MTP should reserve for free
     79 storage.  Only used when mount is marked as emulated.</li>
     80 <li><code>allowMassStorage</code>: true if this mount can be shared via USB mass storage.</li>
     81 <li><code>maxFileSize</code>: maximum file size in MB.</li>
     82 </ul>
     83 <p>Devices may provide external storage by emulating a case-insensitive,
     84 permissionless filesystem backed by internal storage.  One possible
     85 implementation is provided by the FUSE daemon in <code>system/core/sdcard</code>, which can
     86 be added as a device-specific <code>init.rc</code> service:</p>
     87 <pre><code># virtual sdcard daemon running as media_rw (1023)
     88 service sdcard /system/bin/sdcard &lt;source_path&gt; &lt;dest_path&gt; 1023 1023
     89     class late_start
     90 </code></pre>
     91 <p>Where <code>source_path</code> is the backing internal storage and <code>dest_path</code> is the
     92 target mount point.</p>
     93 <p>When configuring a device-specific <code>init.rc</code> script, the <code>EXTERNAL_STORAGE</code>
     94 environment variable must be defined as the path to the primary external
     95 storage.  The <code>/sdcard</code> path must also resolve to the same location, possibly
     96 through a symlink.  If a device adjusts the location of external storage between
     97 platform updates, symlinks should be created so that old paths continue working.</p>
     98 <p>As an example for Android 4.2.2 and earlier, here's the storage configuration for Xoom,
     99 which uses a FUSE daemon to provide primary external storage, and includes a physical SD card as
    100 secondary external storage:</p>
    101 <ul>
    102 <li><a href="https://android.googlesource.com/device/moto/wingray/+/master/vold.fstab">vold.fstab</a></li>
    103 <li><a href="https://android.googlesource.com/device/moto/wingray/+/master/overlay/frameworks/base/core/res/res/xml/storage_list.xml">storage_list.xml</a></li>
    104 </ul>
    105 <p>As an example for Android 4.3 and later devices, here's the <code>fstab.goldfish</code> file
    106 for the Android emulator, which emulates an external SD card as primary external storage:</p>
    107 <ul>
    108 <li><a href="https://android.googlesource.com/device/generic/goldfish/+/master/fstab.goldfish">fstab.goldfish</a></li>
    109 </ul>
    110 <p>Access to external storage is protected by various Android permissions.
    111 Starting in Android 1.0, write access is protected with the
    112 <code>WRITE_EXTERNAL_STORAGE</code> permission, implemented using the <code>sdcard_rw</code> GID.
    113 Starting in Android 4.1, read access is protected with the new
    114 <code>READ_EXTERNAL_STORAGE</code> permission, implemented using the <code>sdcard_r</code> GID.  To
    115 implement the read permission, a new top-level <code>/storage</code> directory was created
    116 such that processes must hold the <code>sdcard_r</code> GID to traverse into it.</p>
    117 <p>Since external storage offers no support for traditional POSIX filesystem
    118 permissions, system code should not store sensitive data on external storage.
    119 Specifically, configuration and log files should only be stored on internal
    120 storage where they can be effectively protected.</p>
    121 <h2 id="multi-user-external-storage">Multi-user external storage</h2>
    122 <p>Starting in Android 4.2, devices can support multiple users, and external
    123 storage must meet the following constraints:</p>
    124 <ul>
    125 <li>Each user must have their own isolated primary external storage, and must not
    126 have access to the primary external storage of other users.</li>
    127 <li>The <code>/sdcard</code> path must resolve to the correct user-specific primary external
    128 storage based on the user a process is running as.</li>
    129 <li>Storage for large OBB files in the <code>Android/obb</code> directory may be shared
    130 between multiple users as an optimization.</li>
    131 <li>Secondary external storage must not be writable by apps.</li>
    132 </ul>
    133 <p>The default platform implementation of this feature leverages Linux kernel
    134 namespaces to create isolated mount tables for each Zygote-forked process, and
    135 then uses bind mounts to offer the correct user-specific primary external
    136 storage into that private namespace.</p>
    137 <p>At boot, the system mounts a single emulated external storage FUSE daemon at
    138 <code>EMULATED_STORAGE_SOURCE</code>, which is hidden from apps.  After the Zygote forks,
    139 it bind mounts the appropriate user-specific subdirectory from under the FUSE
    140 daemon to <code>EMULATED_STORAGE_TARGET</code> so that external storage paths resolve
    141 correctly for the app.  Because an app lacks accessible mount points for other
    142 users' storage, they can only access storage for the user it was started as.</p>
    143 <p>This implementation also uses the shared subtree kernel feature to propagate
    144 mount events from the default root namespace into app namespaces, which ensures
    145 that features like ASEC containers and OBB mounting continue working correctly.
    146 It does this by mounting the rootfs as shared, and then remounting it as slave
    147 after each Zygote namespace is created.</p>
    148