Monthly Archives: 3月 2012

宅鯖FreeBSDを節電しよう

Pocket

はいはいはいドーモそういうわけでですね、自宅鯖の節電をやっていきたいわけですけれども。

9.0-RELEASEのIntelで実施しましたので共有。

AMDでも9.xならなんとかできそう。

しかし8.xかつAMD CPUの方は解散で。

ただ、MLなどをつらつら見ていると、以下の設定を行っても効果がでないケースもあるようなので各自調整のこと。(例: C2よりC3の方がなぜかCPU温度が上がるとか)

やること。

やることをさっさと書く。

CPU throttlingを無効に。

/boot/loader.confで指定。

具体的にはp4tccを無効に。sysctlで調べて複数あればすべてつぶすこと。

以下の例では二つ。

$ sysctl -a|grep "p4tcc"
dev.p4tcc.0.%desc: CPU Frequency Thermal Control
dev.p4tcc.0.%driver: p4tcc
dev.p4tcc.0.%parent: cpu0
dev.p4tcc.0.freq_settings: 10000/-1 8750/-1 7500/-1 6250/-1 5000/-1 3750/-1 2500/-1 1250/-1
dev.p4tcc.1.%desc: CPU Frequency Thermal Control
dev.p4tcc.1.%driver: p4tcc
dev.p4tcc.1.%parent: cpu1
dev.p4tcc.1.freq_settings: 10000/-1 8750/-1 7500/-1 6250/-1 5000/-1 3750/-1 2500/-1 1250/-1

以下のように。

/boot/loader.conf:
hint.p4tcc.0.disabled=1
hint.acpi_throttle.0.disabled=1
hint.p4tcc.1.disabled=1
hint.acpi_throttle.1.disabled=1

C-states設定

/etc/rc.confに設定を加え、C3まで落ちるようにする。

RELEASE、CPUに応じて/boot/loader.confに追加の設定を加える。

9.x, intelの場合

/etc/rc.conf:
performance_cx_lowest="C3"
economy_cx_lowest="C3"

8.x, intelの場合

/etc/rc.conf:
performance_cx_lowest="C3"
economy_cx_lowest="C3"
/boot/loader.conf:
hint.apic.0.clock=0
kern.hz=100
hint.atrtc.0.clock=0

9.x、AMDの場合

/etc/rc.conf:
performance_cx_lowest="C3"
economy_cx_lowest="C3"
/boot/loader.conf:
hint.apic.0.clock=0

再起動。

sysctlで確認

p4tccが表示されない。

$ sysctl -a|grep p4tcc
$

C3が有効になっていて、再起動直後ということもあるけど、システムがほとんどC3ステートにいることが分かる。

$ sysctl -a|grep cx
hw.acpi.cpu.cx_lowest: C3
dev.cpu.0.cx_supported: C1/1 C2/1 C3/57
dev.cpu.0.cx_lowest: C3
dev.cpu.0.cx_usage: 0.00% 0.06% 99.93% last 432us
dev.cpu.1.cx_supported: C1/1 C2/1 C3/57
dev.cpu.1.cx_lowest: C3
dev.cpu.1.cx_usage: 0.00% 0.10% 99.89% last 907us

上記設定の意味

ではその意味などを。

1: CPU throttlingの停止について

powerdはCPUの周波数変更(CPU throttling)とEISTの組み合わせ。

周波数変更は単純に周波数だけ変更する。

EISTは周波数と電圧を変更する。

前者の周波数変更は、どうも周波数を実際に「落とす」わけではなく、周波数はそのままに「動作をするのはクロック8回に1度な」というように単に動作タイミングを間引いているだけらしい。

したがって、発熱を抑える効果はあっても(CPU Frequency Thermal Control)、電力消費を抑える効果は薄い。

効果のない選択肢があっても無駄なだけなのでバッサリ切る。

2: C-statesの設定

C-statesは以下の通り。

下に行けば行くほど節電できる。システムは低負荷時にあらかじめ設定されたC-states(C状態)まで動作を落とす。

デフォルトはC1。C2, C3まで落とすようにするには/etc/rc.confで指定する。

C1: CPUコアの一部のクロックを停止する。

C2: CPUコアのクロックを停止する。

C3: CPUの内部クロック停止、電圧を下げ、システムバスから切り離す。

2-1: AMDの制限

AMDの場合、詳細なC StatesはOSに対して隠蔽される。代わりにC1Eというstateがある。

OSからはマシンがC2にいようが、C3にいようが、C1Eとしてしか分からない。

後述するようにC3ではタイマーに関しての考慮が必要になるのだが、OSから見えないのではどうにもできない。したがってAMDとRELEASEの組み合わせにより、具体的には8.xとAMD CPUではC1Eへの移行が抑止される。

2-2: OS, RELEASEの組み合わせごとのC3の設定

