2013年11月5日火曜日

FUSEの例(archivemount で tgz をマウントしてみる)

とあるAndroidスマホの中を見ていたら、ディレクトリの一部が「fuse」という謎のファイルシステムを使っていることに気がついた。初耳だったので調べてみると、LUKSをもっと手軽にしたようなものらしい(FUSEとLUKSを比較している記事がいくつかみつかった)。

ネットで紹介されているFUSEの利用例はたいていリモートホストのファイルをセキュアにSSHFSとしてマウントするものなので、ここでは矮小というか卑近というか要するにあまり役に立たない例としてローカルホストにあるアーカイブ(tgz)を読み書きする例にした。


1. 環境
Fedora release 19 (Schrödinger’s Cat)
ただし、「archivemount」というパッケージを yum でインストールした。
2. rootで、何でもいいからテキストファイルをつくってアーカイブ化(ファイル名:/root/work.tgz)
[root@localhost ~]# cd
[root@localhost ~]# mkdir work; for i in foo bar baz; do echo $i > work/$i.txt; done
[root@localhost ~]# ll work; cat work/*
total 12
-rw-r--r--. 1 root root 4 Nov  5 01:43 bar.txt
-rw-r--r--. 1 root root 4 Nov  5 01:43 baz.txt
-rw-r--r--. 1 root root 4 Nov  5 01:43 foo.txt
bar
baz
foo
[root@localhost ~]# tar cvzf work.tgz work/
work/
work/bar.txt
work/baz.txt
work/foo.txt
3. 共有用として /var/local/ の下に fuse というディレクトリを作り、/etc/fstab にマウントの設定を追加。
[root@localhost ~]# mkdir -p /var/local/fuse
[root@localhost ~]# cp /etc/fstab{,.orig}
[root@localhost ~]# echo '/root/work.tgz /var/local/fuse fuse.archivemount defaults,allow_other' >> /etc/fstab
この fstab のポイントは、ファイルシステムのタイプを「fuse.archivemount」にすることとオプションに「allow_other」を加えることの二点。
4. fstab の設定にしたがって mount してみる('-a'オプション)
[root@localhost ~]# mount -a
5. マウントされた内容を df と ls で確認
[root@localhost ~]# df
Filesystem               1K-blocks    Used  Available Use% Mounted on
/dev/mapper/fedora-root   28244124 9058868   17743876  34% /
devtmpfs                   1015516       0    1015516   0% /dev
tmpfs                      1022324     148    1022176   1% /dev/shm
tmpfs                      1022324     964    1021360   1% /run
tmpfs                      1022324       0    1022324   0% /sys/fs/cgroup
tmpfs                      1022324    2664    1019660   1% /tmp
/dev/sda1                   487652   83857     378195  19% /boot
archivemount            1048576000       0 1048576000   0% /var/local/fuse
[root@localhost ~]# ll /var/local/fuse/work
total 0
-rw-r--r--. 0 root root 4 Nov  5 01:43 bar.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 baz.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 foo.txt
6. 一般ユーザー(ここでは u1 とする)で、マウントしたディレクトリに読み書きしてみる。
[u1@localhost ~]$ id
uid=1001(u1) gid=1001(u1) groups=1001(u1) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[u1@localhost ~]$ cd /var/local/fuse/work
[u1@localhost work]$ echo hoge > hoge.txt
[u1@localhost work]$ ll
total 0
-rw-r--r--. 0 root root 4 Nov  5 01:43 bar.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 baz.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 foo.txt
-rw-r--r--. 0 root root 5 Nov  5 01:44 hoge.txt
[u1@localhost work]$ vi bar.txt    # ファイル内の文字列「bar」を「bar2」と書き換えるだけ
[u1@localhost work]$ ll
total 0
-rw-r--r--. 0 root root 5 Nov  5 01:44 bar.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 baz.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 foo.txt
-rw-r--r--. 0 root root 5 Nov  5 01:44 hoge.txt
[u1@localhost work]$ rm baz.txt    # ファイルを削除
[u1@localhost work]$ ll
total 0
-rw-r--r--. 0 root root 5 Nov  5 01:44 bar.txt
-rw-r--r--. 0 root root 4 Nov  5 01:43 foo.txt
-rw-r--r--. 0 root root 5 Nov  5 01:44 hoge.txt
7. アンマウントして、アーカイブの中身が変更されているか確認
[root@localhost ~]# umount /var/local/fuse
umount: /var/local/fuse: target is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
[u1@localhost work]$ cd    # u1 の存在で umount が失敗したので cd する
[root@localhost ~]# umount /var/local/fuse
[root@localhost ~]# mv work{,.orig}    # もともとのアーカイブをリネーム
[root@localhost ~]# tar xf work.tgz    # fuse.archivemount 経由で変更したアーカイブを展開
[root@localhost ~]# diff -uwbr work.orig work    # diff をとってみる
diff -uwbr work.orig/bar.txt work/bar.txt
--- work.orig/bar.txt 2013-11-05 01:43:39.096153269 +0900
+++ work/bar.txt 2013-11-05 01:44:38.000000000 +0900
@@ -1 +1 @@
-bar
+bar2
Only in work.orig: baz.txt
Only in work: hoge.txt
差分は期待どおり。これでOK.