2008-02-12
ファイルシステムフルの作り方
備忘。テストとか検証のために、ファイルシステムに空きが無いとかinodeを使い果たした状態を作りたいことがあるけど、LVM使えば簡単やないか。
- ファイルシステムに空きが無い状態
- inodeを使い果たした状態
colinux(0):~$ sudo lvcreate -L 4M -n lvfull vg01 colinux(0):~$ sudo mkfs.ext3 /dev/vg01/lvfull colinux(0):~$ mkdir test colinux(0):~$ sudo mount -t ext3 -o rw /dev/vg01/lvfull test/ colinux(0):~$ df test/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/vg01/lvfull 3963 1043 2716 28% /home/lab/test colinux(0):~$ dd if=/dev/zero of=test/dummy bs=1K count=3963 dd: writing `test/dummy': No space left on device 2705+0 records in 2704+0 records out 2768896 bytes transferred in 0.061086 seconds (45327804 bytes/sec)
colinux(0):~$ sudo lvcreate -L 4M -n lvfull vg01 colinux(0):~$ sudo mkfs.ext3 -N 1 /dev/vg01/lvfull colinux(0):~$ mkdir test colinux(0):~$ sudo mount -t ext3 -o rw /dev/vg01/lvfull test/ colinux(0):~$ df -i test/ Filesystem Inodes IUsed IFree IUse% Mounted on /dev/vg01/lvfull 16 11 5 69% /home/lab/test
2008-01-25
シェルスクリプト - テスト支援
今、シェルの開発をやっているんだけれども、テストが面倒くさい。で、楽できるようにテスト支援シェルみたいなのを作った。以外に役に立ったし気に入ったので、たまにメンテナンスしつつ使っていきたいなあとか思っていたけど、お馴染みのセキュリティ云々で持ち出すことが出来ない。せっかくだから何か残しておきたいと思うので、作るときのノウハウ的なものをメモ。ちなみにブラックボックス。
- テスト時の準備オペレーションを関数化
- 設定ファイルなどをリネームする。
- DBに対してSQLを発行する。
- DBに対して時間差でSQLを発行する。
- 任意のディレクトリにごみファイルを作る。
- 設定ファイルなどの内容を書き換える。
- 共通系モジュールなどのリターンコードを任意の値に変更する。
- ファイル・ディレクトリのパーミッションを設定する。
- などなど。
- シェルの実行を関数でラップ
- 戻り値のチェック。
- 準備オペレーションの内容を元に戻す。
- テストケース毎に一時停止する。
異常系のコードを走らせるために、シェルの実行環境とかをいじる必要があったりする。 そういう場合のオペレーションを全部関数化しておく。例えば以下のようなものとか。
あと、これらの関数で変更した内容を元に戻すための仕組みも用意しておく。例えば、リネームだと
UNIQUE_ID=`date +%Y%m%d%H%M%S`${$} # どこかでユニークなIDを用意しておく。
function rename {
_ORIGINAL=${1}
mv ${_ORIGINAL} ${_ORIGINAL}${UNIQUE_ID}
RECOVER="${RECOVER}:mv ${_ORIGINAL}${UNIQUE_ID} ${_ORIGINAL}"
}
function recover {
IFS=":"
for COMMAND in ${RECOVER}; do
eval ${COMMAND}
done
RECOVER=""
}
とか。(変更内容を戻したいときは、${RECOVER}に登録されたコマンドを実行する。)
とにかく、準備オペレーションをうまいこと関数化しておき、簡単にあるケースに特化した試験環境を作れるようにしておく。ここでどれだけナイスな関数を作っておくかで試験の効率化具合が決まる。
ラッパーの中で、以下の機能を実現する。
こんなかんじ。
function exec_command {
_COMMAND=${1} # 実行コマンド
_EXPECT=${2} # 期待する戻り値
echo ${_COMMAND}
eval ${_COMMAND}
_RC=${?}
if [ ${_RC} -ne ${_EXPECT} ]; then
echo "No good. Return code => ${_RC}"
exit 1
else
echo "Good. Return code => ${_RC}"
fi
read
recover
clear
}
個人的に一番重要なのは、「テストケース毎に一時停止する。」。「テストシェルに通ったのでOKです!」で通じる相手なんてまれで、「シェルをコマンドラインから投入した実行結果のハードコピーが欲しい。」なんてことが多いので、準備オペレーションの内容を元に戻す前で一時停止させる。この仕組みを作っておけば、2個ターミナルを上げて、片方のターミナルでテストシェルを流し、もう片方でハードコピー取得用にコマンドラインからシェルを実行する。ということが楽に出来る。
#!/bin/bash
UNIQUE_ID=${$}`date +%Y%m%d`
#----------------------------------
# 試験環境準備オペレーション用関数
#----------------------------------
function rename {
_ORIGINAL=${1}
mv ${_ORIGINAL} ${_ORIGINAL}${UNIQUE_ID}
RECOVER="${RECOVER}:mv ${_ORIGINAL}${UNIQUE_ID} ${_ORIGINAL}"
}
function recover {
IFS=":"
for COMMAND in ${RECOVER}; do
eval ${COMMAND}
done
RECOVER=""
}
#------------------
# シェル実行用関数
#------------------
function exec_command {
_COMMAND=${1} # 実行コマンド
_EXPECT=${2} # 期待する戻り値
echo ${_COMMAND}
eval ${_COMMAND}
_RC=${?}
if [ ${_RC} -ne ${_EXPECT} ]; then
echo "No good. Return code => ${_RC}"
exit 1
else
echo "Good. Return code => ${_RC}"
fi
read
recover
clear
}
trap recover EXIT
# こっからテストを書く。
rename foo
exec_command "/home/foo/bin/test.sh -c hoge" 0
rename hoge
rename foo
exec_command "/home/foo/bin/test.sh -c hoge" 0
試験環境準備オペレーション用関数(ながい。)を別ファイルにまとめ、読み込んでから使うようにしてもいいし、他にも色々工夫できそう。どっかで使う機会があれば、使ってみよう。
2007-12-27
JavaScriptで15パズル
を作ってみました。→ココ
flickrから「babe」ってタグの写真をとってきて、それをJavaScriptで擬似的に15分割して作成しています。運が良ければべっぴんな姉ちゃんが出てくるけど、その逆も然りでブラクラにもなりうるという感じになっております。機能的にどうとかというのはないので、使ってみれば操作はすぐわかると思います。
作成の動機はJavaScriptの勉強というところなのですが、そもそもはこちらの記事で紹介されていた「Googleの検索結果ページは画像を一つしか読み込んでいない」ってのが気になって、「へー、JavaScriptって画像切れるんや。」とかっていう風に勝手に思ってやりました(バカ)。実際は画像の複製と、画像の一部表示の併せ技で画像の切り取りを擬似的に実現しています(Googleも多分そうだと思うけれど、あのソースは読む気になれない。。。)。
まだリファクタリングしていない箇所もあって、冗長な箇所があったりするのですが、ひとまずは完成しています。 今後は、もし気が向けばアニメーションの勉強がてらのバージョンアップをしたいなあ。
2007-12-11
Ma.gnoliaはブックマークした時点のスナップショットをとっといてくれる
これは便利。IBMの技術関連文章なんかはすぐページが変わったりするので困っているけど、これなら問題ない。乗り換えよっかなあ。。。2007-10-30
coLinuxでLVM
LVM使用までのまとめ。
- カーネルのコンパイル
- LVMのインストール
- イメージファイルの用意
- ファイルシステムの作成まで ■ 物理デバイス(PV)の登録
インストールしたときに入っているカーネルでは、LVMがサポートされていませんでした。なので、LVMのサポートを有効にして、カーネルのコンパイルをする必要がありました。カーネルのコンパイル自体は初めてでしたが、こちらのページの解説とおりにやることでコンパイルすることが出来ました。自分用の備忘も兼ねてということで手順は書いていますが、コンパイル自体の説明はこちらのページを参照されるのが良いと思います。
■ カーネルのソースを取得初めに、コンパイルするためのカーネルソースと、coLinux用のパッチを取得します。注意する点としては、coLinuxのパッチをlinuxカーネルのバージョンと合わせることぐらいです。
#僕はカーネルの2.6.11を選びましたが、特に深い意味はありません。
$ cd /usr/src/ $ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.11.tar.gz $ wget http://downloads.sourceforge.net/colinux/coLinux-0.6.4-src.tar.gz?modtime=1151786092& $ tar xvzf linux-2.6.11.tar.gz $ tar xvzf coLinux-0.6.4-src.tar.gz■ coLinux用のパッチをあてる
$ cd /usr/src/linux-2.6.11 $ patch -p1 < ../coLinux-0.6.4/patch/linux■ 設定ファイルのコピー
$ cd /usr/src/linux-2.6.11 $ cp ../coLinux-0.6.4/conf/linux-config ./■ LVMを有効にする
$ make menuconfig
上記コマンド発行後、組み込むモジュールなどを指定する画面が起動するので、「Load an Alternate Configuration File」でlinux-configを読み込み、「Device Drivers --->」→「Multi-device support (RAID and LVM) --->」の順に進み、「Multiple devices driver support (RAID and LVM)」と「Device mapper support」を有効にします。
これで、LVMに必要なモジュールが取り込まれます。ここまできたら、コンパイルの準備完了です。
$ cd /usr/src/linux-2.6.11 $ make-kpkg --revision=colinux-2.6.11-1 kernel_image kernel_headers $ make vmlinux $ mv /lib/modules/2.6.11-co-0.6.4/ /lib/modules/2.6.11-co-0.6.4.old $ cd /usr/src $ dpkg -i kernel-image-2.6.11_colinux-2.6.11-1_i386.deb
で、作成された/usr/src/linux-2.6.11/vmlinuxをcoLinuxをインストールしたフォルダにあるそれと差し替えます。 coLinuxを再起動して問題なければ、カーネルの再構築は完了です。ちなみに、カーネルのコンパイルは30分くらいかかりました。
apt-getで必要なパッケージを取得します。
$ apt-get install lvm2
これでLVMが使えるようになっているはずです。
記憶装置として使うためのイメージを必要なだけ作成 or 取得します。
■ イメージファイルの取得僕は、こちらのサイトが公開している2Gのイメージを2つ用意しました。自分で作りたいかたは、こちらを参考にすれば良いと思います。
■ 設定ファイルの編集新たに使用するイメージファイルをcoLinuxの設定ファイル(xmlファイル)に追加します。
<!-- 既存の設定 --> <block_device index="0" alias="hda1" path="\DosDevices\c:\coLinux\root_fs" enabled="true" /> <block_device index="1" alias="hda2" path="\DosDevices\c:\coLinux\swap_256Mb" enabled="true" /> <!-- 既存の設定 --> <!-- ここを追加 --> <block_device index="2" alias="hda3" path="\DosDevices\c:\coLinux\hda3" enabled="true" /> <block_device index="3" alias="hda4" path="\DosDevices\c:\coLinux\hda4" enabled="true" /> <!-- ここを追加 -->
編集が終わったら、coLinuxを再起動します。
LVMを使用するには、まず始めにパーティションを物理デバイス(Physical Volume)として登録しなければなりません。その場合、使用するパーティションのパーティションIDを「Linux LVM」に指定する必要があるのですが、coLinuxではその必要はないようです。この辺はたぶんcoLinuxのイメージファイルの扱いを知る必要があると思うのですが、それをいま追求してもあれなので、とりあえず気にしません。いきなりイメージファイルを物理デバイスとして登録します。
$ pvcreate /dev/hda3 /dev/hda4 Physical volume "/dev/hda3" successfully created Physical volume "/dev/hda4" successfully created■ ボリュームグループ(VG)の作成
ボリュームグループ(Volume Group)は仮想的なハードディスクみたいなものです。このあと、仮想的なパーティションをボリュームグループから切り出して、実際に使用するイメージです。ボリュームグループは1つ以上のPVから作成することができます。また、後からボリュームグループに物理ボリュームをを追加することも出来ます。
$ vgcreate vg_test /dev/hda3 /dev/hda4 Volume group "vg_test" successfully created■ 論理ボリューム(LV)の作成
ボリュームグループから、論理ボリューム(Logical Volume)を作成します。論理ボリュームは仮想的なパーティションです。この上にファイルシステムを作成したりします。ここでは、5MバイトのLVを作成してみます。
$ lvcreate -L5M -ntest vg_test Rounding up size to full physical extent 8.00 MB Logical volume "test" created
デフォルトのPhysicalExtentSize(LVMで扱うデータの最小構成で、ファイルシステムのブロックサイズのようなものです。VG作成時に指定することができます。)が4Mバイトとなっているので、8MバイトのLVが作成されています。
■ ファイルシステムの作成論理ボリューム(LV)上にファイルシステムを作成してみます。
$ mkfs.ext3 /dev/vg_test/test mke2fs 1.27 (8-Mar-2002) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 2048 inodes, 8192 blocks 409 blocks (4.99%) reserved for the super user First data block=1 1 block group 8192 blocks per group, 8192 fragments per group 2048 inodes per group Writing inode tables: done Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 34 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
で、仕上げにこれを/root/lvm_testにマウントしてみます。
$ mount -t ext3 -o noatime /dev/vg_test/test /root/lvm_test
LVがマウントされていることを確認します。
$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/hda1 4127424 2547380 1370380 66% / cofs0 52428092 33682664 18745428 65% /mnt /dev/vg_test/test 7931 1043 6479 14% /root/lvm_test
ここまででLVMが問題なく使用できることを確認できました。LVM自体の話しだと、他にも設定ファイルの編集だとかでいろいろあるのですが、それは検索すればすぐ出てきますので、ひとまずはここまでをまとめておきました。
カーネルのコンパイルは予想していたよりもあっさりいったのですが、coLinuxの起動時に以下のようなエラーが出て大変な目にあいました。
C:\coLinux>colinux-daemon.exe -c colinux.xml Cooperative Linux Daemon, 0.6.4 Compiled on Mon May 29 22:19:09 2006 mapping cobd0 to \DosDevices\c:\coLinux\root_fs mapping cobd1 to \DosDevices\c:\coLinux\swap_256Mb mapping cobd2 to \DosDevices\c:\coLinux\fs_2048Mb mapping cofs0 to \DosDevices\C: colinux: error, expected gcc version 3.4.x, got 3.3.x error initializing daemon: exit code 88669c14 daemon: error - CO_RC_ERROR_COMPILER_MISMATCHED, line 423, file colinux/user/daemon.o (67)
こちらの日記によると、
ということらしいです。へー。colinux-daemon.exeが、自分自身をコンパイルしたgccのバージョンとvmlinuxのそれを比べ、違いがあるとエラーを表示して起動失敗となる模様。