節電の観点ではC3が一番良いが、この状態だとAPICタイマーも機能しなくなる。

APICタイマーが止まるとスケジューリングが出来ず、復帰もできなくなる。

したがって、APIC以外のタイマーを使う必要がある。

RELEASE、CPUにより回避策に違いが生まれる。

8.x intelにおいては、APICを使うこと自体を止めれば別タイマ(i8254, RTC)を使ってくれる。

ただ、C3からの復帰に時間がかかってしまうので(といってもusのレベル)、/boot/loader.confで調整を行う。

9.x intelにおいては、eventtimersという適切なタイマを選んでくれる仕組みがあるので特に考慮不要。

8.x amdにおいては、

OSから分からないところでC3に遷移してAPICタイマを止められてはかなわないので、OSレベルでC1E機能が抑止される。

つまりC-statesによる節電は無理。これが解散の理由。

9.x amdにおいては、

APICタイマが有効なときのみC1E機能が抑止される。

だからAPICタイマを無効にすればOK。

参考

CPU throttling

http://en.wikipedia.org/wiki/Dynamic_frequency_scaling

C-States

http://okwave.jp/qa/q4539201.html

EIST

http://ja.wikipedia.org/wiki/Intel_SpeedStep_%E3%83%86%E3%82%AF%E3%83%8E%E3%83%AD%E3%82%B8

No tags for this post.

FreeBSDをインストールしたらやること。(no GUI編)

Pocket

FreeBSDをインストールしてやることをまとめたよ。

まずrootでログイン

シェル、sudo、screen、vim-lite(日本語OKなvi)をインストール。

# pkg_add -r bash sudo screen vim-lite

以降、viはvim等と読み替えておくれ。

# vipw

自アカウントのシェルを変更。

# vi /etc/group

wheelに自アカウントを追加。

sudoが使えるように。

これ以降、原則としてrootは使わない。

# visudo
(以下の%wheelの行をアンコメントする。)
## Uncomment to allow members of group wheel to execute any command
%wheel ALL=(ALL) ALL

自分のアカウントでログイン。

ホームディレクトリの.profileに以下を追加。

言語設定とパッケージの取得先変更。

#
# modified
#
LANG=ja_JP.UTF-8;export LANG
PACKAGEROOT="ftp://ftp2.jp.freebsd.org";export PACKAGEROOT

上記設定を読み込み。

$ . ~/.profile

portsの更新

$ sudo vi /etc/portsnap.conf
(portsnapの取得先をfreebsd.orgからallbsd.orgへ変更(感謝))
#SERVERNAME=portsnap.FreeBSD.org
SERVERNAME=portsnap.allbsd.org

既存のportsは一回捨てる。

rmするのも時間がかかるので、いったんmvして消す。

で、portsnapで取り直し。

$ sudo mv /usr/ports /usr/ports.org
$ sudo rm -Rf /usr/ports.org
(このあとバックグラウンドにするとよい)
$ mkdir /usr/ports
$ sudo portsnap fetch extract

時間がかかるのでさらにターミナルを起動。

起動時のサービスの設定

$ sudo vi /etc/rc.conf
以下を(なければ)追加。
sshd_enable="YES"
powerd_enable="YES"	#低負荷の時にクロック等を下げる
powerd_flags="-a adp -n adp"
ntpdate_hosts="ntp.jst.mfeed.ad.jp"	#時刻合わせ
ntpdate_enable="YES"
#sendmail swtich. see rc.sendmail(8) sendmailを止める。
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

powerd, ntpdateを起動。sendmailはまあ…後で再起動か。

$ sudo service powerd start
$ sudo service ntpdate start

locateデータベースの作成

放っておけば一週間に一回更新してくれるのだが、すぐに使いたいので。

$ sudo /etc/periodic/weekly/310.locate

あとはports管理とか。

$ sudo pkg_add -r psearch pkg_replace portmaster portaudit

でかい言語系。

$ sudo pkg_add -r perl python

とりあえずこんなもん。

No tags for this post.

起動スクリプト操作コマンドservice(Linuxのchkconfigの簡易版)

Pocket

FreeBSDにおいて、各種サーバソフトウェアの起動・停止を行う起動スクリプトは/etc/rc.d、/usr/local/etc/rc.dに格納されている。

いちいち/usr/local/etc/rc.d/apache22 startなどとキーを叩くのは面倒で仕方がない。

そこでportsにあるbsdadminscriptsなどを使っていたのだが、ふと気が付くと7.3あたりからserviceというコマンドが作られたようだ。

使い方。

書式。

 service <起動スクリプト> start|stop|restart等々

使用例

$ sudo service dovecot status
Password:
dovecot is running as pid 1026.
$ sudo service dovecot restart
Stopping dovecot.
Waiting for PIDS: 1026.
Starting dovecot.

注意点としては、引数で与えるのはあくまでも起動スクリプト名であって、サーバソフトウェアの名前ではない、という点。

