FreeBSD

ccd のセットアップ


0. 用意するもの

1. FreeBSD のインストール

パーティションの切り方の例

/usr, /var および /usr/local をミラー構成にする。

ad0   ad1 容量
/   - 128M
swap   swap 1024M
/usr ccd0g
ミラー
/usr 2047M
/var ccd1g
ミラー
/var 2047M
/usr/local ccd2g
ミラー
/usr/local 残り全部

ccd によるソフトウエアミラーの手順

  1. ad0 は /, swap, /usr, /var, /usr/local で、 ad1 は /backup/root, swap, /backup/usr, /backup/var, /backup/usr-local でパーティショニングしておく。 各ディスクの対応するパーティションが同じサイズになるように注意する。
  2. あとはいつも通りインストールする。 ただし、/usr/local に入る packages の類はいっさい入れない(入れても作業途中で潰れてしまう)。
  3. ccd デバイスの入ったカーネルを作る。 具体的には、
    pseudo-device ccd 3
    を加えてカーネルを作る。
  4. シングルユーザーモードでブートし、/backup 以下の 4 つのパーティションと /usr/local を umount。 作業しやすいように /usr, /var はマウントしておく。
  5. sysinstall の中でパーティショニングしたので ad1 のパーティション名が e から始まっている。 混乱を避けるため、disklabel(8) コマンドでパーティション名を振りなおす (e → a, f → e, g → f, h → g)。 こうしておけば、ad0s1e のミラーは ad1s1e というふうになって分かりやすい。
    	# disklabel -r -e ad1s1
    
    エディット画面の下の方の
    8 partitions:
    #        size   offset    fstype   [fsize bsize bps/cpg]
      e:   262144        0    4.2BSD     1024  8192    16   # (Cyl.    0 - 260*)
      b:  1048576   262144      swap                        # (Cyl.  260*- 1300*)
      c: 26520417        0    unused        0     0         # (Cyl.    0 - 26309*)
      f:  4194304  1310720    4.2BSD     1024  8192    16   # (Cyl. 1300*- 5461*)
      g:  4194304  5505024    4.2BSD     1024  8192    16   # (Cyl. 5461*- 9622*)
      h: 16821089  9699328    4.2BSD     1024  8192    16   # (Cyl. 9622*- 26309*)
    
    e: などの部分を書き換える。 b: および c: とそれ以外の部分(size や offset)は触らないこと。
  6. /usr (ccd0) と /var (ccd1) に関しては、まず ad1 だけの 1-disk ccd として設定する。 /usr/local はミラー構成で設定。
    	# ccdconfig ccd0 0 0 /dev/ad1s1e
    	# ccdconfig ccd1 0 0 /dev/ad1s1f
    	# ccdconfig ccd2 256 6 /dev/ad0s1g /dev/ad1s1g
    
  7. 各 ccd に初期ディスクラベルを書き込む。 disklabel(8) コマンドを使う。
    	# disklabel -r -w ccd0c auto
    	# disklabel -r -w ccd1c auto
    	# disklabel -r -w ccd2c auto
    
  8. 各 ccd のディスクラベルを編集してパーティションが一つだけのディスクにする。
    	# disklabel -r -e ccd0c
    	# disklabel -r -e ccd1c
    	# disklabel -r -e ccd2c
    
    ここでは g パーティションとしてみる。

    g パーティションの size, offset が c パーティションと同じになるようにし、その他の a, b, e, f, h は size, offset ともに 0, 0 とする。 行末の # 以降はコメントなので無視してよい。
    起動した状態ではいくつかのパーティションが定義されているが、以下のようになればよい。
    8 partitions:
    #        size   offset    fstype   [fsize bsize bps/cpg]
      a:        0        0    unused        0     0         
      b:        0        0      swap                        
      c: 26520417        0    unused        0     0         # (Cyl.    0 - 26309*)
      e:        0        0    unused        0     0         
      f:        0        0    unused        0     0         
      g: 26520417        0    4.2BSD     1024  8192     16  # (Cyl.    0 - 26309*)
      h:        0        0    unused        0     0
    
    g: の size と offset は c: と同じ、 fstype から後は上記の通り "4.2BSD 1024 8192 16" にする。

  9. ファイルシステムを作る。 大規模な web サーバなどの場合は /usr/local にたくさんの小さなファイルが置かれる可能性があるので i-node の数を増やしておく。
    	# newfs /dev/ccd0g
    	/dev/ccd0g:	16821072 sectors in 4107 cylinders of 1 tracks, 4096 sectors
    	        8213.4MB in 257 cyl groups (16 c/g, 32.00MB/g, 7936 i/g)
    	super-block backups (for fsck -b #) at:
    	 32, 65568, 131104, 196640, 262176, 327712, 393248, 458784, 524320, 589856,
    	....
    	# newfs /dev/ccd1g
    	/dev/ccd1g:	xxxxxxxx sectors in ...
    	# newfs -i 2048 /dev/ccd2g
    	/dev/ccd2g:	xxxxxxxx sectors in ...
    
    (※-i 2048 で i-node の数をデフォルトの倍に増やしている。cf. newfs(8))
    (※ FreeBSD 4.x からは raw device が無くなったので、デバイス名の頭に 'r' が付いていない。4.x 以前を使用する場合は注意)
  10. ccd0g, ccd1g をマウントし、/usr および /var の内容をコピーする。 dump(8) / restore(8) の組み合わせでも tar(1) でもよい。
    	# mount /dev/ccd0g /mnt
    	# (cd /usr; tar cf - .) | (cd /mnt; tar xpBf -)
    	# umount /mnt
    	# mount /dev/ccd1g /mnt
    	# (cd /var; tar cf - .) | (cd /mnt; tar xpBf -)
    	# umount /mnt
    
  11. /usr および /var を umount して、ad1 側のデータを ad0 側にコピー。dd(1) を使う。
    	# umount /var
    	# umount /usr
    	# dd if=/dev/ad1s1e of=/dev/ad0s1e bs=1024k
    	1024+0 records in
    	1024+0 records out
    	1073741824 bytes transferred in 51.2 secs (20 MBytes/sec)
    	# dd if=/dev/ad1s1f of=/dev/ad0s1f bs=1024k
    	2047+0 records in
    	2047+0 records out
    	....
    
  12. ad0, ad1 のミラーとして ccd0, ccd1 を再構成する。
    	# ccdconfig -u ccd0
    	# ccdconfig -u ccd1
    	# ccdconfig ccd0 256 6 /dev/ad0s1e /dev/ad1s1e
    	# ccdconfig ccd1 256 6 /dev/ad0s1f /dev/ad1s1f
    
  13. 念のため fsck(8) してみる。
    	# fsck -p /dev/ccd0g
    	3 files, 3 used, 1689022 free (0 frags, 204409 blocks, 0.0% fragmentation)
    	# fsck -p /dev/ccd1g
    	3 files, ...
    	# fsck -p /dev/ccd2g
    	3 files, ...
    
  14. ブート時に ccd が有効になるよう /etc/ccd.conf を作成。
    	# ccdconfig -g > /etc/ccd.conf
    
    あとで都合がいいように、障害時に使うエントリもコメントの形で書き込んでおく(詳しくは後述)。
  15. ここまですべて OK なら /etc/fstab を書き換える。
  16. ad1 からもブートできるように / パーティションの内容を ad1s1a にコピーしておくと障害発生時に楽。 シングルユーザーモードで dump & restore を使用する。 こちらの fstab は ad1s1a を / としてマウントするように書き換えておく。
    	# mount /dev/ad1s1a /mnt
    	# cd /
    	# dump 0f - / | (cd /mnt; restore xfy -)
    	  DUMP: Date of this level 0 dump: ...
    		...
    	set owner/mode for '.'? [yn] y
    	  DUMP: DUMP IS DONE
    	# vi /mnt/etc/fstab
    		...
    	# umount /mnt
    
    # Device		Mountpoint	FStype	Options		Dump	Pass#
    /dev/ad0s1a		/		ufs	rw		1	1
    /dev/ad0s1b		none		swap	sw		0	0
    /dev/ad1s1b		none		swap	sw		0	0
    /dev/ccd0g		/usr		ufs	rw		2	2
    /dev/ccd1g		/var		ufs	rw		2	3
    /dev/ccd2g		/usr/local	ufs	rw		2	4
    proc			/proc		procfs	rw		0	0
    /dev/ad0s1b		/tmp		mfs	rw,nosuid	0	0
    #
    /dev/acd0c		/cdrom		cd9660	ro,noauto	0	0
    
    ad0s1a の 0 を 1 に書き換える。
あとはいつも通り DNS やら sendmail やらの設定をします。 リブートしてちゃんと上がってくるか確認して完了。

2. ccd しているディスクが死んだ時の対処

ccd しているディスクがふっ飛んだ時は、生きている方のディスクだけで 1-disk ccd を構成すればデータを読み出すことができ、とりあえず運用を再開することもできる。 バックアップを取り、新しいディスクを調達して早めに disk を交換する。
  1. /etc/ccd.conf の書き換え
    ad0 が死んでいる場合は
    	ccd0 0 0 /dev/ad1s1e
    	ccd1 0 0 /dev/ad1s1f
    	ccd2 0 0 /dev/ad1s1g
    
    を、ad1 が死んでいる場合は
    	ccd0 0 0 /dev/ad0s1e
    	ccd1 0 0 /dev/ad0s1f
    	ccd2 0 0 /dev/ad0s1g
    
    を有効にする。 これらの行を予め /etc/ccd.conf に書き込んでおくと素早く対処できる。
  2. とりあえず運用再開して、ディスクを調達。
    まったく同じディスクが手に入ればベスト。 無い場合は元のディスクと同容量かもしくはそれよりも大きいものを調達する。
  3. なるべく早くメンテナンスを実施してディスクを交換する。
    ccd をミラーの状態に戻すには、ccd0 や ccd1 のセットアップ時にやったように、dd コマンドを使って生きている方のディスクから新しいディスクへデータをコピーして、ccdconfig しなおす。

2.1 初期対応作業例

ad1 がふっ飛んだ時の作業例。

この場合、カーネルがエラーを吐きながら何とか運用を続けているか、あるいは reboot の途中で止まっているかのどちらか。 後者の場合の例。

ccd0g: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
Enter root password, or ^D to go multi-user
Password: ********
Enter full pathname of shell or RETURN for /bin/sh:
# ccdconfig -u ccd0		(ccd の設定を解除)
# ccdconfig -u ccd1
# ccdconfig -u ccd2
# ccdconfig ccd0 0 0 /dev/ad0s1e	(1-disk ccd で設定)
# ccdconfig ccd1 0 0 /dev/ad0s1f
# ccdconfig ccd2 0 0 /dev/ad0s1g
# fsck -p /dev/ccd0g		(マウントする前にチェック!)
ccd0g: clean, xxxxx free
# fsck -p /dev/ccd1g
ccd1g: clean, ...
# fsck -p /dev/ccd2g
ccd2g: clean, ...
# mount /usr; mount /var	(vi のため /usr と /var をマウント)
# vi /etc/ccd.conf		(緊急用エントリを有効化する)
# ^D				(マルチユーザーモードに)
Automatic reboot in progress...

2.2 disk 交換作業例

ad1 を交換する場合の作業例。
hatanou@hostname[101] su
Password: ********
hostname# halt	(マシンを止める)
syncing disks... 4 2 done

(ディスクを交換、シングルユーザーモードでブート)

# disklabel -r -w ad1 auto	(初期ディスクラベルを書く)
# /stand/sysinstall		(スライス/パーティションを作成。fdisk を使ってもよい)
# disklabel -r -e ad1		(パーティション情報を編集)
# dd if=/dev/rad0s1e of=/dev/rad1s1e bs=1024k	(ccd0 をコピー)
1024+0 records in
1024+0 records out
1073741824 bytes transferred in ...
# dd if=/dev/rad0s1f of=/dev/rad1s1f bs=1024k	(ccd1 をコピー)
2047+0 records in
...
# dd if=/dev/rad0s1g of=/dev/rad1s1g bs=1024k	(ccd2 をコピー)
20480+0 records in
...
# ccdconfig -u ccd0				(ccd0 の設定を解除)
# ccdconfig ccd0 64 6 /dev/ad0s1e /dev/ad1s1e	(ccd0 をミラーに設定)
# ccdconfig -u ccd1				(ccd1 について同様に)
# ccdconfig ccd1 64 6 /dev/ad0s1f /dev/ad1s1f
# ccdconfig -u ccd2				(ccd2 について同様に)
# ccdconfig ccd2 64 6 /dev/ad0s1g /dev/ad1s1g
# fsck -p /dev/ccd0g		(念のためファイルシステムをチェック)
200 files, 3270081 used, ...
# fsck -p /dev/ccd1g
500 files, ...
# fsck -p /dev/ccd2g
16340 files, ...
# mount /usr; mount /var	(vi を使うためマウント)
# vi /etc/ccd.conf		(元に戻す)
# ^D				(シングルユーザーを抜ける)
Automatic reboot in progress...

A. 備考

A.1 ccd ディスクを別々に分ける理由

ccd ディスクも、普通のディスクと同じように中を a から h までの 8 つのパーティションに分けることができます。

ccd ディスクを一つにしてパーティションで /usr, /var, /usr/local に分けることもできますが、その場合例えば /var の ad1 側と /usr/local の ad0 側で障害が起きたような場合に、すべてのデータを失うリスクがあります。

● ccd ディスクを一つにした場合

ad0ad1
 
障害
 
正常
ccd0
ccd0e
ccd0f
ccd0g
動いてはいるが
すべてのパーティションに
障害がある
ad0ad1
 
 
障害
 
障害
 
ccd0
ccd0e
ccd0f
ccd0g
全滅。

● ccd ディスクを分けた場合

ad0ad1
 
障害
 
正常
 
ccd0g
ccd1g
ccd2g
障害がある状態なのは
ccd1g だけ。動作は可能
ad0ad1
 
 
障害
 
障害
 
 
ccd0g
ccd1g
ccd2g
まだすべてのパーティションを
読める

Last update: 2001/11/09