1. kawaz

    No comment

    kawaz
Changes in body
Source | HTML | Preview

Linuxの主要なファイルシステムでは拡張ファイル属性というものがサポートされている。これはファイル名やファイルサイズやファイルの中身とは別に、任意の属性名で任意の値をファイルに付けられるものです。

拡張属性の基本的な使い方

拡張属性の操作には attr, getfattr, setfattr というコマンドを使うのが一番基本的なやり方になります。これは attr というパッケージに入っているので、無ければ yum install attr とかすれば入れられます。
で、例えばこんなふうに使います。

# 適当にファイルを作って
$ touch file1

# 適当に拡張属性を付けてみる
$ setfattr -n user.foo -v bar file1
$ setfattr -n user.aaa -v AAA file1

# 拡張属性名を指定して値を取得したり
$ getfattr -n user.foo file1
# file: file1
user.foo="bar"

# 拡張属性名をマッチングで一覧したりも出来る
getfattr -m .\* file1
# file: file1
user.aaa
user.foo

# 削除は名前指定で1個ずつ行う
$ setfattr -x user.foo
$ setfattr -x user.aaa

こんなふうに沢山拡張属性を付けてもファイル自体のサイズは一切替わりません。

拡張属性には名前空間というのがあって、頭に user. とついているのがその一つで、種類は以下の通り全部で4つあります。

  • user (ユーザ空間でユーザが好きな名前で好きに使える場所)
  • trusted (ユーザ空間の一種?実行プロセス制限付き)
  • system (システムがアクセス制御とかに使う用)
  • security (SELinuxやcapabilityの付与に使われる)

拡張属性をまとめて全部削除したい

で、ここが本題です。

GlusterFS とかを使ってると拡張属性がバリバリに使われていて trusted.gluster* とか trusted.afr.* とかの拡張属性が全ファイルに数個〜10個ずつくらいついてきたりします。まぁそれは必要があって付いてるものなんで構わないんです。
ですが、ある日 GlusterFS をやめて普通のディスクとして使いたいなー、しかも GlusterFS 内にあったファイルはそのまま使いたいなー、となったとします。
そういう場合は別にブリックフォルダをGlusterにマウントしないだけで、そのまま使ってても全然構わないし、逆にそのまま使えちゃうのって凄い便利で安心だよねーというのがGlusterFSのポイントでもあるんですが、やっぱり気持ち悪いので大量についた拡張属性を掃除したくなるわけです。

そんなとき、setfattr -x -m .\* file1 とかいう風に1ファイルに対して全ての全マッチングした拡張属性名を全部一発で消せたら嬉しいんだけど、そういうオプションはないみたいです。なのでまず getfattr -m .\* とかで拡張属性名一覧を取得して、それを1個ずつ指定して削除という感じでクリーニングしてくことになります。当全面等臭いので関数化しておくと便利です。

rmxattr.sh
#!/bin/bash
rmxattr() {
  local p a
  for p in "$@"; do
    getfattr -m .\* "$p" |
    while read -r a; do
      [[ -z $a ]] && continue
      [[ $a == \#* ]] && continue
      setfattr -x "$a" "$p"
    done
  done
}
if [[ ${BASH_SOURCE[0]} != "$0" ]]; then
  rmxattr "$@"
fi

これを source するか直接実行するかで rmxattr file [[..files]] としてやればそのファイルについてる拡張属性が全部消せます。ちょっと楽になった。
あとはまーさらにこれを find で回してやればディレクトリを再帰的に巡回してやれば、元GlusterFSのブリックなディレクトリが普通のファイルシステムに戻せたりします。

おわり。