例えば、dhcpdだとisc-dhcpdで指定しないといけないが、それを思い出せないこともしばしば。

だから後述の使用法も使って、起動スクリプト名を調べるとよい。

そのほかの使い方:起動スクリプトに関する情報が得られる。

service -e
 有効になっているサービスを表示する。
 起動順(rcorder)に表示
service -r
 無効になっているものも含めてサービスを表示する。
 起動順(rcorder)に表示。
 もちろん無効になっているものは、もしも有効だったら
 という仮定で。
service -l
 rc.dディレクトリの下にあるファイルをすべてリストする。
 /etc/rc.dのほか、たとえば/usr/local/etc/rc.dなど。
-v
 ほんの少しだけ説明が増える。
 (試してみたら本当に少しだけだった)

例えば。-rだと、-eのときにはない起動スクリプトも表示されていることが分かる。

$ service -e|grep "/usr/local"
/usr/local/etc/rc.d/mrtg_daemon
/usr/local/etc/rc.d/jenkins
/usr/local/etc/rc.d/dovecot
/usr/local/etc/rc.d/clamav-clamd
/usr/local/etc/rc.d/clamav-freshclam
/usr/local/etc/rc.d/apache22
$ service -r|grep "/usr/local"
/usr/local/etc/rc.d/svnserve
/usr/local/etc/rc.d/rsyncd
/usr/local/etc/rc.d/rrdcached
/usr/local/etc/rc.d/munin-node
/usr/local/etc/rc.d/mrtg_daemon
/usr/local/etc/rc.d/jenkins
/usr/local/etc/rc.d/htcacheclean
/usr/local/etc/rc.d/dovecot
/usr/local/etc/rc.d/clamav-clamd
/usr/local/etc/rc.d/clamav-freshclam
/usr/local/etc/rc.d/apache22
No tags for this post.

ZFSの重複ファイル節約機能dedupがすげえ(ただしメモリ大尽に限る)

Pocket

最初にお断りするが、十分なメモリ、あるいはSSDをお持ちでない方は帰っていただいて結構です。

 

Dedupとは

ZFSにはdedupという機能がある。

その機能を有効にすると、例えばここに1GBのファイルが一つあるとして、それをコピーしても、場所が同じpool内である限り、1GBのディスクしか消費しない。

 

何それただのハードリンクと思うのは早い。

 

仮に同一のファイルA, Bがあるとする。いずれも1GB。

ハードリンクすればディスク消費量は1GBだ。

さてここで、ファイルBの一部、1bitだけを変えたいとする。

もはやハードリンクはできず、別個のファイルとして扱うことになる。

したがってディスク消費は2GB。

 

ではdedupだとどうなるか。

1bit違う1GBのファイル二つがあっても、なんと1GBと128KBだけしかディスクを消費しないという驚きの仕組み。

 

どういうことかというと、dedupはファイルが同じかどうかをブロックごとに判断するということ。

先の例でいえば、異なる1bitを含むブロック分だけを追加で確保し、それ以外はファイルAと同じものを使う。

なお、ZFSでブロックサイズは512B~128KB。

つまり大目に見積もっても1GBと128KBだけの消費でよいわけ。

 

種明かし:テーブルと大量のメモリ

なぜそんなことができるのか。

ZFSはプール上にあるデータのすべてのブロックのハッシュをメモリ上に持っている。

あるファイルをディスクに書き込む前に、ファイルをブロックに分解しハッシュテーブルと照合、書き込み要否を判断するという仕組み。

 

問題はメモリ上に置くテーブルのサイズだ。

dedupを有効に使うには、テーブルを置けるほど十分なメモリが必要になる。

しかし、のちほど見積もりをするが、数TBのディスクを考えるとメモリで賄うのは少々厳しい。

当然、メモリをこればっかりに使うわけにもいかないのだし。

もちろん、テーブルをハードディスクに置くことはできるが、ファイルを書き込むたびにディスク上のハッシュテーブルを参照することになる。

つまりすっごく遅くなる。

よろしい。ならばSSDだ。

とはいえ、Dedupの目的がディスクの容量節約ならば、安いHDDケチってメモリ、SSD無理して買うのも本末転倒という話になってくる。

月並みだけど、よく考えた方がいいよね。

 

Dedupの見積もり。

では仮に2TBのデータが詰まったZFSでDedupしたら、どれくらいのメモリが必要か。

ハッシュテーブルは1ブロックにつき320Bytes。

zfsのブロックサイズは512Bから128KBで可変。

ざっくり64KBとみなす。

では計算。

 

2TB=1024 * 1024 * 1024 * 2 = 2147,483,648KB。

2TB/64KB=33,554,432 blocks

2TBは33,554,432 blocks。

1blockあたり320Bytesなので、かければテーブルに必要なサイズが出る。

 

