テクノロジー · 実用ガイド

rm が「Operation not permitted」?chmod や chattr の前に unlink boundary を証明する

正確な errno を保存し、parent と inode flag を調べ、sticky、mount、namespace、policy を分け、一原因だけの修復を disposable sibling で検証します。

pathname、parent、inode flag、sticky ownership、mount、capability、policy の順に rm の EPERM を調べるオリジナル図。
オリジナルイラスト:permission や privilege を変える前に unlink boundary を証明します。 Watch at Ease

「Operation not permitted」は unlink boundary の証拠であり、rm にもっと force が必要という証明ではありません。parent directory、immutable/append-only flag、sticky ownership、filesystem rule、namespace capability、security policy が操作を支配している可能性があります。

まず正確な pathname と errno を保存します。変更せずに各 boundary を調べ、証明した原因一つだけを直し、disposable sibling で parent を検証します。削除が明示承認され backup 済みの場合だけ、正確な target を削除します。

1. pathname と本当の errno を固定する

完全な command、正確な stderr、effective user、working directory、namespace を保存します。存在するはずの target は realpath -e で確認し、target と parent の stat を別々に記録します。元の pathname も残します。unlink は directory entry に作用するため、symlink、bind mount、改名された parent で対象が変わります。

すべての “cannot remove” を EPERM と決めつけません。Linux は parent の write/search 不足を EACCES、read-only filesystem を EROFS、mount point や一部 NFS を EBUSY とします。strace が必要なら disposable fixture、または削除が承認・backup 済みの時だけにします。成功する trace は本当に名前を削除します。

2. file mode より先に parent を調べる

namei -l で component を歩き、immediate parent と target を別々に stat します。名前の削除は parent directory を変更します。file 自体を writable にしても directory operation は許可されません。owner、group、mode、ACL を変更せず記録します。

parent に sticky bit があると、effective user が file owner、directory owner、または適切な capability を持たない限り unlink が拒否されます。共有 directory の保護は残し、/tmp などから sticky を外さず、正しい actor または ownership を証明します。

3. target と parent の inode flag を読む

target と parent の両方で lsattr -d -- を実行します。immutable は delete と rename を防ぎ、append-only も unlink を EPERM にできます。全 filesystem が全 flag を支えるわけではないので、unsupported は次の境界を調べる証拠です。

flag が原因と証明されたら、object の owner と設定理由を記録し、正確な object の必要な i または a だけを解除します。CAP_LINUX_IMMUTABLE を持つ host または namespace から行い、recursive chattr や広範な privileged container は使いません。

4. mount、filesystem、policy を分類する

正確な target に findmnt -T を使い、source、filesystem type、options を記録します。read-only mount は EROFS で EPERM とは別です。mount point や NFS silly rename は EBUSY になり得ます。overlay、network、container filesystem には ownership と namespace の境界もあり、古い製品固有 workaround は現在の万能解ではありません。

mode、sticky ownership、inode flag で説明できなければ、ls -lZ、最近の AVC/kernel log、effective capability、該当 container/user namespace を収集します。具体的な policy または owning layer だけを直し、SELinux/AppArmor を全体で無効化したり blanket privileged にしたりしません。

5. 一原因だけ直し acceptance を証明する

証拠に結び付いた可逆な変更を一つだけ行います。意図した parent owner/access の修正、証明した flag 一つの解除、正しい sticky owner での実行、mount/storage layer の修復、特定 security rule の更新です。その後 stat、lsattr、findmnt を再取得します。

実 target の前に、policy が許せば同じ parent に disposable sibling を作成して unlink します。これは parent operation の証明であり、target 削除の承認ではありません。正確な pathname、backup、owner approval を確認して一度だけ削除します。unlink 後も open file は最後の descriptor が閉じるまで inode と data を保持できます。

観察、単一原因の修復、使い捨て sibling probe、承認済み target の削除を分けるオリジナル図。
オリジナルイラスト:診断し、一原因だけ直し、sibling を試してから target を一度だけ削除します。 Watch at Ease