Linux提供 procfs/sysfs
procfs/sysfs フレームワーク
procfs/sysfs フレームワーク アプリケーション
プログラム
McKernel提供 procfs/sysfs Linux
McKernel
mcoverlayファイルシステム mcctrl
(1) open()などによる アクセス
(4) アクセス要求転送
(3) コールバック関数呼び出し mcexec
(2) McKernel提供ファイルまたは Linux提供ファイルへの振り分け
Figure 2.6: procfs/sysfsのアクセス要求転送
mcoverlay upperdir
lowerdir (read-only)
mcoverlay upperdir
lowerdir 対象ファイル
(1) copyup 処理
nocopyupw オプションなし (overlayfs の処理) nocopyupw オプションあり
対象ファイル
対象ファイル
(2) ライト処理 (1) ライト処理
Figure 2.7: nocopyupwオプションの有無によるライト処理の違い
mcoverlayfsのマウントオプションを表??に示す。nocopyupw, nofscheckがoverlayfs
936
に対して追加されたオプションである。
Table 2.5: mcoverlayfsのマウントオプション
オプション 説明
lowerdir=<dirs> lowerdirを指定する。
’:’で区切り複数指定可能(最大500) upperdir=<dir> upperdirを指定する。
workdir=<dir> workdirを指定する。
workdirは、upperdirと同じマウント下のディレクトリでな ければならない。
default permissions デフォルトパーミッションを設定する。
nocopyupw 書 き 込 み 時 に upperdir に ファイ ル を 作 成 し 、そ れ に 対 して書き込みを行う処理(copyup 処理)を無効にする。
procfs/sysfsをlowerdirに指定する際は本オプションを指 定する必要がある。
nofscheck procfs/sysfsをlowerdirに指定可能にする。
937
2.6.1 詳細
938
overlayfsのデータ構造に対する修正は以下の通り。
939
1. ovl opt bit
940
マウントオプションを追加するために、以下のenum及び、マクロを追加する。
941
enum ovl_opt_bit {
942
__OVL_OPT_DEFAULT = 0,
943
__OVL_OPT_NOCOPYUPW = (1 << 0),
944
__OVL_OPT_NOFSCHECK = (1 << 1),
945
};
946 947
#define OVL_OPT_NOCOPYUPW(opt) ((opt) & __OVL_OPT_NOCOPYUPW)
948
#define OVL_OPT_NOFSCHECK(opt) ((opt) & __OVL_OPT_NOFSCHECK)
949
2. ovl d fsdata
950
d fsdataを格納するために、以下の構造体を追加する。
951
struct ovl_d_fsdata {
952
struct list_head list;
953
struct dentry *d;
954
struct ovl_entry *oe;
955
};
956
3. ovl config
957
マウントオプションを追加するために、optを追加する。
958
struct ovl_config {
959
char *lowerdir;
960
char *upperdir;
961
char *workdir;
962
bool default_permissions;
963
unsigned opt; <-- 追加
964
};
965
4. ovl fs
966
d fsdataを格納するために、d fsdata listを追加する。
967
struct ovl_fs {
968
struct vfsmount *upper_mnt;
969
unsigned numlower;
970
struct vfsmount **lower_mnt;
971
struct dentry *workdir;
972
long lower_namelen;
973
/* pathnames of lower and upper dirs, for show_options */
974
struct ovl_config config;
975
struct list_head d_fsdata_list; <-- 追加
976
};
977
5. ovl tokens
978
マウントオプションを追加するために、OPT NOCOPYUPW及び、OPT NOFSCHECK
979
を追加する。
980
enum {
981
OPT_LOWERDIR,
982
OPT_UPPERDIR,
983
OPT_WORKDIR,
984
OPT_DEFAULT_PERMISSIONS,
985
OPT_NOCOPYUPW, <-- 追加
986
OPT_NOFSCHECK, <-- 追加
987
OPT_ERR,
988
};
989 990
static const match_table_t ovl_tokens = {
991
{OPT_LOWERDIR, "lowerdir=%s"},
992
{OPT_UPPERDIR, "upperdir=%s"},
993
{OPT_WORKDIR, "workdir=%s"},
994
{OPT_DEFAULT_PERMISSIONS, "default_permissions"},
995
{OPT_NOCOPYUPW, "nocopyupw"}, <-- 追加
996
{OPT_NOFSCHECK, "nofscheck"}, <-- 追加
997
{OPT_ERR, NULL}
998
};
999
6. ovl fs type
1000
nameの値を”mcoverlay”に変更する。
1001
static struct file_system_type ovl_fs_type = {
1002
.owner = THIS_MODULE,
1003
.name = "mcoverlay", <-- 変更
1004
.mount = ovl_mount,
1005
.kill_sb = kill_anon_super,
1006
};
1007
MODULE_ALIAS_FS("mcoverlay"); <-- 変更
1008
overlayfsに対する関数の修正を表??、表??に示す。
1009
Table 2.6: overlayfsの関数に対する修正(1)
関数 修正内容
ovl copy xattr() OVL OPT NOFSCHECK(opt)が有効の場合、vfs getxattr()のエラーを無視 する。
ovl copy up locked() ovl copy xattr()呼び出し時にovl get config opt()で取得したopt 値を渡す。
ovl clear empty() ovl copy xattr()呼び出し時にovl get config opt()で取得したopt 値を渡す。
ovl setattr() ovl get config opt()でopt値を取得する。
OVL OPT NOCOPYUPW(opt)の場合、処理しない。
ovl permission() ovl reset ovl entry()を呼び出してから処理する。
ovl setxattr() ovl get config opt()でopt値を取得する。
OVL OPT NOCOPYUPW(opt)の場合、処理しない。
ovl removexattr() ovl get config opt()でopt値を取得する。
OVL OPT NOCOPYUPW(opt)の場合、処理しない。
ovl d select inode() 1. ovl get config opt()でopt値を取得する。
2. OVL OPT NOCOPYUPW(opt)の場合、ovl open need copy up()を 呼び出さない。
3. OVL OPT NOFSCHECK(opt)で対象ファイルがsysfsの場合、
ovl find d fsdata()を呼び出してdentryが登録されているか確認 する。登録されていない場合にはovl add d fsdata()を呼び出して 登録し、dentry->d fsdataにrealpath.dentry->d fsdata の値を設定する。
ovl get config opt() opt値を返す。
ovl reset ovl entry() 1. ovl get config opt()でopt値を取得する。
2. OVL OPT NOFSCHECK(opt)の場合、ovl find d fsdata()を呼び出し て、dentryが登録されている場合には取得したd fsdataをoeに 設定する。
ovl find d fsdata() dentry->d sb->s fs infoのd fsdata listに登録されているd fsdata を検索して、dentryが登録されていた場合、dentryのovl entryを戻 す。
ovl add d fsdata() 1. struct ovl d fsdataのメモリ領域を確保して、dentryの登録デー タを設定する。
2. dentry->d sb->s fs infoのd fsdata listに登録する。
ovl clear d fsdata() d fsdata listに登録されている全てのd fsdataを削除して、struct ovl d fsdataのメモリ領域を解放する。
ovl path type()
ovl reset ovl entry()を呼び出してから処理する。
ovl path upper() ovl dentry upper() ovl dentry lower() ovl dentry real() ovl dir cache() ovl set dir cache() ovl path lower() ovl dentry is opaque() ovl dentry set opaque() ovl dentry update() ovl dentry version inc() ovl dentry version get() ovl dentry release() ovl dentry revalidate() ovl dentry weak revalidate()
Table 2.7: overlayfsの関数に対する修正(2)
関数 修正内容
ovl lookup real() OVL OPT NOFSCHECK(opt)の場合、ovl dentry weird()を呼び出さない。
ovl path next() ovl reset ovl entry()を呼び出してから処理する。
ovl lookup() 1. ovl get config opt()でopt値を取得する。
2. ovl reset ovl entry()を呼び出してから処理する。
3. ovl lookup real()を呼び出す際、opt値を渡す。
ovl put super() ovl clear d fsdata()を呼び出してから処理する。
ovl statfs() struct kstatfsのf typeにMCOVERLAYFS SUPER MAGICを設定する。
ovl show options() nocopyupw, nofscheckオプションの説明を追加する。
ovl parse opt() nocopyupw, nofscheckオプションの設定を追加する。
ovl mount dir noesc() OVL OPT NOFSCHECK(opt)の場合、ovl dentry weird()を呼び出さない。
ovl mount dir() ovl mount dir noesc()を呼び出す際、optを渡す。
ovl lower dir() ovl mount dir noesc()を呼び出す際、optを渡す。
ovl fill super() 1. struct ovl fsのd fsdata listを初期化する。
2. ovl mount dir()を呼び出す際、optを渡す。
3. ovl lower dir()を呼び出す際、optを渡す。
4. OVL OPT NOCOPYUPW(opt)の場合、以下の設定を行わない。
• mnt->mnt flags |= MNT READONLY;
• sb->s flags |= MS RDONLY;
2.6.2 実装の制限
1010
McKernelが生成する/proc/[pid]/下のファイルをopenして、closeせずにopenした状態
1011
でexecして、execしたプロセスで同一ファイルをopenするとエラー(ENOENT)となる。原因
1012
は、exec()時には、新たなプロセスの情報を返せるようにするため/proc/[pid]/下のファ
1013
イルを作成し直すが、overlayfsはlowerに指定されるディレクトリ下のファイルのinode番
1014
号が変わった場合、エラーを返すためである。
1015
2.6.3 開発時の留意事項
1016
Linux-4.0からLinux-4.6への移行に際する仮想ファイルシステムの以下の仕様変更に追従す
1017
る必要があった。
1018
1. struct inode operationsのdentry open()が削除されて、struct dentry operations
1019
のd select inode()が追加された。
1020
2. VFSのvfs open()では、dentry open()が呼ばれずに、d select inode()が呼び出
1021
されるようになった。
1022
また、以下のバージョンのLinuxカーネルでのみ動作する。
1023
• 3.10.0-327から3.10.0-693(RHEL-7.2から7.4)
1024
• 4.0.0から4.1.0
1025
• 4.6.0から4.7.0
1026