33,554,432 blocks * 320 Bytes = 10,737,418,240 = 10GBytes

 

はい解散。

と言いたくなるレベルですな。

念のため記載するが、上記は2TBのデータを使っているときのdedupテーブルの試算。

2TBのプールに100bytes程度のファイル一つ置いただけなら、ハッシュテーブルは320Bytes程度。

 

Dedupの活きる道

そもそも2TB全部にDedupするのが間違いであった。

Dedupを活かしたいなら、扱うファイルで決めるのも手。

ざっくり言えばオフィスドキュメント、仮想マシンイメージなど、重複が見込まれるファイルを多く保管するディレクトリに対してのみDedupするとよいでしょう。

一方で動画などはあまり有効ではないでしょう。

なお、プールでDedupするとどれくらい得か、というのは調べることができる。

zdbにプール名を与えてやればいい。

一番下に重複具合が表示される。以下の例では1.06。あまり意味はないってことですな。

ちなみに、あるプールに同一のファイルを3つだけ置くとここが3.00になる。

$ sudo zdb -S vault
パスワード:
Simulated DDT histogram:
bucket              allocated                       referenced
______   ______________________________   ______________________________
refcnt   blocks   LSIZE   PSIZE   DSIZE   blocks   LSIZE   PSIZE   DSIZE
------   ------   -----   -----   -----   ------   -----   -----   -----
1    8.22M   1.02T   1.02T   1.02T    8.22M   1.02T   1.02T   1.02T
2     406K   50.6G   50.6G   50.6G     815K    102G    102G    102G
4      185   17.1M   17.1M   17.1M      835   73.6M   73.6M   73.6M
8      146   14.2M   14.2M   14.2M    1.75K    182M    182M    182M
16       17   8.50K   8.50K   8.50K      407    204K    204K    204K
32      150   16.7M   16.7M   16.7M    5.43K    600M    600M    600M
64        9    132K    132K    132K      820   9.49M   9.49M   9.49M
128        6      3K      3K      3K    1.02K    521K    521K    521K
256        3    129K    129K    129K      884   40.5M   40.5M   40.5M
64K        1    128K    128K    128K    73.4K   9.18G   9.18G   9.18G
Total    8.62M   1.07T   1.07T   1.07T    9.10M   1.13T   1.13T   1.13T
dedup = 1.06, compress = 1.00, copies = 1.00, dedup * compress / copies = 1.0

DedupのONのしかた

まあzfs set dedup=ONとかすればいいんだけど、現状使う予定もないので詳しく調べてない。

No tags for this post.

trは一文字ごとに判断する件について

Pocket

$ cat sample.txt
<a><b>

上記のテキストに対して以下のtrを実行するとどうなるか。

tr "ab" "cd"

試してみる。

$ tr "ab" "cd" < ./sample.txt
<c><d>

げえっ。

つまり、trは1文字ずつ判断する。

 a→cに変わり、

 b→dに変わる。

 ※「ab」を置換しない点に注意。

応用。

同じファイルに対して。

$ tr -d "<>" < sample.txt
ab

「<>」ではなく「<」「>」を消去していることに注意。

No tags for this post.

/var/logの下がえらいことになっていたでござる。(あるいはFreeBSDでログのローテーション設定をするには(logrotateではなくnewsyslog))。

Pocket

ある日、ふと/var/logの下を見てみたら、1.5GBytesに膨れ上がった某ログファイルがあって腰を抜かした件について。

思えば、サーバソフトウェアなどでは、インストールしたらまずそのものの設定で頭が一杯だ。

一方で、いわゆるシモの世話といいますか、吐き出すログの設定には頭が回ってなかったことに深く反省するのであります。

俺の例でいえば、apache、clamav、dhcpdのログが手つかずでありました(冒頭、1.5GBytesになっていたログはdhcpdのもの)。

portsから入れたサーバのログは、いちど確認したほうがいいだろう。

基本は/var/logの下に出力されるが、/usr/local/var/logが(あれば)見た方がいいし、場合によっては思わぬところに吐き出されてる可能性もある。

newsyslogd

さて、FreeBSDではログのローテートはnewsyslogdが行う。Linuxではlogrotateにあたるもの。

handbookではこのへん

英語(推奨)

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/configtuning-configfiles.html

日本語

http://www.freebsd.org/doc/ja_JP.eucJP/books/handbook/book.html#CONFIGTUNING-CONFIGFILES

newsyslogの設定サンプル

man newsyslog.confを見ればだいたい分かる。以降、英文はここからの引用。

http://www.freebsd.org/cgi/man.cgi?query=newsyslog.conf&apropos=0&sektion=0&manpath=FreeBSD+9.0-RELEASE&arch=default&format=html

以下の順番で並べるだけ。間はスペースで埋めること(separated with whitespace)。

# filename          [owner:group]    mode count size when [ZB] [/pid_file] [sig_num]

以下、サンプル。

