unix

killできれいに死ぬシェルスクリプト

止めるまで動きつづける統計値を延々と出力するようなプログラムの出力を加工するスクリプトというのがあるとする。

たとえばeth0のトラフィックをkB/sを表示するもの:

[sar.sh]
#!/bin/sh
/usr/bin/sar -n DEV 1 | awk '$2=="eth0"{print $6,$5}'

で、これをつかってあるプログラムを実行したときのトラフィックを記録したいとする。

[test.sh]
#!/bin/sh
./sar.sh >sar.out &
pid_sar=$!

long_program

kill $pid_sar
cat sar.out

プログラムの実行が終わったらkillしているのだが、シェルが終了するだけでsarやawkは動いたままになる。

シェルは死ぬときにバックグラウンドのプロセスをkillしてはくれないのだ。

コマンドラインから ./sar.sh を直接実行した場合はシェル(/bin/sh ./sar.sh)だけでなくsarもawkも終了するのは、Ctrl-Cを押したときに端末ドライバ(tty)がフォアグラウンドプロセスグループに対してSIGINTを送ってくれるためだ。UNIXは今となっては無駄に端末まわりの機能が豊富なのだ。プロセスグループをつくってくれるのはコマンドラインを解釈しているログインシェルである。

スクリプト1の中からスクリプト2を実行した場合にスクリプト2がきれいに終了するには、そういうふうにシェルスクリプトを書けばよいとおもうところだが、pipeでつないでいるので個別のプログラムのpidがわからないという問題が。

ということで、一番簡単なプロセスグループをつくってしまえばokという解決方法をとることにした。

こんなかんじで自分をプロセスグループリーダにしてプロセスグループをつくる。

[setpgid.c]
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int
main(int ac, char **av)
{
        char *prog = av[0];
        if (ac < 2)
                return 1;
        if (setpgid(0, 0) < 0) {
                fprintf(stderr, "%s:setpgid:%s\n", prog, strerror(errno));
                return 1;
        }
        execvp(av[1], av+1);
        fprintf(stderr, "%s:exec:%s\n", prog, strerror(errno));
        return 1;
}

つかいかたはこんかかんじ。コマンドを起動するときにsetpgidをはさむのと、killするときにプロセスグループにシグナルを送るためにpidにマイナスをつける。

[test.sh]
#!/bin/sh
./setpgid ./sar.sh >sar.out &
pid_sar=$!

long_program

kill -TERM -$pid_sar
cat sar.out

でもいちいち呼出側にsetpgidを入れてまわるのは頭わるいのでshebangに入れる。

[sar.sh]
#!./setpgid /bin/sh
/usr/bin/sar -n DEV 1 | awk '$2=="eth0"{print $6,$5}'
[test.sh]
#!/bin/sh
./sar.sh >sar.out &
pid_sar=$!

long_program

kill -TERM -$pid_sar
cat sar.out

プロセスグループにシグナルを送るのは自分でやるならシグナルをつかまえて自分のプロセスグループにシグナルを送りなおせばいいはず。

[sar.sh]
#!./setpgid /bin/sh
die() {
        echo "bye"
        trap - TERM INT
        kill -TERM -$$
}
trap die TERM INT
/usr/bin/sar -n DEV 1 | awk '$2=="eth0"{print $6,$5}'

とおもってやってみるとシェルがシグナルをうけとっても、シェルレベルのシグナルハンドラを実行してくれない。どうもシェル依存のようだ。バックグランドで実行してwaitで待てばシグナルハンドラを実行してくれるようだが、POSIX規格で決まっているわけではないので絶対安全というわけではないらしい。

#!./setpgid /bin/sh
die() {
        echo "bye"
        trap - TERM INT
        kill -TERM -$$
}
trap die TERM INT
/usr/bin/sar -n DEV 1 | awk '$2=="eth0"{print $6,$5}' & wait

とりあえずの妥協点としてはこんなところか。

http://togetter.com/li/942376

koie

autoconfで構造体のサイズを調べる方法

他言語からCのライブラリのラッパーを実装するときに、構造体の大きさを知りたいということは、ちょくちょくあるとおもう。

configure.ac

