fs_tab文件的解析

fstab 文件保存在哪

按照android文檔,Android 4.3 及更高版本,init、vold和recovery所用到的都是/fstab.<device>文件。可是在AndroidO 的中,彷佛發生了變化。node

fsmgr中,fstab 的來源有兩個,一個是device tree中指定,另外一個則是從fstab.<device>文件中加載。這兩個來源的中的fstab配置最終會被合併到一塊兒。android

image-20201124200046658

  1. fstab 文件c++

    能夠看出,AndroidO中配置 fstab文件的地方有三個: /odm/etc//vendor/etc//,優先級由大變小。shell

fstab. 中的 device 值就是屬性 ro.boot.hardware 的值,若是沒有配置該屬性,就會去/proc/cmdline中讀取hardware的值,還讀不到就去查找 device tree。app

image-20201124200547339

在Rockchip平臺上,fstab.rk30board直接保存到了根目錄。不太清楚爲啥不按照安卓標準,放在/vendor/etc目錄下面額。函數

  1. 設備樹中的配置ui

    經過查看RK339的設備樹文件,能夠看到systemvendor分區的配置是在設備樹中配置的。code

    image-20201125000826082

解析fstab

fstab的基本格式以下:ip

<src> <mnt_point> <type> <mnt_flags> <fs_mgr_flags>
  • src: sysfs(/sys)下能夠的設備的路徑。路徑必須以/開頭,設備的實際路徑是/sys$(src)
  • mnt_point: 設備掛載路徑。
  • type: 該設備的上的卷的文件類型。
  • mnt_flags:Vold會忽略該字段,因此,對於由vold管理的設備,該字段能夠設置爲defaults
  • fs_mgr_flagsfs_mgr_flagsVold 會忽略此字段中不包含 voldmanaged= 標記的統一的 fstab 中的任何行。該標記必須後跟描述卡的標籤,以及分區號或字詞 auto。例如:voldmanaged=sdcard:auto

fs_msg中,使用 struct fstab來表示fstab文件中的數據,使用struct fstab_rec來表示fstab中的每一條記錄。內存

struct fstab {
    int num_entries;			// fstab中的記錄數
    struct fstab_rec* recs;		// fstab中的全部條目
    char* fstab_filename;		// fstab的文件路徑
};

struct fstab_rec {
    char* blk_device;			// 對一個 <src>
    char* mount_point;			// 對應 <mnt_point>
    char* fs_type;				// 對應 <type>
    unsigned long flags;		// 對應 <mnt_flags>
    char* fs_options;			// <mnt_flags>中未記錄在struct flag_list mount_flags中的字段
    int fs_mgr_flags;			// 對應 <fs_mgr_flags>
    // -----------------------------------------------------
    char* key_loc;				
    char* key_dir;
    char* verity_loc;
    long long length;			 // length=
    char* label;				// voldmanaged=sdcard:3  label=sdcard
    int partnum;				// voldmanaged=sdcard:3   partnum = 3  auto partnum = 1
    int swap_prio;				// swapprio=
    int max_comp_streams;
    unsigned int zram_size;
    uint64_t reserved_size;
    unsigned int file_contents_mode;
    unsigned int file_names_mode;
    unsigned int erase_blk_size;
    unsigned int logical_blk_size;
};

struct fstab_rec的前6個,就分別對應fstab中記錄項。後面的就是記錄fs_mgr_flags中的參數的值。

struct fstab_rec->fs_options 比較特殊,其記錄的是 mnt_flags中,未記錄的參數類型。當執行mount的時候,他將直接做爲參數傳遞過去。

static struct flag_list mount_flags[] = {
    { "noatime",    MS_NOATIME },
    { "noexec",     MS_NOEXEC },
    { "nosuid",     MS_NOSUID },
    { "nodev",      MS_NODEV },
    { "nodiratime", MS_NODIRATIME },
    { "ro",         MS_RDONLY },
    { "rw",         0 },
    { "remount",    MS_REMOUNT },
    { "bind",       MS_BIND },
    { "rec",        MS_REC },
    { "unbindable", MS_UNBINDABLE },
    { "private",    MS_PRIVATE },
    { "slave",      MS_SLAVE },
    { "shared",     MS_SHARED },
    { "defaults",   0 },
    { 0,            0 },
};

從fstab文件解析

實際解析過程就是逐行解析,而後分割字符串。沒啥好記錄的,代碼太長就不貼了。能夠看一下解析函數:

static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) {
    // [1] 統計行數
    // [2] 分配 fstab 內存和 fstab_rec 內存
    // [3] 逐行解析
}

從設備樹解析

內核DTS中的配置,最終都會在目錄/proc/device-tree下體現,android也有一些自有配置,其目錄是/proc/device-tree/firmware/android。其中fstab就記錄在該目錄下(完整目錄就是/proc/device-tree/firmware/android/fstab)。

結合前面的 DTS截圖,最終fstab生成的目錄結構以下:

/proc/device-tree/firmware/android/fstab/
    system
    	status
    	dev
    	type
    	mnt_flags
    	fsmgr_flags
    vendor
    	status
    	dev
    	type
    	mnt_flags
    	fsmgr_flags

fs_mgr對其的解析過程就是遍歷/proc/device-tree/firmware/android/fstab/,一次讀取其每一個子目錄的全部節點數據,每一個目錄構建成一個<dev> <mnt_point> <type> <mnt_flags> <fsmgr_flags>\n形式的字符串。而後拼接。

image-20201125125137257

​ 最後,將read_fstab_from_dt返回的字符串轉換成FILE*調用函數fs_mgr_read_fstab_file完成解析。

image-20201125125338130

合併fstab

前面提到fs_mgr會將fstab文件和DTS中的配置信息合併。合併過程也很簡單,就是建立一片內存,將兩個部分的數據拷貝過去。

image-20201125125737739

若是 fstab文件和 DTS 中的 配置項存在重複,fs_mgr 是怎麼處理。

相關文章
相關標籤/搜索