Help us understand the problem. What is going on with this article?

cpとmvとinodeの話

More than 3 years have passed since last update.

実行中のファイルに対して、
cpで上書きする場合だと、Text file busyで置き換えられず、
mvだと何も聞かれず置き換えられます。

この挙動の違いについて、まとめと実験。

inodeを見ると、それとなく分かります。

https://ja.wikipedia.org/wiki/Inode

以下引用

リンクを全く持たない inode もありうる。
通常そのようなファイルはディスクから削除され、
そのリソース(ディスクブロック)はファイル削除処理の過程で
再利用のために解放されるが、何らかのプロセスが
そのファイルを使用中ならば、アクセスし続けることができ、
最後にクローズされるときに削除処理が行われる。

このため、プログラムを改版(リコンパイル)するときは、
以前の実行ファイルをまず削除して、新しい版の実行ファイルは
新たな inode で作成されるようにすることが推奨される。
これにより、古い版が実行中であっても何ら問題なく処理を続行することになる。

(訳注:削除しないで上書きすると、実行中の実行ファイルが書き換えられるため、
メモリ管理の実装によってはおかしな状態が発生する)。

引用終わり

つまり、
以下のファイルがあるとして。

・/sa/sbin/org_exec inode=100 inodeの中身=abc
・/sa/sbin/new_exec inode=200 inodeの中身=123

cp /sa/sbin/new_exec /sa/sbin/org_exec

とした場合、inode=100の内容を、
inode=200の内容で上書きするので、
以下のようになる。

・/sa/sbin/org_exec inode=100 inodeの中身=123
・/sa/sbin/new_exec inode=200 inodeの中身=123

org_execを使っている人は、突然abcが123になって、
なんぞ?っとなる。そしてcpコマンドは、こうなるとまずいので、
Text file busyを出して、失敗にする。

mv /sa/sbin/new_exec /sa/sbin/org_exec

とした場合、/sa/sbin/org_exec inode=200となり、
inode=100は、何もファイルパスを指さない状態となるだけになる。

・ファイルパスは無い inode=100 inodeの中身=abc
・/sa/sbin/org_exec inode=200 inodeの中身=123
・/sa/sbin/new_execは無くなった状態になる(org_execにmvしているので)

inode=100はファイルパスはなくなるが、inodeの中身は変わっていないので、
現状誰かが使用していたとしても、問題なくabc、という中身を見ることができる。
なので、実行中のファイルに、別のファイルをmvしても問題ないので、
mvは成功する。

そして、inode=100の内容は、それを使っているプロセスが
ファイルをクローズすれば再利用可能な状態に戻る。

以下、実際にやってみた結果。
cpだとエラーがでて失敗し、
mvは成功している。

mvはinodeの内容自体は変えず、
inodeとファイルパスの関連を変えているだけ、
というのが分かるはず。

そしてmvした後も、a.exeは動き続けている。
ただしこれは、mvする前の状態のa.exeである点に
注意が必要。

[root@localhost ~]#
[root@localhost ~]# stat a.exe
File: a.exe'
Size: 6777 Blocks: 16 IO Block: 4096 regular file
Device: 802h/2050d Inode: 790530 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-09-09 13:14:19.642295609 +0900
Modify: 2015-09-09 13:14:18.178283786 +0900
Change: 2015-09-09 13:14:18.178283786 +0900
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# stat b.exe
File:
b.exe'
Size: 6800 Blocks: 16 IO Block: 4096 regular file
Device: 802h/2050d Inode: 790537 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-09-09 13:16:20.022259845 +0900
Modify: 2015-09-09 13:16:17.200237245 +0900
Change: 2015-09-09 13:16:17.200237245 +0900
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# ./a.exe &
[1] 21205
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# cp b.exe a.exe
cp: overwrite a.exe'? y
cp: cannot create regular file
a.exe': Text file busy
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# mv b.exe a.exe
mv: overwrite a.exe'? y
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# stat a.exe
File:
a.exe'
Size: 6800 Blocks: 16 IO Block: 4096 regular file
Device: 802h/2050d Inode: 790537 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-09-09 13:16:20.022259845 +0900
Modify: 2015-09-09 13:16:17.200237245 +0900
Change: 2015-09-09 13:17:12.565688924 +0900
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# ps aux | grep a.exe
root 21205 0.0 0.0 11736 828 pts/0 S 13:16 0:00 ./a.exe
root 31922 0.0 0.0 103304 884 pts/0 S+ 13:54 0:00 grep a.exe

間違い等あれば、指摘ください。。

todanano
C、C++、postgresql、php、perl、sh、その他Linux関連をあれこれ触っています。
http://www.example.com/%E6%8C%81%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした