2011/05/02

EeePC 4G-X + Debian squeeze で SD(SDHC)カード使う

マウント関連 

EeePC 4G-XではSDHCカードが使用できます。
4GBの内蔵SSDでは容量不足のため、/data パーティションは 32GB SDカードにしています。
SDカードを挿入して出力された /var/log/syslog の内容を見ると、/dev/sdb が SDカードスロットだと判明しました。
(同じLinuxやDebianでもバージョンが異なると対応するデバイスも異なる可能性があるので、かならず確認して下さい)

ファイルシステムを作成します。
# mkfs -t ext3 /dev/sdb1

/etc/fstabに以下を追記します
/dev/sdb1 /data  ext3 defaults,noatime 0 0

第4フィールドのオプションに 'sync,dirsync' を指定してみたところ、すばらしくパフォーマンスが悪かったので外しました。

lennyの時は shutdown時に正しくsync/umountせずに終了し、毎回ファイルシステムを破壊してしまうために 事前にejectが必要でしたが、squeezeでは改善されて(いまのところは)大丈夫のようです。

 

他サービスとの兼ね合い 

今回、上記のように /data パーティションを SDカードに指定し、その領域にMySQL DBファイルく置く設定にしました。
しかしPC起動時にSDカードをマウントするよりも先に MySQLが起動しようとしてしまい、DBファイルがない旨のエラーが出てしまいました。
解決方法は以下のどちらかです。
  1. MySQLの起動を遅らせる
  2. MySQLより先にSDカードをマウントさせる
今回、/data パーティションは apacheなどの他サービス用のデータも格納しているので前者のような個別対応ではなく、SDカードを先にマウントさせるようにしました。
各種サービスは /etc/rc?.d/S?? で起動されるので、それよりも前にマウントするように設定します。
具体的にはテンプレートファイル /etc/init.d/skeleton を元にして、起動/停止用に /etc/init.d/sdmount というファイルを作成し、S01で他のサービスよりも先に実行させます。その内容は、8秒(根拠はありません)待って、mount -a するだけの簡単なスクリプトです。
今回は手を抜いたので、stop時には特になにもしていません。

#! /bin/sh
### BEGIN INIT INFO
# Provides: sdmount
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: re-mount all device
# Description: /dev/sdb1(SDHC) re-mount after boot
### END INIT INFO

DESC="mount SDHC device"
NAME=sdmount
SCRIPTNAME=/etc/init.d/$NAME

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
#. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
W=8
echo "wait $W sec..."
sleep $W
mount -a

return 0
}

#
# Function that stops the daemon/service
#
do_stop()
{
# D=/dev/sdb1
# sync; sync
# umount $D

return 0
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
return 0
}

case "$1" in
start)
do_start
;;
stop)
do_stop
;;
status|restart|force-reload)
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac




etc/rc?.d から runlevelに合わせてシンボリックリンクを張ります。
一つ目の -n オプション付きは動作確認(dry run)で、実際にリンクは張っていません。
 
# update-rc.d -n sdmount defaults      
update-rc.d: using dependency based boot sequencing
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc0.d/K01sdmount
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc1.d/K01sdmount
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc2.d/S01sdmount
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc3.d/S01sdmount
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc4.d/S01sdmount
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc5.d/S01sdmount
insserv: enable service ../init.d/sdmount -> /etc/init.d/../rc6.d/K01sdmount
insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop

# update-rc.d sdmount defaults
update-rc.d: using dependency based boot sequencing

これで再起動時にも 各種サービスを起動する前に /data をマウントするようになり、エラーは出なくなりました。
本当は、stop時に umount/ejectするスクリプトにして、S01, K99 とするように、以下のコマンドを実行しました。
 # update-rc.d  sdmount start 1  2 3 4 5 . stop 99 0 1 6 .
ですが、なぜかうまくSnn/Knnが認識されず、必ず S01/K01になってしまいました。
K01で umountされてしまうと当初の問題とは逆に、各種サービス起動中にディスクをアンマウントしようとするので(実際にはdevice busyでアンマウントは失敗するはず)、思ったとおりの動きになりません。
個別にシンボリックリンクを張るのも面倒なので、start時だけの処理としました。(手抜きです)

それにしても...
一応 class 10とはいえSDカードをHDDのように使用するには無理があるのか、CPUは遊んでいるのにIOが足を引っ張ってパフォーマンスはかなり悪いようです。
USB経由でSSDを繋いだほうが幸せになれるのでしょうか。

0 件のコメント:

コメントを投稿