df
この時期、夜の散歩が楽しい。
何故かと言うと、いろいろなクリスマス・デコレーションが見られるからだ。バンビちゃんが 何頭も庭に居たり、アヒルちゃんだか白鳥さんだか知らないけれど、何羽もフェンスに居たりだ。 きっと、お子さんにせがまれて飾っているのかな?
電飾は大体暖色系が多いけど、去年あたりから青色ダイオードが出てきたように思う。これらの LEDは半導体なので半永久的に使えるかと思ったら、だんだんと劣化して、光量が減っていくとか。 で、寿命の定義は、初期光量の半分になった時だそうだ。大体10万時間との事。
最近は、青色ダイオードのおかげでう、LED-TVが出来るようになり、某メーカーは売り出しに躍起。 せいぜい頑張ってください。どう頑張ったって、田園の真ん中に立つ、集虫灯のパチンコ屋看板の 二の舞でしょう。広告がメインでその間に番組を流すなんて、時代遅れになりまっせ。
TVを見て欲しかったら、広告塔は無料じゃなくっちゃ!!!!! 良く聞けよ。関東一円のTV局。
最近、おいらのTVは寿命っぽくて、TVをONした当初は黄色っぽく映るんよ。液晶TVのくせに、 何となくブラウン管の末期的症状に似ているな。液晶の裏側に鎮座する蛍光灯の寿命かしらん。
と、まあ、半導体にも寿命がありまっせと愚痴ってきたけど、クリスマスのイルミネーションは いいよな。出番は、年に一度きり。これなら、寿命は半永久的でっせ。爺婆が孫の為に買って あげたデコレーションセットが、3代とか4代受け継げるぞ。大事にしなされ。
何でも鑑定団で、100年前に使われていた、祭り用の道具です、なんて言われて、思わぬ高値を 付けるかも???
gc
るびまのHotlinksでnariさんが登場してる。 日本で一番有名なgc屋さんではなかろうか。(無駄に)豪華な野次馬に囲まれて楽しそう。
なんで竹内先生が島根に居るんだ? 温泉にでも入りに行ったのか? ささださんに誘われて 研究室のプチ旅行なのかと、いらぬ詮索をしてしまったぞ。まあ、先生が島根に居る理由は大体 想像つくけど。
gcのページを作っちゃうなんてオタッキーだなあ。 読んでると楽しいよ。おいらも以前、amscmのgcのコードを読んだんで親近感があるねぇ。
Mostly-Concurrent Mark & Sweep GC のアルゴリズム 後でゆっくり読んでみよう。
gcとは直接関係ないけど、rubyに穴が見つかって、新しいのが出てるのね。FreeBSDのportsから Ruby 1.9.1-p376 リリースにしたよ。
WindowsXPの調子が悪いその参です。
(苦笑)してますよ。今度はどんなトラブルかと言うと、、、
HDDの容量は無限じゃないんです。だからたまには、マイコンピュータのHDDのアイコンを右クリックして、 だらりと出てきたメニューから一番下のプロパティーを選んで、円グラフを見る訳ですよ。
所が何時の間にか、右クリックしてもメニューが直ぐに出てこなくなり、カーソルはお待ち 下さいアイコンになったままになるんです。で、大分時間が経ってから、メニューがだらりと 出てくるんです。そこをすかさず捕らえて、カーソルを一番下まで持ってこないと、メニュー が消失。また、一からやり直し。これだからGUIって嫌いさ。unixなら、dfって叩くだけで 済んじゃうじゃないですか。
そうそう、duに相当するのもGUIの操作だといらいらさせられますね。いちいち、ファイル数や 容量の総計の計算過程を表示せんでもいいでぇ。馬鹿ファイルシステムは、そうやって時間 稼ぎせんと、さっと表示できんのか脳。紙芝居はPowerPointだけかと思っていたら、DNAに 植え付けられているのね。
df
Windowsではいらいらさせられるdf相当。unixでは一瞬だけど、その仕組みやいかに? ちょっと潜って見てみるか。
まずは、仕様書だな。man df
普段使っているけど、結構知らなかったオプションがあるのね。-cで総計も出ますだってさ。 さすがに -i は知ってたけど。馬鹿GUIは、いろんな単位での表示も出来なくて、GUIの割りには 使う人に不親切だよ。
[sakae@fb8 ~]$ df -ich Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/da0s1a 721M 208M 455M 31% 3.0k 115k 3% / devfs 1.0K 1.0K 0B 100% 0 0 100% /dev /dev/da0s1d 4.9G 3.3G 1.2G 74% 254k 405k 39% /usr total 5.6G 3.5G 1.6G 68% 257k 520k 33%
続いて、関連情報を見ると
関連項目 lsvfs(1), quota(1), fstatfs(2), getfsstat(2), statfs(2), getmntinfo(3), fstab(5), mount(8), quot(8)
manしたおかげで、一つ新しいコマンドを覚えたよ。
[sakae@fb8 ~]$ lsvfs Filesystem Refs Flags -------------------------------- ----- --------------- msdosfs 0 ufs 2 procfs 0 synthetic devfs 1 synthetic cd9660 0 read-only nfs 0 network
上記が、今ロードされてるモジュールですってさ。話題のzfsはロードしてないので、見えていない。 Refsは、現在マウントされているものの数。 manのチェーンを辿って行ったら、mount_ntfsなんてのが見つかった。心の広いOSだ事!
では、お約束のソースを見るかな。まあ、大体どうなっているかは想像つくわな。fstatfsで 今のfsを引っ張ってきて、それを元にgettsstatあたりで個別のデータを取り出してくる。 後は、いろいろな単位に加工して表示かな。
df.c
[sakae@fb8 /usr/src/bin/df]$ ls Makefile df.1 df.c [sakae@fb8 /usr/src/bin/df]$ wc df.c 613 2068 15691 df.c
こんな具合になってた。折角なので、自分のエリアに持ってきてから -g付きでコンパイルしてみる。 (ライオンだって、狩ってきた獲物を安全な所へ運んでから、料理するでしょ)
[sakae@fb8 /usr/src/bin/df]$ mkdir ~/work [sakae@fb8 /usr/src/bin/df]$ cp Makefile df.c ~/work [sakae@fb8 /usr/src/bin/df]$ cd ~/work [sakae@fb8 ~/work]$ make Warning: Object directory not changed from original /usr/home/sakae/work cc -O2 -pipe -I/usr/home/sakae/work/../../sbin/mount -std=gnu99 -fstack-protector -c df.c df.c:63:20: error: extern.h: No such file or directory df.c: In function 'main': df.c:162: warning: implicit declaration of function 'makevfslist' df.c:162: warning: assignment makes pointer from integer without a cast df.c:178: warning: assignment makes pointer from integer without a cast df.c:277: warning: implicit declaration of function 'checkvfsname' *** Error code 1 Stop in /usr/home/sakae/work.
ははは、エラーだわさ。
[sakae@fb8 ~/work]$ diff Makefile.org Makefile 4c4 < MOUNT= ${.CURDIR}/../../sbin/mount --- > MOUNT= /usr/src/sbin/mount 9a10 > CFLAGS+= -g -O0 [sakae@fb8 ~/work]$ make Warning: Object directory not changed from original /usr/home/sakae/work cc -O2 -pipe -g -O0 -I/usr/src/sbin/mount -std=gnu99 -fstack-protector -c df.c cc -O2 -pipe -g -O0 -I/usr/src/sbin/mount -std=gnu99 -fstack-protector -c /usr/src/sbin/mount/vfslist.c cc -O2 -pipe -g -O0 -I/usr/src/sbin/mount -std=gnu99 -fstack-protector -o df df.o vfslist.o -lutil make: don't know how to make df.1. Stop [sakae@fb8 ~/work]$ ./df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0s1a 738318 213124 466130 31% / devfs 1 1 0 100% /dev /dev/da0s1d 5093430 3459626 1226330 74% /usr
どうやら、出来たっぽい。よそのコマンド(mount)の一部を拝借してるのね。上の実行例でも 分かるけど、マウントしてるファイルシステム情報が必要なんだな。そんじゃ、gdbで追って みますかね。
119 while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1) 190 mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 199 for (i = 0; i < mntsize; i++) { (gdb) 202 update_maxwidths(&maxwidths, &mntbuf[i]); (gdb) 199 for (i = 0; i < mntsize; i++) { (gdb) 204 if (cflag) (gdb) 206 for (i = 0; i < mntsize; i++) (gdb) 207 if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) (gdb) 208 prtstat(&mntbuf[i], &maxwidths); (gdb) Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/da0s1a 738318 213124 466130 31% /
なるほどね、getmntinfo と prtstatあたりが肝か。prtstatを見てみる
440 (void)printf(" Mounted on\n"); (gdb) Filesystem 1K-blocks Used Avail Capacity Mounted on 442 (void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname); (gdb) 443 if (Tflag) (gdb) 445 used = sfsp->f_blocks - sfsp->f_bfree; (gdb) 446 availblks = sfsp->f_bavail + used; (gdb) 445 used = sfsp->f_blocks - sfsp->f_bfree; (gdb) 446 availblks = sfsp->f_bavail + used; (gdb) 447 if (hflag) { (gdb) 446 availblks = sfsp->f_bavail + used; (gdb) 447 if (hflag) { (gdb) 450 (void)printf(" %*jd %*jd %*jd", (gdb) 457 (void)printf(" %5.0f%%", (gdb) 459 if (iflag) { (gdb) 473 (void)printf(" "); (gdb) 474 if (strncmp(sfsp->f_mntfromname, "total", MNAMELEN) != 0) (gdb) 475 (void)printf(" %s", sfsp->f_mntonname); (gdb) 476 (void)printf("\n"); (gdb) /dev/da0s1a 738318 213124 466130 31% /
長々とページを稼いでしまったけど、本質は、190行目のgetmntinfoだけね。後はほとんど 整形の為だわさ。gdbで190行目を実行した後のデータを見ると
(gdb) p *mntbuf $18 = {f_version = 537068824, f_type = 2, f_flags = 20480, f_bsize = 2048, f_io\ size = 16384, f_blocks = 369159, f_bfree = 262597, f_bavail = 233065, f_files =\ 117758, f_ffree = 114785, f_syncwrites = 0, f_asyncwrites = 0, f_syncreads = 0\ , f_asyncreads = 0, f_spare = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, f_namemax = 255, f_owner = 0, f_fsid = {val = {0, 0}}, f_charspare = '\0' <repeats 79 times>, f_fstypename = "ufs",\ '\0' <repeats 12 times>, f_mntfromname = "/dev/da0s1"..., f_mntonname = \ "/", '\0' <repeats 86 times>}
とか、ちょっと綺麗に表示するぞとか
(gdb) set print pretty on (gdb) p *(mntbuf+2) f_asyncreads = 0, f_flags = 2101248, f_bsize = 2048, f_iosize = 16384, f_version = 537068824, f_type = 2, f_flags = 2101248, f_bsize = 2048, f_iosize = 16384, f_blocks = 2546715, f_bfree = 816902, f_bavail = 613165, f_files = 659454, f_ffree = 404957, f_syncwrites = 0, f_asyncwrites = 0, f_syncreads = 0, f_asyncreads = 0, f_spare = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, f_namemax = 255, f_owner = 0, f_fsid = { val = {0, 0} }, f_charspare = '\0' <repeats 79 times>, f_fstypename = "ufs", '\0' <repeats 12 times>, f_mntfromname = "/dev/da0s1"..., f_mntonname = "/usr", '\0' <repeats 83 times> }
解説も man statfsしたら出てきた。
struct statfs { uint32_t f_version; /* 構造体のバージョン番号 */ uint32_t f_type; /* ファイルシステムのタイプ */ uint64_t f_flags; /* マウントフラグのコピー */ uint64_t f_bsize; /* ファイルシステムの断片サイズ */ uint64_t f_iosize; /* 最適な転送ブロックサイズ */ uint64_t f_blocks; /* ファイルシステム上の合計データブロックサイズ */ uint64_t f_bfree; /* ファイルシステム上の利用可能なブロック */ int64_t f_bavail; /* スーパユーザ以外が利用可能なブロック */ uint64_t f_files; /* ファイルシステム上の合計ノード数 */ int64_t f_ffree; /* スーパユーザ以外が利用可能なノード数 */ uint64_t f_syncwrites; /* マウントしてからの同期書込み数 */ uint64_t f_asyncwrites; /* マウントしてからの非同期書込み数 */ uint64_t f_syncreads; /* マウントしてからの同期読取り数 */ uint64_t f_asyncreads; /* マウントしてからの非同期読取り数 */ uint64_t f_spare[10]; /* 未使用領域 */ uint32_t f_namemax; /* ファイル名の長さの最大 */ uid_t f_owner; /* ファイルシステムをマウントしたユーザ */ fsid_t f_fsid; /* ファイルシステム ID */ char f_charspare[80]; /* 後のための余白 */ char f_fstypename[MFSNAMELEN]; /* ファイルシステムのタイプ名 */ char f_mntfromname[MNAMELEN]; /* マウントされたファイルシステム */ char f_mntonname[MNAMELEN]; /* このディレクトリにマウント */ };
次は、duの秘密かな?