AC_PREREQ(2.59)
AC_INIT([oreore], [0.1], [info@example.com])
AC_CONFIG_HEADERS([config.h])
AC_CHECK_SIZEOF([pthread_mutex_t], [], [#include <pthread.h>])
AC_SUBST([HOGE], [$ac_cv_sizeof_pthread_mutex_t])
AC_CONFIG_FILES([boke.txt])
AC_OUTPUT

config.h.in

#undef SIZEOF_PTHREAD_MUTEX_T

boke.txt.in

sizeof pthread_mutex_t is @HOGE@.

実行例

% autoconf
% ./configure
checking for gcc... no
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether cc accepts -g... yes
checking for cc option to accept ISO C89... none needed
checking size of pthread_mutex_t... 8
configure: creating ./config.status
config.status: creating boke.txt
config.status: creating config.h
% cat config.h
/* config.h.  Generated from config.h.in by configure.  */
#define SIZEOF_PTHREAD_MUTEX_T 8
% cat boke.txt
sizeof pthread_mutex_t is 8.
%

koie

シェルスクリプトで一時的代入の挙動(2)

ここからの続き

name=value command 構文

commandのところをいろいろ変えて、コマンド行での変数代入が永続的かどうか調べてみた。

  • nullコマンド(built-in)
  • trueコマンド(freebsd shとdashではbuilt-in、bashでは外部コマンド→うそでしたbuilt-inでした)
  • ユーザ定義関数
  • 外部コマンド
テストスクリプト
X1=YES :
echo "X1=${X1-NO}"
printenv X1

X2=YES true
echo "X2=${X2-NO}"
printenv X2

g() {
    :
}
X3=YES g
echo "X3=${X3-NO}"
printenv X3

X4=YES cal >/dev/null
echo "X4=${X4-NO}"
printenv X4

f() {
    X=FUNC
}
X=CMD f
echo "X=${X-NO}"
printenv X
fbsd sh
X1=YES
X2=NO
X3=NO
X4=NO
X=NO
bash
X1=NO
X2=NO
X3=NO
X4=NO
X=NO
bash -o posix
X1=YES
YES
X2=NO
X3=YES
YES
X4=NO
X=FUNC
FUNC
dash
X1=YES
X2=NO
X3=YES
X4=NO
X=FUNC
結果

永続的か?

Shell nullコマンド 関数 trueコマンド 外部コマンド
fbsd sh YES NO NO NO
bash NO NO NO NO
bash -o posix YES+環境変数 YES+環境変数 NO NO
dash YES YES NO NO

コマンド行の代入と呼ばれた関数内での代入の競合は?

Shell 結果
fbsd sh 永続的でない
bash 永続的でない
bash -o posix 永続的+環境変数
dash 永続的

koie

シェルスクリプトで一時的代入の挙動

シュルスクリプトで、コマンドの前に代入を書くとコマンドを実行するときに一時的にシェル変数と環境変数を設定できて便利。

よくある用法

readで空白も読みたいときにIFS=""を指定する場合に

echo "*** WITHOUT IFS="
cal | while read X; do
    echo "$X"
done

echo "*** WITH IFS="
cal | while IFS= read X; do
    echo "$X"
done

実行結果

*** WITHOUT IFS=
September 2015
Su Mo Tu We Th Fr Sa
1  2  3  4  5
6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

*** WITH IFS=
   September 2015
Su Mo Tu We Th Fr Sa
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

てっきりこの代入は一時的だとおもっていたのだが、呼ばれるコマンドがシェル関数かコマンドかで挙動が違うらしい。


http://tiswww.case.edu/php/chet/bash/POSIX

31. Assignment statements preceding shell function calls persist in the
    shell environment after the function returns, as if a POSIX
    special builtin command had been executed.


試した環境
  • FreeBSD /bin/sh
  • CentOS /bin/dash
  • bash
  • bash -o posix
テストスクリプト
f() {
    echo "$X"
    /usr/bin/printenv X
}
g() {
    X="$X.g1" f
    X="$X.g2" f
}
h() {
    X="$X.h1" g
    X="$X.h2" g
}
X=m1 h
X="$X.m2" h
sh
m1.h1.g1
m1.h1.g2
m1.h2.g1
m1.h2.g2
.m2.h1.g1
.m2.h1.g2
.m2.h2.g1
.m2.h2.g2
dash
m1.h1.g1
m1.h1.g1.g2
m1.h1.g1.g2.h2.g1
m1.h1.g1.g2.h2.g1.g2
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1.g2
bash
m1.h1.g1
m1.h1.g1
m1.h1.g2
m1.h1.g2
m1.h2.g1
m1.h2.g1
m1.h2.g2
m1.h2.g2
.m2.h1.g1
.m2.h1.g1
.m2.h1.g2
.m2.h1.g2
.m2.h2.g1
.m2.h2.g1
.m2.h2.g2
.m2.h2.g2
bash -o posix
m1.h1.g1
m1.h1.g1
m1.h1.g1.g2
m1.h1.g1.g2
m1.h1.g1.g2.h2.g1
m1.h1.g1.g2.h2.g1
m1.h1.g1.g2.h2.g1.g2
m1.h1.g1.g2.h2.g1.g2
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1.g2
m1.h1.g1.g2.h2.g1.g2.m2.h1.g1.g2.h2.g1.g2

まとめると

Shell 一時的か? 環境変数か?
fbsd sh Yes No
dash No No
bash Yes Yes
bash -o posix No Yes

続く

koie

sshでリモートログインしてlsするまで

                          _____________
                         |             |
     ____________        | xterm       |           
    |            |       |__________   |           
    | Xserver    |       |          |  |           
    |_________   |       | Xtoolkit |  |     ________        ________    _______  fork  _______ 
    |         |  |       |----------|  |    |        |      |        |  |       | exec |       |
    | xdriver |  |       | Xlib     |  |    | ssh    |      | sshd   |  | shell |----->| ls    |
    |_________|__|       |__________|__|    |________|      |________|  |_______|      |_______|
    |            |       |             |    |        |      |        |  |       |      |       |
    | libc       |       | libc        |    | libc   |      | libc   |  | libc  |      | libc  |
    |____________|       |_____________|    |________|      |________|  |_______|      |_______|
      |        |            |        |         |  |            |  |         |            |  |
USER  |        |            |        |         |  |            |  |         |            |  |
______|________|____________|________|_________|__|____________|__|_________|____________|__|__________
      |        |            |        |         |  |            |  |         |            |  |       
KERN  |        |   event    |        |   "ls"  |  |   "xxx"    |  |  "ls"   |____________|  |       
      |        |  --------> |        | ------> |  |  ------->  |  | ------> |   <------     |readdir
      |        +--(socket)--+        +--(pty)--+  +--(socket)--+  +--(pty)--+    "core"     |       
    [driver]      <-------             <------       <-------       <------                 |       
      |            request              "core"        "yyy"          "core"            [FileSystem] 
      |          X protocol                        SSH protocol                             |
      |                                                                                     |
______|_____________________________________________________________________________________|__________
     _|_____                                                                             ___|___
HW  |       |                                                                           |       |
    | KBD   |                                                                           | disk  |
    | Mouse |                                                                           |_______|
    | Video |
    |_______|

koie

printfして画面に文字がでるまで

            _______________
           |               |   _______________
           | xterm         |  |               |
           |     __________|  | Xserver       |
           |    |          |  |               |
 _______   |    | Xtoolkit |  |      _________|
|       |  |    |----------|  |     |         |
| a.out |  |    | Xlib     |  |     | xdriver |
|_______|  |____|__________|  |_____|_________|
|       |  |               |  |               |
| libc  |  | libc          |  | libc          |
|_______|  |_______________|  |_______________|     USER
    |        |         |         |      |  |
____|________|_________|_________|______|__|_______
    |        |         |         |      |  |
 ___|________|___   ___|_________|___   |  |
|                | |                 |  | [drv?]
|  pty           | |  IPC(socket)    |  |  |
|________________| |_________________|[drv]|
                                        |  |        KERN
________________________________________|__|_______
                              __________|  |
                        _____|_____     ___|___
                       |           |   |       |
                       | KBD/Mouse |   | Video |
                       |___________|   |_______|    HW
___________________________________________________

koie

無名ファイル(3)

カレントディレクトリを消す実験でシェルから実行するとシェルが何をしているかわからないのでopenしているかもしれない。なのでテストプログラムを組んで実験してみた。

koie@guriandgura% df .
Filesystem  1024-blocks   Used  Avail Capacity  Mounted on
/dev/ad4s2a      507630 352518 114502    75%    /
koie@guriandgura% uname -sr
FreeBSD 9.0-CURRENT
koie@guriandgura% cat -n foo.c
     1  #include <stdio.h>
     2  #include <sys/types.h>
     3  #include <dirent.h>
     4  #include <sys/stat.h>
     5
     6  static void
     7  ls_file(const char* path)
     8  {
     9      struct stat st;
    10      lstat(path, &st);
    11      printf("%-10s ino=%ld nlink=%ld\n", path, st.st_ino, st.st_nlink);
    12  }
    13
    14  static void
    15  ls_dir(const char* path)
    16  {
    17      DIR* dp = opendir(path);
    18      if (dp == NULL) {
    19          perror("opendir");
    20          return;
    21      }
    22      printf("ls %s {\n", path);
    23      struct dirent *dep;
    24      while ((dep = readdir(dp)) != NULL) {
    25          char fn[100];
    26          snprintf(fn, sizeof fn, "%s/%s", path, dep->d_name);
    27          ls_file(fn);
    28      }
    29      closedir(dp);
    30      printf("}\n");
    31  }
    32
    33  int
    34  main()
    35  {
    36      int rc;
    37      if (mkdir("d", 0777) < 0) {
    38          perror("mkdir");
    39          return 1;
    40      }
    41      if (chdir("d") < 0) {
    42          perror("chdir");
    43          return 1;
    44      }
    45      ls_dir(".");
    46      if (rmdir(".", 0777) < 0) {
    47          perror("rmdir");
    48          printf("keep going.\n");
    49      }
    50      if (rmdir("../d", 0777) < 0) {
    51          perror("rmdir");
    52          return 1;
    53      }
    54      ls_dir(".");
    55      ls_file(".");
    56      return 0;
    57  }
koie@guriandgura% cc foo.c
koie@guriandgura% ./a.out
ls . {
./.        ino=33552 nlink=2
./..       ino=33544 nlink=3
}
rmdir: Invalid argument
keep going.
ls . {
}
.          ino=33552 nlink=0
koie@guriandgura%
$ uname -sr
Linux 2.6.18-194.32.1.el5
$ cc foo.c
$ uname -sr
Linux 2.6.18-194.32.1.el5
$ ./a.out
ls . {
./..       ino=64225281 nlink=4
./.        ino=64225284 nlink=2
}
rmdir: Invalid argument
keep going.
ls . {
}
.          ino=64225284 nlink=0
$

この結果からすると、ディレクトリのデータ部分(つまりディレクトリエントリ)は消えているが、ディレクトリ自身(=ディレクトリのメタデータ=inode)は消えてなくて、おそらくlookupで"."が特別扱いされいるためにディレクトリエントリを参照することなくカレントディレクトリを返しているのではないだろうか。

#正直なところおっさんにはカーネルソースを読む気力はすでにない。

無名ファイル(2)

2つopenしたときにリンクカウントがどうなるか試してみた。

FreeBSD UFS2の場合:

koie@guriandgura% uname -sr
FreeBSD 9.0-CURRENT
koie@guriandgura% cat -n test.sh
     1  #!/bin/sh
     2  mkdir d || exit 1
     3  cd d || exit 1
     4
     5  touch file
     6
     7  sleep 10 >>file &
     8  sleep 1
     9  ls -li file
    10
    11  sleep 10 >>file &
    12  sleep 1
    13  ls -li file
    14
    15  wait
    16
    17  cd .. || exit 1
    18  rm -r d

koie@guriandgura% sh -x test.sh
+ mkdir d
+ cd d
+ touch file
+ sleep 10
+ sleep 1
+ ls -li file
33552 -rw-r--r--  1 koie  wheel  0  2月 18 00:26 file
+ sleep 10
+ sleep 1
+ ls -li file
33552 -rw-r--r--  1 koie  wheel  0  2月 18 00:26 file
+ wait
+ cd ..
+ rm -r d
koie@guriandgura%

Linux ext3の場合:

$ uname -sr
Linux 2.6.18-164.11.1.el5
$ sh -x test.sh
+ mkdir d
+ cd d
+ touch file
+ sleep 10
+ sleep 1
+ ls -li file
19170211 -rw-rw-r-- 1 koie koie 0 Feb 18 00:33 file
+ sleep 10
+ sleep 1
+ ls -li file
19170211 -rw-rw-r-- 1 koie koie 0 Feb 18 00:33 file
+ wait
+ cd ..
+ rm -r d
$

2つopenしたからといってリンクカウントが3にはならず1のまま。もしopen/closeのたびにリンクカウントを更新したとするとinodeのアップデートが頻発してパフォーマンスに問題がでるだろう。可能性としてはatime/mtimeのようにすぐに更新しないという戦略で逃げているかもしれない。

inodeを消すかはdinodeのlinkcountとvnodeのrefcountが両方0になったときだと予想。

$ mkdir d
$ ls -lid d
19170210 drwxrwxr-x 2 koie koie 4096 Feb 18 00:42 d/
$ cd d
$ ls -lid .
19170210 drwxrwxr-x 2 koie koie 4096 Feb 18 00:42 ./
$ rmdir .
rmdir: .: Invalid argument
$ rmdir ../d
$ ls -lid .
19170210 drwxrwxr-x 0 koie koie 0 Feb 18 00:42 ./
$

リンクカウント0のディクトリができて、参照できることからinodeは消されてないことがわかる。

名無ファイル

unixでファイルをつくってからrmするとどうなるかテスト。OSはFreeBSDでファイルシステムはUFS2。

前準備で空っぽなファイルbokeをつくる。

catコマンドをバックグラウンドで実行してオープンした状態を維持する。

guriandgura# df /
Filesystem  1K-blocks   Used  Avail Capacity  Mounted on
/dev/ad4s2a    507630 352502 114518    75%    /
guriandgura# mkdir /hoge
guriandgura# cd /hoge
guriandgura# cat >boke&
[1] 56133
guriandgura# ls -al
total 4
drwxr-xr-x   2 root  wheel   512  2月 13 00:17 .
drwxr-xr-x  32 root  wheel  1024  2月 13 00:17 ..
-rw-r--r--   1 root  wheel     0  2月 13 00:17 boke
guriandgura# ls -i /hoge/boke
49952 /hoge/boke

inode番号は49952で、まだ書き込んでいないのでファイルサイズは0。

fsdbでinodeをのぞいてみる。

-rオプションをつけてread onlyでのぞき。

guriandgura# fsdb -r /dev/ad4s2a
** /dev/ad4s2a (NO WRITE)
Examining file system `/dev/ad4s2a'
Last Mounted on /
current inode: directory
I=2 MODE=40755 SIZE=1024
	BTIME=Apr 25 04:11:35 2007 [0 nsec]
	MTIME=Feb 13 00:17:04 2011 [0 nsec]
	CTIME=Feb 13 00:17:04 2011 [0 nsec]
	ATIME=Jul 20 23:54:57 2010 [0 nsec]
OWNER=root GRP=wheel LINKCNT=32 FLAGS=0 BLKCNT=4 GEN=694ba5aa
fsdb (inum: 2)> inode 49952
current inode: regular file
I=49952 MODE=100644 SIZE=0
	BTIME=Feb 13 00:17:03 2011 [0 nsec]
	MTIME=Feb 13 00:17:03 2011 [0 nsec]
	CTIME=Feb 13 00:17:03 2011 [0 nsec]
	ATIME=Feb 13 00:17:03 2011 [0 nsec]
OWNER=root GRP=wheel LINKCNT=1 FLAGS=0 BLKCNT=0 GEN=18996b66
fsdb (inum: 49952)> quit

LINKCNT=1となっていてディレクトリからちゃんと参照されているのがわかる。

ファイルをrmしたらinodeはどうなるか?

rmというのはディレクトリからの参照を消すこと。

guriandgura# ls -li boke
49952 -rw-r--r--  1 root  wheel  0  2月 13 00:17 boke
guriandgura# rm boke
guriandgura# ls -li boke
ls: boke: そのようなファイルまたはディレクトリはありません
guriandgura# sync
guriandgura# fsdb  -r /dev/ad4s2a
** /dev/ad4s2a (NO WRITE)
Examining file system `/dev/ad4s2a'
Last Mounted on /
current inode: directory
I=2 MODE=40755 SIZE=1024
	BTIME=Apr 25 04:11:35 2007 [0 nsec]
	MTIME=Feb 13 00:17:04 2011 [0 nsec]
	CTIME=Feb 13 00:17:04 2011 [0 nsec]
	ATIME=Jul 20 23:54:57 2010 [0 nsec]
OWNER=root GRP=wheel LINKCNT=32 FLAGS=0 BLKCNT=4 GEN=694ba5aa
fsdb (inum: 2)> inode 49952
current inode: regular file
I=49952 MODE=100644 SIZE=0
	BTIME=Feb 13 00:17:03 2011 [0 nsec]
	MTIME=Feb 13 00:17:03 2011 [0 nsec]
	CTIME=Feb 13 00:19:28 2011 [0 nsec]
	ATIME=Feb 13 00:17:03 2011 [0 nsec]
OWNER=root GRP=wheel LINKCNT=0 FLAGS=0 BLKCNT=0 GEN=18996b66
fsdb (inum: 49952)> quit

リンク数が0になったのがわかる。つまりファイルシステム上ではどのディレクトリにも名前がないということ。

ファイルにデータをかきこんだらどうなるか?

guriandgura# fg
cat > boke
hoge
hoge
^Z
中断
guriandgura# sync
guriandgura# fsdb -r /dev/ad4s2a
** /dev/ad4s2a (NO WRITE)
Examining file system `/dev/ad4s2a'
Last Mounted on /
current inode: directory
I=2 MODE=40755 SIZE=1024
	BTIME=Apr 25 04:11:35 2007 [0 nsec]
	MTIME=Feb 13 00:17:04 2011 [0 nsec]
	CTIME=Feb 13 00:17:04 2011 [0 nsec]
	ATIME=Jul 20 23:54:57 2010 [0 nsec]
OWNER=root GRP=wheel LINKCNT=32 FLAGS=0 BLKCNT=4 GEN=694ba5aa
fsdb (inum: 2)> inode 49952
current inode: regular file
I=49952 MODE=100644 SIZE=10
	BTIME=Feb 13 00:17:03 2011 [0 nsec]
	MTIME=Feb 13 00:20:36 2011 [0 nsec]
	CTIME=Feb 13 00:20:36 2011 [0 nsec]
	ATIME=Feb 13 00:17:03 2011 [0 nsec]
OWNER=root GRP=wheel LINKCNT=0 FLAGS=0 BLKCNT=4 GEN=18996b66
fsdb (inum: 49952)> quit

SIZE=10になってファイルが大きくなっているのがわかる。またBLKCNT=4になって実際にデータブロックが割り当てられているのもわかる。

closeしたらinodeはどうなる?

catコマンドをkillしてcloseする。

guriandgura# fg
cat > boke
^C
guriandgura# sync
guriandgura# fsdb -r /dev/ad4s2a
** /dev/ad4s2a (NO WRITE)
Examining file system `/dev/ad4s2a'
Last Mounted on /
current inode: directory
I=2 MODE=40755 SIZE=1024
	BTIME=Apr 25 04:11:35 2007 [0 nsec]
	MTIME=Feb 13 00:17:04 2011 [0 nsec]
	CTIME=Feb 13 00:17:04 2011 [0 nsec]
	ATIME=Jul 20 23:54:57 2010 [0 nsec]
OWNER=root GRP=wheel LINKCNT=32 FLAGS=0 BLKCNT=4 GEN=694ba5aa
fsdb (inum: 2)> inode 49952
current inode 49952: unallocated inode
fsdb (inum: 49952)> quit
guriandgura# 

inodeビットマップがクリアされてしまったのだろう、unallocatedと表示されてしまいディスク上のinodeがどうクリアされたかは見えず。

まとめ

openしたままrmするとリンク数は0になるが、inodeが再利用されないようにinodeビットマップは使用中のままである。

もしopenしたままrmしたあとにシステムクラッシュすると、fsckはこのinodeは使われていないとしてビットマップを修正するだろう。

記事検索
月別アーカイブ
アクセスカウンター

    タグ絞り込み検索
    ギャラリー
    • 國盛 知多梅酒
    • 國盛 知多梅酒
    • 國盛 知多梅酒
    • 國盛 知多梅酒
    • 國盛 知多梅酒
    • 今日の練習 2024-04-15
    Amazon
    楽天市場
    adby google
    LINE読者登録QRコード
    LINE読者登録QRコード