2011年1月3日月曜日

第6回 V7から始めるUNIX講座 復習とまとめ

第6回 V7から始めるUNIX講座 復習とまとめ

●復習

前回でディレクトリファイルにファイル名とinodeが対になって管理している。

てっきり、ディレクトリのツリー構造をどこかに保持していると思ってた(DBのインデックスのように)

これは間違い。
あくまでディレクトファイルで管理している。
しかし、それだと辻褄が合わなくなる場合がある(突然電源がダウンした場合など)
その場合にinode(ファイル)としては存在するが、ディレクトリファイル上に管理情報がない状態になる。
そのファイルをlost+foundに置きます。
ファイル名が分からないので、inode番号のファイル名になります。
(備考)
本当はLost & Found(落とし物あずかり所)の意味らしいですが、&が特別な意味があるので+にしたと聞いたことがあります。

このチェックをするのが、fsckになります。
初期のUNIXでは、毎回fsckでチェックしていました。(この辺は割り切り仕様)

後になって、DBMSの考え方を取り込んで、ファイルシステムのロールバック、ロールフォワードが可能になりました。
それがジャーナルログになります。

●第6回目:ファイルシステム
ブロック単位で読み書きします。1ブロックは512バイトです。
フラットな構成になっていて、構成は以下の通りです。

1、SuperBlock(1ブロックくらいの小さい領域)
ファイルシステム全体で何個のファイルが使われているか、後何個のファイルを作ることが出来るか。空きブロックがどこにどれだけあるかなど。ファイルシステム全体を管理する構造を保持している。

2、inodeBlocks
UNIXファイルシステムでは、ファイルはinodeです。inodeへの操作がファイル操作になります。
inodeを特定するとファイルを特定することが出来ます。
→ファイルの実体はあくまでinodeです。
ただそれだと人間にとって辛いのでツリー構造のディレクトリにて、inodeに名前を付けたもの=ファイル名にてオペレーションを行います。
inodeBlocksにはinodeの配列が順番に並んでいるだけです。
ディレクトリについては、ツリー構造を保持しているわけではなく、ディレクトリファイルという特殊なファイルで構成していまs。(詳細は後述)

3、Block
 文字(ソースファイル)、ディレクトリの一部、a.outなどが入っている。

●SuperBlockの実装
http://www.tamacom.com/tour/kernel/unix/S/59.html


これがSuperBlockの構造になります。
1 /*
2 * Structure of the super-block
3 */
4 struct filsys {
5 unsigned short s_isize; /* size in blocks of i-list */
6 daddr_t s_fsize; /* size in blocks of entire volume */
7 short s_nfree; /* number of addresses in s_free */
8 daddr_t s_free[NICFREE];/* free block list */
9 short s_ninode; /* number of i-nodes in s_inode */
10 ino_t s_inode[NICINOD];/* free i-node list */
11 char s_flock; /* lock during free list manipulation */
12 char s_ilock; /* lock during i-list manipulation */
13 char s_fmod; /* super block modified flag */
14 char s_ronly; /* mounted read-only flag */
15 time_t s_time; /* last super block update */
16 /* remainder not maintained by this version of the system */
17 daddr_t s_tfree; /* total free blocks*/
18 ino_t s_tinode; /* total free inodes */
19 short s_m; /* interleave factor */
20 short s_n; /* " " */
21 char s_fname[6]; /* file system name */
22 char s_fpack[6]; /* file system pack name */
23 };


s_isize:inodeがどれくらいあるか
s_fsize:Blockがどれくらいあるか
SuperBlockのサイズは固定なので、管理情報としては存在しない
この構造はmkfsで作成します。

ファイルシステム全体でinodeとBlockをどれくらいの割合にするかはオプションで決められる。
例:小さいファイルを沢山作りたい。大きなファイルを少なく作りたい。

初期化はmkfsで行うが、マウントしてからは、SuperBlockはカーネルが頻繁に更新する。
例:df(ファイルシステムの空き容量を示す)、 duなんかはここから情報を取って表示している。

●inode
配列になっていて0、1、2・・・・・・・・・・・・・・・・・・・・・・・・・・・
となりますが、0番と1番は使われていない。2番から使います。
→UNIXV6は1番から使っていたらしい。V7から2番になった。
0番を使っていないのは、空き(未使用)を表現するため。
UNIXV7からは1番はBadBlock、Block不良の場合に使うようにしたので2番にしたのではないか。