/var/log/local7.log    600  10 1024 * JC

/var/log/local7.logが、1MBytesを超えた時点でローテーション。

生成されたログのパーミッションは600で、bzip2で圧縮され(J)、10個保存される。

/var/log/httpd-access.log    644  7 * @T03 JC

apacheのログを毎日午前3時にローテーション、圧縮して7日分残す。

設定を変えたらnewsyslogdを再起動。

# /etc/rc.d/newsyslog restart
Creating and/or trimming log files.
#

設定について

filename

 その名の通り。

[owner:group]

 省略可。アーカイブ後ファイルの所有ユーザとグループ

mode

 ログファイルとアーカイブ後ファイルのパーミッション。

 サーバソフトが作るオリジナルのパーミッションと合わせておくのがよい。

 というのも、newsyslogdがログをローテーションするときに新しいログファイルを作るから。

 owner:groupにはなく、こちらにだけ「ログファイル」という記載があるのはなぜでしょうな。

count

 残す「アーカイブ後の」ログファイル数。

 3なら、アーカイブされたログが3つになる。

size

 このサイズを超えたときにローテーションされる。

 キロバイトで指定。

 アスタリスク(*)の場合には、サイズベースでのローテーションはしない。

when

 ローテーションする時間、時刻契機を指定。

 インターバル、時刻を指定できる。

 書式は二つ。後述する。

 注意すべき点は、newsyslog自体が一時間に一回しか起動しないこと。

 これはつまり以下のような動作となる、と理解した。

 ・仮に、newsyslogdが毎時0分に起動し、かつ

 ・毎時1分にローテーションする設定にした場合、

 →例えば、1時1分ではなく、2時にローテーションが発生する。

newsyslog.conf(5)より抜粋

