Внешнее хранилище управляется сочетанием сервиса vold init
и системного сервиса StorageManagerService. Монтирование физических внешних накопителей выполняется vold, который подготавливает носитель, прежде чем предоставить доступ к нему приложениям.
Примечание. В Android 8.0 класс MountService был переименован в StorageManagerService.
Сопоставления файлов
В Android 4.2.2 и более ранних версий в файле конфигурации vold.fstab
определяются сопоставления устройств sysfs с точками монтирования файловой системы. Каждая строка имеет следующий формат:
dev_mount <label> <mount_point> <partition> <sysfs_path> [flags]
label– ярлык для тома.mount_point: путь к файловой системе, по которому должен быть смонтирован том.partition: номер раздела (начиная с 1) или auto для первого доступного раздела.sysfs_path: один или несколько путей sysfs к устройствам, которые могут предоставить эту точку монтирования. Разделены пробелами и начинаются с символа/.flags– необязательный список флагов, разделенных запятыми. Не должен содержать/. Возможные значения:nonremovableиencryptable.
В Android 4.3 и более поздних версиях различные файлы fstab, используемые init, vold и recovery, были объединены в файл /fstab.<device>. Для внешних накопителей, управляемых vold, записи должны иметь следующий формат:
<src> <mnt_point> <type> <mnt_flags> <fs_mgr_flags>
src– путь в sysfs (обычно подключается в /sys) к устройству, которое может предоставить точку подключения. Путь должен начинаться с символа косой черты (/).mount_point: путь в файловой системе, по которому должен быть смонтирован том.type– тип файловой системы на томе. Для внешних карт это обычноvfat.mnt_flags:Voldигнорирует это поле, и ему должно быть присвоено значениеdefaults.fs_mgr_flags:Voldигнорирует все строки в объединенном файле fstab, в которых в этом поле не указан флагvoldmanaged=. За этим флагом должен следовать ярлык, описывающий карту, и номер раздела или словоauto. Вот пример:voldmanaged=sdcard:auto. Другие возможные флаги:nonremovable,encryptable=sdcard,noemulatedsdиencryptable=userdata.
Сведения о конфигурации
Взаимодействие с внешним хранилищем на уровне фреймворка и выше обрабатывается через StorageManagerService. Из-за изменений конфигурации в Android 6.0 (например, удаления наложения ресурса storage_list.xml) сведения о конфигурации разделены на две категории.
Android 5.x и более ранние версии
Файл конфигурации storage_list.xml для устройства, обычно предоставляемый через наложение frameworks/base, определяет атрибуты и ограничения устройств хранения данных. Элемент <StorageList> содержит один или несколько элементов <storage>, один из которых должен быть отмечен как основной. Атрибуты <storage> включают:
mountPoint: путь к точке монтирования в файловой системе.storageDescription– строковый ресурс, описывающий эту точку монтирования.primary– значение true, если это основное внешнее хранилище.removable: true, если у этого подключения есть съемный носитель, например физическая SD-карта.emulated– значение true, если эта точка монтирования эмулируется и поддерживается внутренним хранилищем, возможно, с использованием демона FUSE.mtp-reserve– количество МБ хранилища, которое MTP должен зарезервировать для бесплатного хранения. Используется, только если точка монтирования помечена как эмулированная.allowMassStorage– значение true, если этот раздел можно использовать как USB-накопитель.maxFileSize– максимальный размер файла в МБ.
Устройства могут предоставлять внешнее хранилище, эмулируя файловую систему без учета регистра и разрешений, поддерживаемую внутренним хранилищем. Один из возможных вариантов реализации – демон FUSE в system/core/sdcard, который можно добавить как сервис init.rc для конкретного устройства:
# virtual sdcard daemon running as media_rw (1023)
service sdcard /system/bin/sdcard <source_path> <dest_path> 1023 1023
class late_start
где source_path – это внутренняя память, а dest_path – целевая точка монтирования.
При настройке скрипта init.rc для конкретного устройства переменная среды EXTERNAL_STORAGE должна быть определена как путь к основному внешнему накопителю. Путь /sdcard также должен вести к тому же местоположению, возможно, через символическую ссылку. Если устройство корректирует местоположение внешнего накопителя между обновлениями платформы, необходимо создать символические ссылки, чтобы старые пути продолжали работать.
Android 6.0
Настройка подсистемы хранения теперь сосредоточена в файле fstab, относящемся к определенному устройству. Чтобы обеспечить более динамичное поведение, мы удалили несколько статических файлов конфигурации и переменных.
- Оверлей ресурсов
storage_list.xmlудален и больше не используется фреймворком. Теперь устройства хранения данных настраиваются динамически, когда их обнаруживаетvold. - Переменные среды
EMULATED_STORAGE_SOURCE/TARGETбыли удалены и больше не используются Zygote для настройки точек подключения, относящихся к определенному пользователю. Теперь разделение пользователей обеспечивается с помощью GID, относящихся к определенным пользователям, а основное общее хранилище монтируется в нужное место с помощьюvoldво время выполнения.- Разработчики могут создавать пути динамически или статически в зависимости от своих потребностей. Включение UUID в путь позволяет идентифицировать каждую карту и сделать ее местоположение более понятным для разработчиков. Например,
/storage/ABCD-1234/report.txt– это не то же самое, что/storage/DCBA-4321/report.txt.
- Разработчики могут создавать пути динамически или статически в зависимости от своих потребностей. Включение UUID в путь позволяет идентифицировать каждую карту и сделать ее местоположение более понятным для разработчиков. Например,
- Сервисы FUSE, заданные в коде, были удалены из файлов
init.rc, относящихся к конкретным устройствам. Теперь они динамически разветвляются изvoldпо мере необходимости.
Помимо этих изменений в конфигурации, в Android 6.0 появилась концепция переносимого хранилища. На устройствах с Android 6.0 любое физическое устройство хранения, которое не было адаптировано, считается переносным.
Внедряемый накопитель
Чтобы указать в fstab внедряемый накопитель, используйте атрибут encryptable=userdata в поле fs_mgr_flags. Вот типичное определение:
/devices/platform/mtk-msdc.1/mmc_host* auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
Когда устройство хранения данных становится внутренним, платформа удаляет его содержимое и записывает таблицу разделов GUID, которая определяет два раздела:
- небольшой пустой раздел
android_meta, зарезервированный для использования в будущем. GUID типа раздела: 19A710A2-B3CA-11E4-B026-10604B889DCF. - большой раздел
android_ext, зашифрованный с помощью dm-crypt и отформатированный с использованиемext4илиf2fsв зависимости от возможностей ядра. GUID типа раздела: 193D1EA4-B3CA-11E4-B075-10604B889DCF.
Съемный накопитель
В элементе fstab устройства хранения данных с атрибутом voldmanaged по умолчанию считаются портативными, если не определен другой атрибут, например encryptable=userdata. Например, вот типичное определение для устройств USB OTG:
/devices/*/xhci-hcd.0.auto/usb* auto auto defaults
voldmanaged=usb:auto
Платформа использует blkid для определения типа файловой системы перед подключением. Если файловая система не поддерживается, пользователь может отформатировать носитель.