ルートは2番を使います。
$ cd /
$ ls -di
2 .
iオプション(inode番号表示)を付けると/のinode番号が2であることが分かります。

/procや/sysなどマウントポイントになっているディレクトリが1になっていました。

●ファイルのリンク
UNIXでは、ハードリンクを使うと同じinodeに別の名前を複数付与できます。
$ echo > a
$ ln a b
$ ls -li
aとbは同じinode番号でリンクカウントが2になります。
$ ln b c
$ ls -li
aとbとcは同じinode番号でリンクカウントが3になります。

●ディレクトリのリンク
$ mkdir a
ディレクトリを作っただけでリンクカウントが2になっている。

$ ls -al

..
.はカレントディレクトリ、..は親ディレクトリ
ディレクトリもディレクトリという属性を持ったファイルでしかないが、ディレクトリとして存在するには、自分自身と親ディレクトリから参照されるので、作成しただけでリンクカウントが2になる。

そのため、
1、mkdirをしてディレクトリファイルの作成
2、親から作成したディレクトリを参照する設定
1と2の間で電源ダウンなどが発生すると、ファイルシステムに矛盾が発生する。
→そのため、ジャーナルのような概念がDBMSから入ってきた。

矛盾は発生するが、そこは割り切り。
矛盾が発生した場合はfsckでリカバリーする。

●ディレクトリとは
lsを実行すると、ファイルが表示される。
lsは「cat .」相当のことをやっている。(カレントディレクトリファイルの中身を表示)

V7で$ cat .を実行すると、inodeとファイル名の対で表示される。
16バイトで1エントリー。2バイトがinode、14バイトがファイル名(固定長)
→そのため、昔のUNIXのファイル名の長さが14文字という制限はここから。

ディレクトリファイルというのは、inodeとファイル名を対にして並べただけのシンプルな構成。

今後、これをベースにして、ファイル名の長さなどを拡張が行われていった。

inode番号が0のエントリは削除されたファイル(inode)

こういう構造なので、簡単に矛盾が発生するので当時のUNIXは起動時に必ずfsckが実行された。
後に、正しくシャットダウンされたという印がスーパーブロックに書いてあったら、fsckはスルーするように実装が追加された。

●dinode
http://www.tamacom.com/tour/kernel/unix/S/60.html


1 /*
2 * Inode structure as it appears on
3 * a disk block.
4 */
5 struct dinode
6 {
7 unsigned short di_mode; /* mode and type of file */
8 short di_nlink; /* number of links to file */
9 short di_uid; /* owner's user id */
10 short di_gid; /* owner's group id */
11 off_t di_size; /* number of bytes in file */
12 char di_addr[40]; /* disk block addresses */
13 time_t di_atime; /* time last accessed */
14 time_t di_mtime; /* time last modified */
15 time_t di_ctime; /* time created */
16 };
17 #define INOPB 8 /* 8 inodes per block */
18 /*
19 * the 40 address bytes:
20 * 39 used; 13 addresses
21 * of 3 bytes each.
22 */


di_modeにread, write, executeの3ビットが3つとファイルの種類(regular、directory)などが格納されている。
di_addrにBlockのどこに実体があるかが書いてある。

ディスクをダンプしてみると、一定のパターンで755が出現するのが分かる。
→inodeBlocksにinodeが順番に並んでいることが分かる。

●ディレクトリの作成(構造に従って記述)
1、inode Blocksから空いてるinodeを1つ確保する。
2、確保したinodeのdi_modeにdirectoryと書く。
3、自分と親の参照によりリンクカウントを2にする
4、実体はBlockに書き込むのでBlockから空いてるものを1つ確保する。
5、di_addrから確保したBlockを指すようにする。
6、Blockの中に2バイトのinode番号と14バイトのファイル名を並べる
7、使わなくなったら、inode番号を0にする。

●namei
http://www.tamacom.com/tour/kernel/unix/S/90.html

ファイル名(パス名)からinodeに変換する。
UNIXの核になる関数

●補足
SDをUbuntuでext3でmkfsした時のログです。

OS type: Linux
Block size=4096 (log=2)→ブロックサイズは4096のようです。
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
235248 inodes, 939802 blocks→inodeBlocksが235248、Blockが939802作成されています
46990 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=964689920
29 block groups
32768 blocks per group, 32768 fragments per group
8112 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736

Checking for bad blocks (read-only test): done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

0 件のコメント:

コメントを投稿