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の秘密かな?