zfs diffがはいったのをすっかりわすれてたので、あわててためしてみた。
とりあえずつかいかたをみる
% zfs diff must provide at least one snapshot name usage: diff [-FHt] <snapshot> [snapshot|filesystem] For the property list, run: zfs set|get For the delegated permission list, run: zfs allow|unallow
スナップショットは1つは指定しないとだめってことか。
usageの最後にpropertyとpermissionの記述がくっついてるのを不思議におもったが、/usr/src/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c:usage()をみたら、とりあえず全部のヘルプにくっつけてるんだな。これまで気にしてなかった。
とりあえず動かしてみる。
% zfs diff tank/home/koie Badly formed snapshot name tank/home/koie: missing '@' delimiter in snapshot name
おっとファイルシステムを指定したら文句をいわれた。ちゃんとusageよめよ>俺
% zfs diff tank/home/koie@__hour-01 The diff delegated permission is needed in order to create a just-in-time snapshot for diffing : unable to generate diffs
1引数だと/usr/src/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_diff.c:make_temp_snapshot()でスナップショットをとるみたいだ。ライブファイルシステムとスナップショットのdiffはスナップショット間のdiffにおとしこまれるようだ。スナップショットの作成コストが軽いからできるワザだな。それにしてもエラーメッセージの最後の行がくさっとる。
ちなみにzfs diff中にzfs list -t snapshot -r tank/home/koieしてみたら tank/home/koie@zfs-diff-55659-000000009f26d0d5 というスナップショットが作られてた。ソースコードをみると最初の数字はPIDなのはわかったが、後の方はわからんかった。
% zfs diff tank/home/koie@__hour-01 tank/home/koie@_hour-02 Unable to obtain diffs: そのようなファイルまたはディレクトリはありません
第2引数をタイポしたら不親切なメッセージがでた。
うちなおし。
% zfs diff tank/home/koie@__hour-01 tank/home/koie@__hour-02 Unable to obtain diffs: The sys_mount privilege or diff delegated permission is needed to execute the diff ioctl
特権が必要なようだ。あるいはzfs allowで許可しておくかどちらか。
% sudo zfs diff tank/home/koie@__hour-01 tank/home/koie@__hour-02 Password: M /home/koie/ M /home/koie/Mail M /home/koie/Mail/trash/.mew-mtime ... - /home/koie/MailDB/id.db - /home/koie/.recentf.~2197~ ... R /home/koie/.recentf -> /home/koie/.recentf.~2198~ + /home/koie/MailDB/id.db ... + /home/koie/.recentf ...
libzfs_diff.cをみると先頭の文字は以下のようになっている:
+ | ADD |
M | MODIFIED |
- | REMOVED |
R | RENAMED |
ファイルシステムレベルでおいかけてるから、MODIFIEDなのかREMOVED+ADDなのかを区別できているな。ファイルを書き換えたなら"M"、一旦unlinkしてから作り直したら"-"と"+"がでる。上の例でいうとid.dbがそう。
man zfsしてもzfs diffの記述がまだないので/usr/src/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c:zfs_do_diff()をみると、オプションはこうなってた:
-F | ZFS_DIFF_CLASSIFY | ファイルタイプを表示 |
-H | ZFS_DIFF_PARSEABLE | renameで" -> "のかわりに"\t"をつかう |
-t | ZFS_DIFF_TIMESTAMP | 時刻も表示 |
ファイルタイプは以下のとおり
B | S_IFBLK |
C | S_IFCHR |
/ | S_IFDIR |
> | S_IFDOOR |
| | S_IFIFO |
@ | S_IFLNK |
P | S_IFPORT |
= | S_IFSOCK |
F | S_IFREG |
? | そのほか |
引数の1番目は "@〜" と書けるようだ。そのときは2番目の引数は必須で、つかいかたはたぶんこんなかんじ:
% sudo zfs diff @__hour-14 tank/home/koie
べんりじゃな。libzfs_diff.c:get_snapshot_names()をみると、そのほかにもいろいろなバリエーションがあるようだ:
/* * Can accept * dataset@snap1 * dataset@snap1 dataset@snap2 * dataset@snap1 @snap2 * dataset@snap1 dataset * @snap1 dataset@snap2 */
そんなところでおしまい。