If a time is specified, the log file will only be trimmed if newsyslog(8) is run within one hour of the specified time. If an interval is specified, the log file will be trimmed if that many hours have passed since the last rotation.

 書式

 @で書くもの、$で書くものの二つ。

 @は、[cc]yy]mm]dd][T[hh[mm[ss?]

 $は、[Dhh], [Ww[Dhhと[Mdd[Dhh

 サンプルを見るのが一番よい。(これもmanから抜粋)

 $D0 毎日午前0時。@T00と同じ意味

 $D23 毎日23時。@T23と同じ意味

 $W0D23 毎週日曜23時

 $W5D16 毎週金曜16時

 $M1D0 毎月1日の午前0時。@01T00と同じ意味

 $M5D6 毎月5日の午前6時。@05T06と同じ意味

flags 一部のみ。基本JCでよい。

 J ログをbzip2で圧縮。Zならgzip。Xならxz。

 C ログが存在しない場合に作る。

 G パターンにマッチしたログファイルを対象にできる。

 

pid_file

 通常、ログをローテーションした後はsyslogdにシグナルが送られる。

 syslogd以外のプロセスにシグナルを送りたい場合には、プロセスの

 pidが書かれたファイルをここで指定する。

以上

No tags for this post.

ZFS優しすぎ涙がでた。

Pocket

前口上

試しにZFSを使ってみて(VMware Playerで気軽に試せるようになったとは、なんと便利な世の中か)本当に驚いた。

ディスク繋いでzpoolコマンド一発ですぐ使える。パーティションに頭を悩ませる必要もない。RAIDだって楽勝。ディレクトリごとに圧縮することもできるし、気が変わったら、いつでも止めることもできる。スナップショットも早い。

実は、何年か前にZFSについて調べたときはまだまだバギーな印象だったのと、ZFSを使えるようなパワフルマシンがなく保留にしてたんだけど、すごく損した気分。

いままで幾たび、fdiskやnewfs失敗してひどい目にあったことか。電子の海に消えたデータを思う。

 

そしてRAID。ソフトRAIDで言えばlvmも有名だが、俺にはもうコマンドが複雑すぎて覚えられない(lv…が論理ボリュームを、pv…が物理ボリュームを扱うんだって?)。

これはすごく危険。

だってソフトRAID含め、こういったディスクを扱うコマンドを使うのは、初期設定と、問題の発生したとき。

俺みたいなオッチョコチョイが、問題が発生して焦っているときに、コマンドが複雑だと二次災害を引き起こすんだって。

…正直に言うと実際に引き起こした。

 

ZFSならとにかくzpool、zfsさえ覚えておけばいいのだ。

 

ZFS

宅鯖ではZFSを使いたいからFreeBSDを選んだ。

そして、いろいろwebを渉猟するにi386でZFSは辛そうなのでamd64とし、下記の通りzpoolのバージョンもどーんと上がっているので, 9.0-RELEASEを入れた。メジャーバージョンの最初はちょっと不安ではあるけれど。

ZFSのバージョン

8.2+ – zpool v15

9.0+ – zpool v28

あとは、特に難しいこともなく、2.5Tのディスク1本買ってきて、つないで、領域作って、こんな感じ。

作業ログは後述。

$ sudo zpool status
パスワード:
pool: vault
state: ONLINE
scan: none requested
config:
NAME        STATE     READ WRITE CKSUM
vault       ONLINE       0     0     0
ada1      ONLINE       0     0     0
errors: No known data errors
$ zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
vault  2.27T  1007G  1.28T    43%  1.00x  ONLINE  -

 

ディスク1本なので、RAIDも組まず、圧縮もせず(データがjpg写真とか自炊本、自炊DVD、CDとか圧縮の効かないものばかりだから)。

あんなに煽っておいてアレだが、だってまだディスク高いし・・。

 

チューニング

ただまあ、ここを見てチューニングだけはしておいた。

http://wiki.freebsd.org/ZFSTuningGuide

 

/boot/loader.confにおけるチューニング

vfs.zfs.prefetch_disable="1"
vfs.zfs.txg.timeout="5"

1行目

ZFSのprefetchを無効にすると全体的にスピードが向上する。

ただし読み書きが頻繁に発生する状態だとシステムが遅くなる傾向あり。

なお、4GB以上のメモリが実装されているとデフォルトで0になるとのこと。

2行目

txgが何の意味か分からないけど(task queue?)、こうしておくとスループットが上がる上に、システムが極端に遅くなる問題が改善される。

(In my case 50-100% CPU is used by ZFS with *no* disk activity during the pauses then a burst of rapid disk activity and then another pause. なんて言ってる)

なお、これはZFS v28からはデフォルト。

 

/etc/sysctl.confにおける設定

kern.maxvnodes=250000
vfs.zfs.write_limit_override=131072

1行目でvnodes数の上限をデフォルトの約200000(a little over 200,000)から増やす。

2行目でTXG write limitの値を減らす。デフォルト値は知らん。

4GBメモリなら256MB、と書いてあるので、2GBを積んでる俺は128MBにした。

なお、ZFS v28より前ではvfs.zfs.txg.write_limit_overrideとのこと。

そのほかの設定:periodic script

/etc/periodic/daily/404.status-zfsにスクリプトがある。

有効にすると、毎日zpoolの状態をしらべて、daily output, security outputでメールしてくれる。

そうそう、root宛のメールは転送設定しておくと便利。

$ sudo /etc/periodic/daily/404.status-zfs
Checking status of zfs pools:
all pools are healthy

 

/etc/periodic.confに以下を追記しておけばOK

daily_status_zfs_enable="YES"

 

以下は作業ログ

作業ログ

ディスクをつないで起動、dmesgで確認

$ dmesg|grep ada
ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
ada0: <VB0250EAVER HPG7> ATA-8 SATA 2.x device
ada0: 300.000MB/s transfers (SATA 2.x, UDMA5, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 238475MB (488397168 512 byte sectors: 16H 63S/T 16383C)
ada0: Previously was known as ad4
ada1 at ahcich1 bus 0 scbus1 target 0 lun 0
ada1: <WDC WD25EZRX-00MMMB0 80.00A80> ATA-8 SATA 3.x device
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 2384658MB (4883781168 512 byte sectors: 16H 63S/T 16383C)
ada1: Previously was known as ad6

ada1が新しく繋いだディスク。

ここにZFS用のpoolを作成する。

$ sudo zpool create vault ada1
Password:
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault on /vault (zfs, local, nfsv4acls)
$ df -h
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/ada0p2    228G     15G    194G     7%    /
devfs          1.0k    1.0k      0B   100%    /dev
vault          2.2T     31k    2.2T     0%    /vault

 

無事完成。

なんと勝手にマウントまでしてくれる。これですぐ使える。

2.5Tなのに数秒程度で完了。

ビクビクしながらfdiskしたりnewfsしたりする必要がない。電卓も要らない(そういう時代もあったのです)。

衝撃的です。

コマンドが簡単なうえに、早いというのは、重ねて言うけど障害復旧に極めて有利な点。

大きなディスクをnewfsするときの、遅々として進まないカウンタを見てジリジリしたことのある人なら共感してくれるはず。

 

なお、この状態では/etc/fstabに何も書き込まれていないので、再起動すればマウントは外れる。

 

ではこのpoolからディレクトリを切り出す。

itunes用と、通常の共有ディレクトリ用の二つを作る。

 

$ sudo zfs create vault/itunes
$ sudo zfs create vault/chamber
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault on /vault (zfs, local, nfsv4acls)
vault/itunes on /vault/itunes (zfs, local, nfsv4acls)
vault/chamber on /vault/chamber (zfs, local, nfsv4acls)
$ df -h
Filesystem      Size    Used   Avail Capacity  Mounted on
/dev/ada0p2     228G     15G    194G     7%    /
devfs           1.0k    1.0k      0B   100%    /dev
vault           2.2T     32k    2.2T     0%    /vault
vault/itunes    2.2T     31k    2.2T     0%    /vault/itunes
vault/chamber    2.2T     31k    2.2T     0%    /vault/chamber

 

これらを/export配下に移動させる。

これが既存の考えにはない動作。頭の中でファイルシステムに対する考え方がグニョっとなるのを俺は感じたよ。

 

$ sudo zfs set mountpoint=/export/itunes vault/itunes
$ sudo zfs set mountpoint=/export/chamber vault/chamber
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault on /vault (zfs, local, nfsv4acls)
vault/itunes on /export/itunes (zfs, local, nfsv4acls)
vault/chamber on /export/chamber (zfs, local, nfsv4acls)

そしたら/etc/fstabに書き込んでおしまい。

昔はデバイス名を書き込んでいた場所にZFSのディスクプールを書くわけですな。

vault/itunes    /export/itunes         zfs     rw      0       0
vault/chamber   /export/chamber                zfs     rw      0       0

afpでファイルをコピーしているのだが、あまり負荷はかかっていない模様。

ZFSはリソース食いと聞いてたのでコワゴワコピーしたんだけど、まあ100Mbpsのネットワーク越しですしな。

last pid:  1773;  load averages:  0.11,  0.21,  0.17    up 0+00:45:03  23:54:03
42 processes:  1 running, 41 sleeping
CPU:  0.2% user,  0.0% nice, 15.0% system,  0.4% interrupt, 84.4% idle
Mem: 46M Active, 189M Inact, 1426M Wired, 64M Cache, 200M Buf, 119M Free
Swap: 907M Total, 556K Used, 906M Free
PID USERNAME     THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
1697 root           1  31    0 55860K  4288K select  1   3:55 16.36% afpd

そのほか

重大な作業をするときは必ず-nオプションを付けること。

ドライランと呼ばれるもので、実際の作業はせずに結果をシミュレートできる。

 

ストレージプールを作業するときには明示的にexportすること。

exportすれば、未書き込みのデータがすべて処理され、システムから削除される。

そこで引数なしでimportを実行すると、import可能な、言い換えるとexport済みのプールが表示される。

No tags for this post.

FreeBSDにMacのファイル共有プロトコルAFPを喋らす。(追記あり)

Pocket

AFP(Apple Filing Protocol)。

Macのファイル共有はOSXからSMB/CIFSになったと勝手に思いこんでたから驚いた。AppleTalkが今に生きてるとは。

ただ、AFPは下位レイヤにAppletalkじゃなくTCPを使うことができるそうなので納得。

追記:コメントで教えていただきましたが、さいきんAppletalkは死んでしもうたそうです。R.I.P.

UNIX系でAppleTalk互換ソフトウェアといえばNetatalk。

Macでファイル共有するなら正直SMB/CIFSでいいかなとも思ったが、どうもNetatalkの方が軽いと聞いたので、試しに使ってみる。

iTunesのライブラリも置いてみたいのだ。

netatalkには、AFPデーモンのafpd、CNID管理のcnid_metad、appletalkを動かすatalkd、リモートプリントサービスのpapd、Mac向けタイムサーバのtimelordが含まれる。

AFP over TCPで要るのは、afpd, cnid_metadと理解した。

Macのファイル共有で面白いのは各ファイル、フォルダに固有のIDを付けて管理するという点。パスを使わないのだ。これは大昔からaliasという考え方があったせいか。

そして、ホストのファイル、ディレクトリとID(CNID, Catalog Node ID)のくくりつけを管理するのがcnd_metadということらしい。(metaという名前だけに、DBは別にあるのだが)

net/netatalkからインストール

# cd /usr/ports/net/netatalk
# make config
Apple Talkを外す。
# make install clean

苦難の設定

すごく大変だった。

なんかマニュアルがすごく分かりにくく感じる。

共有フォルダ設定はAppleVolumes.defaultを使い、それ以外はnetatalk.conf, afpd.confを使うようだ。

以下を見ながら試行錯誤。

http://netatalk.sourceforge.net/2.2/htmldocs/configuration.html#id1590298

/usr/local/etc/netatalk.confで全般の設定。

変えたのは以下の二点。

#### machine's AFPserver/AppleTalk name.
ATALK_NAME=sylph_osx
#### Set which daemons to run.
#### If you use AFP file server, run both cnid_metad and afpd.
CNID_METAD_RUN=yes
AFPD_RUN=yes

/usr/local/etc/afpd.conf

変更なし。

/usr/local/etc/AppleVolumes.default

ここで共有フォルダの設定。下記において最初の二行はデフォルト。

最後の一行のみ追加した。

~はホームディレクトリだな。

:DEFAULT: options:upriv,usedots
~
/export/itunes itunes

なお、以下にオプションが山ほど。

http://netatalk.sourceforge.net/2.2/htmldocs/AppleVolumes.default.5.html

書式は以下の通り。

<共有フォルダ実パス> <外部への共有フォルダ名> [<オプション>]

オプションでめぼしいものは以下の二つくらいかな。

tm OSXのタイムマシンサポートを有効に。
ro 読み取り専用

複数指定する場合にはたとえば(実際にはtmとroを一緒に使うことはないが)以下のようにカンマ(,)でつなぐ。

/dir/path share options:tm,ro

そうしたら、/etc/rc.confに以下を追加する。

netatalkを動かすにはavahi_daemonが必要で、avahiを動かすにはdbusが必要だからこんな感じ。

なお運用中に設定を変更した場合にはこれらサービスをすべて再起動したほうがいいようだ。

#AFP
dbus_enable="YES"
avahi_daemon_enable="YES"
avahi_dnsconfd_enable="YES"
netatalk_enable="YES"
cnid_metad_enable="YES"
afpd_enable="YES"

で、再起動するか、/usr/local/etc/rc.dで上から順番に起動させればOK。

FreeBSDのnetatalk関連の起動スクリプトは、startさせても何のメッセージも出ないのが不親切だと思う。

macからはafp://<ホスト>の書式でアクセスできる。

運用。安定していないのか?

320GBほどのデータをAFP経由でコピーしたのだが、以下のメッセージが表示されてなかなか終わらない。

何が悪いのだろう?

Mar  6 06:35:22 isis afpd[3237]: afp_disconnect: trying primary reconnect
Mar  6 06:35:22 isis afpd[1695]: Reconnect: transfering session to child[1697]
Mar  6 06:35:22 isis afpd[1695]: Reconnect: killing new session child[3237] after transfer
Mar  6 06:35:22 isis afpd[1697]: afp_dsi_transfer_session: succesfull primary reconnect
Mar  6 06:35:29 isis afpd[3237]: afp_disconnect: primary reconnect succeeded
Mar  6 06:38:18 isis afpd[1697]: read: Operation timed out
Mar  6 06:38:18 isis afpd[1697]: dsi_stream_read: len:-1, Operation timed out
Mar  6 06:38:18 isis afpd[1697]: dsi_stream_send: Broken pipe
Mar  6 06:38:18 isis afpd[1697]: dsi_wrtreply: Broken pipe
Mar  6 06:38:18 isis afpd[1697]: dsi_disconnect: entering disconnected state
Mar  6 06:38:18 isis afpd[1697]: dsi_disconnect: entering disconnected state
No tags for this post.

ssmtpを使ってroot宛のメールをgmailに転送したら便利杉ワロタ。

Pocket

ssmtpとは。

Extremely simple MTA to get mail off the system to a mail hub

なんかね、20年近く前までは、sendmailの設定できるってだけで高給取りだったそうなんですよ。

だからqmailとかpostfixとか生まれたらしいんですがね、もうそんな設定の難しいソフトウェアはベースシステムから取っ払ってほしいんですよ。

で、ssmtpなら設定は簡単だし、gmailがsmtp開放してるってんで、まあ入れてみた。

root宛にメールを送れば、自分のスマホにメールが届くというのは便利杉で驚いた次第。

事前準備: sendmailよRIP

まずsendmailを止める。

# /etc/rc.d/sendmail stop

sendmailが次回以降も起動しないように/etc/rc.confに以下を追記。

君にはお世話になった。

#vi /etc/rc.conf
(以下を追記)
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

ssmtpをインストール

# cd /usr/ports/mail/ssmtp
# make install clean
# make replace

最後のreplaceは/etc/mail/mailer.confを修正して、sendmailをssmtpに置き換えてくれる。

sendmailは他のたくさんのプログラムがアクセスするからね。

/etc/mail/mailer.confを見ると、何が変わったかがわかる。

make replace後の/etc/mail/mailer.confの内容
#sendmail       /usr/libexec/sendmail/sendmail
#send-mail      /usr/libexec/sendmail/sendmail
#mailq          /usr/libexec/sendmail/sendmail
#newaliases     /usr/libexec/sendmail/sendmail
#hoststat       /usr/libexec/sendmail/sendmail
#purgestat      /usr/libexec/sendmail/sendmail
sendmail        /usr/local/sbin/ssmtp
send-mail       /usr/local/sbin/ssmtp
mailq           /usr/local/sbin/ssmtp
newaliases      /usr/local/sbin/ssmtp
hoststat        /usr/bin/true
purgestat       /usr/bin/true

ssmtpの設定

ここでroot宛のメールをgmailに転送する設定をする。

/usr/local/etc/ssmtp/ssmtp.confを作成

root=youremail@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=youremail@gmail.com
AuthPass=yourpassword
UseSTARTTLS=YES

実験

$ mail -v root
Subject: <件名を入れる>
適当な本文
(Ctrl+Dを押す)

これでOK。

No tags for this post.