データストレージ——Androidファイルストレージシステム及びファイルシステム(Android Q)


Androidストレージシステムおよびストレージのマウント
AndroidはLinuxカーネルに基づいて開発されたので、ファイルシステムもLinuxファイルシステムと似ています.
まずAndroidストレージの分類を見てみましょう.
内部ストレージと外部ストレージ、内蔵SDカードと外付けSDカード
一般的なAndroid携帯電話には2つのメモリカードがあり、1つは携帯電話に内蔵されており、交換不可で、内蔵メモリカードと呼ばれています.もう1つは拡張カードスロットでSDカードを追加することができ、外付けSDカードと呼ばれます.内蔵メモリカードと外付けSDカードは、物理的に区別され、1つはデバイスに内蔵され、もう1つは追加された拡張カードです.
Androidシステムでは、ストレージは内部ストレージと外部ストレージの2種類に分けられます.内部ストレージはアプリケーションのインストールディレクトリの下(dataディレクトリ)、外部ストレージ(通常はsdcardディレクトリ)はアプリケーションのインストールディレクトリの外にあり、それらはディレクトリを基準として区分されている.内蔵メモリカードと外付けSDカードの概念と混同しないでください.一つは論理的な区分で、もう一つは物理的な区分です.
ストレージに必要な権限
App開発では、通常、Appのストレージ権限についていくつかの処理が必要です.
  • 内部ストレージには、Appの個別申請権限は必要ありません.
  • 外部ストレージは、Appが外部ストレージの読み書き権限を申請する必要があり、使用する場合は、まず、外部ストレージがマウントされているかどうかを判断する(外部ストレージは必ずしも利用可能ではないため).
  • 読み取り権限:android.permission.READ_EXTERNAL_STORAGE
  • 読み書き権限:android.permission.WRITE_EXTERNAL_STORAGE

  • ストレージが内部ストレージと外部ストレージに分かれていることを理解しました.次に、外部ストレージがどのようにシステムにマウントされているかを分析します.
    外部ストレージのマウント
    sdcardはよく言われるsdカードルートディレクトリで、外部ストレージがどのようにシステムにマウントされているかを分析します.
    パスのリンク関係
    sdcardのパスリンク関係を見てみましょう.
    /sdcard -> /storage/self/primary
    /mnt/sdcard -> /storage/self/primary
    
    /storage/self/primary -> /mnt/user/0/primary
    /mnt/runtime/default/self/primary -> /mnt/user/0/primary
    
    /mnt/user/0/primary -> /storage/emulated/0
    

    説明:
  • sdcardはソフトリンクであり、実際のアドレスは/storage/self/primaryである.
  • /storage/self/primaryおよび/mnt/runtime/default/self/primaryもソフトリンクであり、実際のアドレスは/mnt/user/0/primaryである.
  • /mnt/user/0/primaryもソフトリンクであり、実際のアドレスは/storage/emulated/0である.
  • は、最終的に/storage/emulated/0ディレクトリにリンクされます.

  • 動的ストレージ権限の付与の実装
    Android6.0インストール時権限モデルから実行時権限モデルに危険とマークされた権限を移動する新しい適用権限モデルが導入されました.新しいモデルにはREAD/WRITE_が含まれていますEXTERNAL_STORAGEという2つのストレージ権限のため、Androidシステムは、実行中のアプリケーションを殺したり再起動したりしない前提で、ストレージアクセスを動的に許可する必要があります.
    ストレージへの動的アクセスは、マウントされているすべてのストレージデバイスの3つの異なるビューを維持することによって実現されます.
    /mnt/runtime/default:すべてのアプリケーション、rootネーミングスペースに権限を必要とせずに表示されます./mnt/runtime/read:対にREAD_があるEXTERNAL_STORAGE権限の適用が表示されます./mnt/runtime/write:対有WRITE_EXTERNAL_STORAGE権限の適用が表示されます.
    この3つの異なる権限ディレクトリが表示されるのは、異なる権限appアクセスを制御するためです.次に、マウントネーミングスペースを使用してマウントポイントの分離を実現し、異なるマウントネーミングスペースのプロセスで、表示されるディレクトリ階層が異なります.各appは、独自の権限に基づいて異なる権限のruntimeディレクトリを選択してアクセスし、異なるユーザーがアクセスするディレクトリも現在のユーザーのidによって区別されます.
    具体的には、zygote forkプロセスの場合、実行中のアプリケーションごとにmountネーミングスペースを作成し、bind mountの適切な初期ビューを作成します.実行時権限が付与されると、vold(voldはAndoridシステムのデバイスマネージャ、Androidシステムはvold層を介してディスクのホットスワップ機能を完了する)が実行中のアプリケーションのネーミングスペース上でbind mountによってビューを更新する.権限が取り消されると、そのアプリケーションがkillされることを意味する.システムはsetns()関数を用いて上述の特性を実現し、Linux 3が要求する.8ですがLinux 3.4この機能はパッチに加えてもサポートされます.
    /mnt/runtime/defaultのマウント
    /mnt/runtime/default電源を入れてinitを実行します.rcの場合、storageの下にマウントします.
        # Mount default storage into root namespace
        mount none /mnt/runtime/default /storage bind rec
    

    そしてinitを実行する.rcスクリプトのソフトリンク:
        # Symlink to keep legacy apps working in multi-user world
        symlink /storage/self/primary /sdcard
        symlink /storage/self/primary /mnt/sdcard
        symlink /mnt/user/0/primary /mnt/runtime/default/self/primary
    

    ソフトリンク&ハードリンク
    上記では、Androidファイルシステムに多くのソフトリンクが使われていることを知っていますが、ソフトリンクとは何ですか?リンクはまたいくつのタイプに分けられますか?
    *ソフトリンク
    ソフトリンクはシンボルリンクとも呼ばれ、このファイルには別のファイルのパス名が含まれています.任意のファイルまたはディレクトリで、windowsのショートカットに似た異なるファイルシステムのファイルをリンクできます.リンクファイルは、存在しないファイルにもリンクできます.
    *ハードリンク
    ハードリンクは一つの災害バックアップに相当する、データは二つの場所に保管され、複製とは異なる二つの場所の間に同期機構が存在し、一つのデータの変更はリアルタイムで別の場所に同期し、もう一つのデータが削除された場合、別の場所のデータに影響しない.
    ハードリンクは、ファイルのコピーとして存在しますが、実際のスペースは使用されません.ハードリンクファイルには2つの制限があります.ディレクトリにハードリンクを作成できません.リンクを作成できるのは、同じファイルシステム内のファイル間だけです.
    権限制御とファイルシステム
    Android 8.0以上は、三星wrapfsが書き換えたSDcardFSファイルシステムをサポートし始めた.
    fuseファイルシステム(Filesystem in Userspace)
    以前のバージョンandroidシステムではfuseファイルシステムが使用されており、異なるAPPによるファイルアクセスの権限を制御していました.
    Androidは携帯電話に内蔵されているSDカードをuserdataパーティションと統合してパーティション化した.userdataパーティションはext 4ファイルシステムを使用してデータを格納し、userdataパーティションにアクセスするにはext 4ファイルシステムを直接操作し、内蔵SDカードにアクセスするにはfuseファイルシステムにアクセスしてからext 4ファイルシステムにアクセスします.
    fuseファイルシステムの基本的な方法は、fuseデバイスを作成し、内蔵SDカードディレクトリに関連付けられたディレクトリにfuseデバイスをマウントすることです.では、内蔵SDカードへのアクセスは、まずfuseファイルシステムにアクセスし、ext 4ファイルシステムにアクセスすることになります.fuseのカーネルセクションには、pendingキューとprocessingキューを含む複数のキューが作成されます.呼び出し元がSDカードを内蔵したシステムを呼び出すたびに、fuseはファイルアクセスパスをext 4ファイルシステムに対する操作パスに変換し、対応する操作コードを設定し、要求に入れる.fuseはユーザ状態に3つのモニタリングスレッドがあり,fuseデバイスを循環的に読み出す.fuseデバイスの読み出し動作は、カーネル部分でpendingキューからの読み出し要求を変換し、キューに要求がない場合、対応するスレッドはスリープ状態に入る.モニタリングスレッドはpendingキュー内のリクエストを読み出した後、リクエストをext 4ファイルシステムに対するシステム呼び出し操作に変換する.システム呼び出し実行が完了すると、モニタリングスレッドは実行結果をfuseデバイスに書き込み、fuseデバイスに対する書き込み操作はカーネル部分で結果をprocessingキューに入れるように変換される.プロセスキューは結果を順次取り出し,呼び出し者に返す.
    fuseは、カーネル状態とのインタラクションを複数回行う必要があります.これにより、スイッチングオーバーヘッドが発生します.
    SDcardFSファイルシステム
    sdcardfsの役割はfuseと同様であり、ファイルアクセスを制御するための権限でもある.sdcardfsの動作は、内蔵SDカードディレクトリを権限制御ディレクトリにマウントすることです.SDカードを内蔵したシステムを呼び出し、sdcardfsを経由してからアクセス経路をext 4ファイルシステムの真の経路に変更し、ext 4ファイルシステムに到達します.ext 4の実行が完了したら、結果をsdcardfsに返し、呼び出し者に返します.
    sdcardfsのメリット:
  • は同じファイルにアクセスし、fuseは6回のユーザ状態とカーネル状態の切り替えを必要とするが、sdcardfsは2回の切り替えしか必要としない.
  • fuseはカーネルに複数のキューがあり、キュー内の要素の列は前の要素が先に列を出すのを待つ必要があるため、単一のファイルアクセスではsdcardfsよりもfuseの方が時間がかかります.大量のファイルアクセスが必要な場合,累積による時間差は明らかに感じられる.
  • SDcardは、ユーザ状態とカーネル状態の切り替えを低減するため、理論的性質が実際のシステムに非常に近い.