Linuxでファイルのメタデータを確認する方法の実務上の結論は「owner・mode・size・inode・timestampsはstat、ACLはgetfacl、extended attributeはgetfattrで分けて取得します。content hashとmetadataを別項目で記録します。」です。metadata inventoryはstatだけで完結せず、content hash、ACL、xattrを別層として取得します。属性が存在しない状態と、toolや権限のため読めない状態を同じ空欄にしません。
metadataを層ごとに確認する
file metadataには種別、device/inode、link数、owner/group、mode、size、atime/mtime/ctime/birth time、ACL、extended attributeなど複数の層があります。stat一回で全てを取得できるわけではなく、security labelやcapabilityもxattrに格納される場合があります。目的に必要な層を決め、内容hashとmetadataを同じものとして扱いません。
statで基本属性、getfaclでaccess/default ACL、getfattr -dで許可されたextended attributeを確認します。getfaclのeffective権限はACL maskの影響を受け、表示されたnamed entryだけで実効権限を判断できません。symbolic link自体と参照先の取得方法、filesystemごとのxattr namespace対応を先に確認します。
statで足りないACL・xattr層を列挙する
- 必要なmetadata項目と時刻精度を定義する
- symbolic link自身か参照先かを決める
- ACLとxattrの有無を確認する
- backup/transferが保持すべき属性を決める
対象filesystemがACLやxattrを支えるか、必要toolが存在するかを先に確認します。device・inodeが途中で変わった時は採取を止め、同じpath名の別fileを混在させずsnapshotから再開します。
基本属性・hash・ACL・xattrを別recordで採る
主要metadataを一行表示
stat --format='%n|%F|%s|%U|%G|%a|%i|%h|%x|%y|%z|%w' -- ./document.txt
delimiterを含むfile名に注意し、機械連携ではNUL等の設計を検討します。
content hashを別取得
sha256sum -- ./document.txt
metadataの一致とcontent byte列の一致を分けて記録します。
ACLを確認
getfacl --absolute-names -- ./document.txt
named entryとmaskによるeffective権限を確認します。
extended attributeを確認
getfattr -d -m- -- ./document.txt
security labelやuser attributeが含まれる場合の共有範囲を制限します。
symbolic link文字列を読む
stat --format='%N %F' -- ./current
readlink -- ./current
link自身と参照先fileのmetadataを混同しません。
stat・getfacl・getfattrの読み分け
statはfilesystem objectのmode、owner、size、inode、link数、timestamps等を返します。ACLやxattrは別interfaceで、statだけでは完全なaccess controlを表せません。ctimeは作成時刻ではなくstatus change、birthtimeは未対応なら不明です。hashはcontentを表しmetadataを含みません。
ctimeはmetadataが変わった時刻で、creation timeという意味ではありません。birth timeはunsupportedなら値がない場合があります。modeのgroup bitsとACL maskの関係、default ACLが新規childへ継承される点を分けます。getfattrでsecurity.*が権限不足により見えない場合、attributeが不存在と断定せず、stderrと実行権限を記録します。
parent directoryのsearch権限不足、ACL読取り権限、xattr namespace制限、unsupported filesystem、NFS mapping、raceによるinode置換を別statusにします。getfaclやgetfattrの空出力を『metadataなし』へ短絡せず、command statusとtoolのavailabilityを確認します。copy後にownerだけ合ってもACLやxattrが落ちていれば完全な保持ではありません。
属性なしと取得不能を同じ空出力にしない
- statだけで全metadataを取得できると思う
- ctimeをcreation timeと誤記する
- content hash一致をpermission一致とする
- symlinkと参照先を同一recordにする
- copy/zipがACLやxattrを必ず保持すると仮定する
getfacl/getfattrの空結果は「属性なし」とは限りません。unsupported、permission denied、command missingをstatusへ残し、chmodやsetfaclで読める状態へ変えず、権限所有者に再収集を依頼します。
chmodやsetfaclなしでsecurity metadataを読む
今回は読み取りのみとし、chmod、chown、setfacl、setfattr、touchを実行しません。metadata dumpにはuser名、security label、内部pathが含まれるため保管権限を限定します。復元testはcopyで行い、正本へ上書きしません。
診断ではchmod、chown、setfacl、setfattrを実行しません。security labelやcapabilityはservice起動と権限境界へ影響するため、空にして試すことも避けます。収集結果にはowner名やsecurity属性が含まれるので保存先を制限します。修復が必要なら対象filesystemで保持可能なbackupと復元testを準備して別承認にします。
保持と復元をsampleで検証する
regular file、directory、hard link、symlink、ACL/xattr付きsampleを用意します。copy/archive/restore前後でstat、hash、ACL、xattrを比較し、保持しない項目と復元方法を記録します。
通常file、directory、hard link、symbolic link、access ACL、default ACL、user xattrを持つtest treeを用意します。stat、getfacl、getfattrの結果をdevice/inode単位で保存し、metadata保持optionを使ったtest copyとrestore後に差分比較します。内容hash、mode、ACL mask、xattr名と値を別々に照合し、unsupported項目を明示します。
device・inodeをkeyにmetadata inventoryを作る
inventoryではpathだけでなくdevice、inode、file type、uid/gid数値、mode、timestamp、ACL/xattr取得statusを列化します。人向け整形を固定文字列parseせず、tool versionとlocaleを固定します。走査前後にinodeとctimeを再取得し、途中置換を検知します。取得不能を空objectへ変換せず、unsupportedとpermission errorを別codeで残します。
migrationで保持すべき属性をtool別に決める
単純な所有者・時刻確認はstat、共有権限の調査はgetfacl、application/security付加情報はgetfattrを使います。migrationやbackupでは利用toolがACL、xattr、hard link、sparse、ownerをどこまで保持するか実測します。完全性の証明には内容hashとmanifestの真正性も必要で、metadata一覧だけでは改ざん有無を確定できません。
合格はACLあり・なし、xattrあり・なし、読取不可fixtureで存在と取得可否を別fieldにできることです。device・inode不一致のrecordは結合せず、対象を固定して取り直します。

コメント