2013年12月7日土曜日

CentOS 6.5 のトピックス

CentOS 6.5 で新たに追加された機能等の、自分用メモです。
なんと言っても、個人的には md の TRIM サポートが追加されたことがありがたいです。
https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/6.5_Release_Notes/bh-storage.html
~抜粋~
mdadm での TRIM サポート
mdadm ツールは、RAID0、RAID1、RAID10、RAID5 向けに TRIM コマンドをサポートします。
~~~
SSD を md で束ねたい方に朗報ではないかと思います。md RAID0 (SSD 3台利用) の上に ext4 を作成して試してみましたが、fstrim 出来るようになってました!

<その他に目に留まったもの>
・makedumpfile に LZO と Snappy サポートが追加。ダンプ時間短縮に有効です。

2014-05-11追記
md RAID0 以外でも TRIM が動くのか、RAID1、RAID10、RAID5 も試してみましたが、わたしの環境では RAID1 + ext4 は fstrim 出来ましたが、RAID10 と RAID5 は NG でした。使った SSD は、Plextor の M6M です。hdparm によると、M6M は、RZAT/DRAT の両方が非対応になっているようなので、もしかしたらそこらが関係するのだろうかと思ってます。パッチを読めという話でしょうが、また今度。。

2014-05-12追記
カーネル 2.6.32-431.17.1.el6 の changelog を確認してみたら、RAID5 については、
2013-11-10 12:00:00
Rafael Aquini  [2.6.32-431.el6]:
- [md] Disabling of TRIM on RAID5 for RHEL6.5 was too aggressive (Jes Sorensen) [1028426]
...
2013-10-21 12:00:00
Rafael Aquini  [2.6.32-425.el6]:
...
- [md] Disable TRIM on RAID5 for RHEL 6.5 (Jes Sorensen) [837097]
6.5 の最終段階で、disable にされたようです。何らか、うまく行かないパターンがあったのでしょう。
あと、RAID10 についてですが、先日、実験する際、起動するカーネルを間違えていたようで、オラクル UEKr2 を使っていたせいのようです。あらためて、2.6.32-431.17.1.el6 で再度実験を行ったところ、Plextor M6M の md RAID10 + ext4 は OK でした(fstrim 動きました)。

2013年10月20日日曜日

CentOS 5 + UEK で ZFS on Linux を利用

CentOS 5 で運用しているサーバでも、ZFS on Linux を利用したかったのですが、カーネルのベースバージョンが古く、ビルドできないため諦めていました。もっと新しいバージョンのカーネルを自分でビルドすれば不可能ではないとしても、手間がかかり過ぎますし。

ところが、あまり着目していなかったオラクル社提供の OEL5 (Oracle Enterprise Linux 5) 向けの UEK (Unbreakable Enterprise Kernel) R2 なら、カーネルのベースバージョンが 3.0-stable であることを知り、それならビルドできるのではと、やってみました。
最終的には利用できるようになりましたが、いろいろとトラブルに直面しましたし、もし既に CentOS 5 で運用中で、どうしても ZFS を利用したいということでなければ、やめたほうが良いかと思います。難易度は少し高めではないかと。
わたしが遭遇したトラブルの数々です。
(1) kernel-uek パッケージだけ入れてみたが、UEK カーネル 2.6.39 が起動できない
(2) なんとか UEK カーネルが起動できたが、起動時にシステム時刻が狂う
(3) 起動時に udev のエラーが出る
(4) multipath が動作しなくなり、multipath + LVM のボリュームが正しく初期化できない
(5) CentOS 5 標準のカーネル 2.6.18 系では出ていなかった audit のメッセージが出まくる
(6) 肝心の ZFS のビルド時、dkms がエラーを吐く (ZFS の利用には支障ないようです)
(7) 監視で利用している munin が動かなくなった
(8) KVM ゲスト用にカーネルブートオプションで設定していた hugepage 数が、UEK カーネルではなぜか少し不足した
(9) KVM ゲストの一つが起動できない
(10) UEK カーネルにも ksmd は居るのだが、ksmctl start 出来ない
これらのうち (9) と (10) は未だ解決できておらず、かなりの手間ではありましたが、わたしの場合には、やってみて良かったという印象です。ZFS on Linux 0.6.2 が活用できるようになったのは勿論のこと、CentOS 5 標準カーネルでは提供されない機能(tickless 、zram 、ext4 の discard 、btrfs 等)も利用できるようになりましたので。
もし、当該サーバを CentOS 6 にバージョンアップするとしたら、今回の手間どころではなかったと思いますし、カーネルだけ最新装備にするという、オラクル社のアイデア・策略は、なかなか憎いことを・・・と思いました。

なお、CentOS 5 + UEK + ZFS on Linux 0.6.2 の性能を実験環境(ThinkPad T510)で測定してみたところ、同一マシンのマルチブート環境の CentOS 6 で測定した値と同程度でした。こちらの過去記事の CentOS 5 環境で、UEK の導入練習・試行をしてから、サーバに手をつけました。

2014-06-17追記
ZFS on Linux 0.6.3 がリリースされたので、CentOS 5 + UEK の環境でソース(.tar.gz)からビルドしてみたところ、まだ、ビルド可能でした。別記事で書きましたが、かなり性能アップしているので、迷わずアップデートがオススメかと思います。

2013年10月13日日曜日

kernel.pid_max の拡張

デスクトップ用途での Linux 利用では、不要と思いますが、少し大きなサーバ用途では pid の上限値を拡大しておいたほうが良いかもしれません。CentOS では /etc/sysctl.conf で設定します。
kernel.pid_max = 99999  ※デフォルト 32768、同時起動スレッド数も制限されるのでご注意を、、、
いくつまで拡張しておくかは用途次第ですが、pid を画面表示するようなツールで、くずれた表示の原因となるかもしれませんので、不足しなさそうなら、99999 (5桁、デフォルトの約3倍) にしておくと良いのではと思います。pid 管理はビットマップ方式で行われるので、pid_max を増やしてもメモリ消費はほとんどありません。
なお、最近のカーネルでは、サーバ規模に応じて自動的に拡張されるようなので、sysctl.conf に設定する前に、現在の値を確認したほうがいいです。それと、32bit 版では 32768 より大きい値は設定できません。いまどき、サーバで 32bit 版を使うことは少ないと思いますが。

2013-10-14追記
うろ覚えで”サーバ規模に応じて・・・”と書きましたが、CentOS 6 のカーネル 2.6.32-358.el6 を見てみたら、CPU 数が多い場合に拡張されるようになってました。kernel/pid.c の中です。CentOS 5 系のほうは、CPU 数に応じた自動拡張の処理は無いようでした。2.6.18-348.el5 参照。
CentOS 6 / RHEL6 のサーバ構築の際、闇雲に kernel.pid_max を設定すると、意図せず下方修正してしまうかもしれませんので、構築屋さんの方はお気をつけて。まあ、システム設計上下方修正な値で良いならよいわけでしょうけども。

2015-03-08追記
本日、マルチブート環境の FreeBSD 10.0 を 10.1 に upgrade したのですが、その際に、top を眺めていたら、FreeBSD の pid 範囲が 99999 までであるようでした。FreeBSD 付属の top では、どういう意図なのか last pid なる表示項目があり、そこを眺めていたら、99999 で wrap しました。トリビアですが、参考メモです。
補足:ZFS on Linux に強く興味を持っており、FreeBSD 実装との比較用に、マルチブート環境を作ってあります。なので、FreeBSD は殆ど使ってないです。現在は、デスクトップ利用なら CentOS 7 が最も使い易く感じています。systemd のおかげで起動が抜群に速いし。

2016-06-11追記
レッドハットのナレッジに、RHEL6 の pid_max 自動拡張の話しが説明してありましたので、リンク張っておきます。
https://access.redhat.com/solutions/28908
https://access.redhat.com/solutions/874023
CPU 数が 32 より大きいと、1024 x CPU 数 に拡張されますよと。

2019-01-30追記
kernel.pid_max が 99999 以下でないとマズいというソフトウェア (GUARDIANWALL) が実際にあった。
https://security-support.canon-its.jp/info_and_news/show/10?site_domain=GUARDIANWALL
まあ、明日は我が身と気を付けよう。

2013年7月11日木曜日

Btrfs の resize

別記事で Btrfs 化について書きましたが、実験環境とは別に 20G のパーティションに別途 Fedora19 をインストール済みでしたので、これを 10G に縮小する操作を行ってみました。Btrfs は未だ開発途上という状況なので、最悪の場合は、ぶっ壊れるかもねという心象がありますが、まあ、壊れてもさしてダメージが無い環境なので。

縮小操作は、man btrfs の通りで、いたって簡単でした。
# btrfs filesystem resize 9g /
システムデータしか入ってないこともあり、処理は殆ど一瞬で終わりました。サイズ指定は、いったん 9g にしていますが、パーティションを 10G に縮小後に、パーティションサイズまで resize するために、適当に 1G ほど余裕をとりました。
パーティション縮小は fdisk -u で行い、システム再起動後に次のように操作を行いました。
# btrfs filesystem resize max /
Resize '/' of 'max'

# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda10      10240000 2441692   6037316  29% /
devtmpfs         4011116       0   4011116   0% /dev
tmpfs            4017612     156   4017456   1% /dev/shm
tmpfs            4017612     780   4016832   1% /run
tmpfs            4017612       0   4017612   0% /sys/fs/cgroup
tmpfs            4017612      44   4017568   1% /tmp

# btrfs filesystem balance /
Done, had to relocate 7 out of 7 chunks

# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda10      10240000 2442728   7569272  25% /
devtmpfs         4011116       0   4011116   0% /dev
tmpfs            4017612     156   4017456   1% /dev/shm
tmpfs            4017612     780   4016832   1% /run
tmpfs            4017612       0   4017612   0% /sys/fs/cgroup
tmpfs            4017612      48   4017564   1% /tmp
balance という操作が肝で、これを行わないと、空きが少なく見えます(たぶん、balance しなくても、逼迫してくれば使われるのかな??)。

2019-11-16追記
Btrfs raid1 のサイズ拡張を行ったのですが、前述の balance 操作ではダメでした。検索してみると、先人の方がおられましたのでメモ。
https://qiita.com/takaki@github/items/5d96d80dc78b09ea600b
明示的に devid を指定することで、うまくいきました。実施した環境は CentOS7 です。
man btrfs-filesystem を読んでみると、デフォルトの devid は 1 であると記載あるようです。むしろ、devid 指定必須のほうが、分かり易いのではと思ってしまった。先人の方の情報に辿りつくまで、無駄に時間を使ってしまいました。最初から man をちゃんと読めばよかったというのもありますが。

2013年7月7日日曜日

Fedora19 のルートファイルシステムを Btrfs 化する

先日、Fedora19 が正式リリースされましたが、1パーティションに btrfs でインストールしたいと思ったのですが、インストーラでは指定できないようでした。何回か試行錯誤しましたが、まず ext4 でインストールしておいて、そのあと Live メディアから起動して、内容をバックアップして、mkfs.btrfs 後に書き戻すという方法で成功しましたので、自分用のメモも兼ねてご紹介です。

今回は、まっさらな SSD を使って、sda1 にインストールしました。インストーラからパーティションを切っても問題ないと思いますが、事前に 10G ほど sda1 を確保してからインストールしました。10G とは小さめですが、btrfs の透過圧縮機能をあてにしたサイズです。わたしの場合、これまでは Fedora を ext4 に入れるとしたら 20G くらいは割り当てていましたが、圧縮機能があれば半分の 10G くらいでも、わたしの用途では十分かなと。
ソフトウェアの選択を Development and Creative Workstation にして、ext4 にインストールした直後だと、約6G ほど消費した状態でした。

btrfs 化は、ライブメディア Fedora-Live-Desktop-x86_64-19-1.iso を利用して、次のように行いました。
※まずは、ライブメディアを起動して、ターミナルを開く
※root 権限を得る
# sudo bash

※ext4 のバックアップツールとして dump をインストール
# yum install dump

※別の HDD 等にバックアップを行う。わたしの場合は別の ext4 領域を使いました。
# mkdir /mnt_sdb1
# mount /dev/sdb1 /mnt_sdb1
# dump -y -0uf /mnt_sdb1/dump.sda1 /dev/sda1  ※ここで -y は LZO 圧縮するオプションです

※btrfs ファイルシステム作成
# mkfs.btrfs -f /dev/sda1

※バックアップデータを書き戻す
# mkdir /mnt_sda1
# mount -t btrfs -o compress-force=lzo /dev/sda1 /mnt_sda1
# cd /mnt_sda1
# restore -rf /mnt_sdb1/dump.sda1

※/etc/fstab に書かれている UUID とファイルシステム種別等を書き換える
# cd /mnt_sda1
# blkid /dev/sda1
/dev/sda1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" UUID_SUB="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" TYPE="btrfs"
# vi etc/fstab
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx / btrfs defaults,compress-force=lzo 1 1

※initramfs の再作成と GRUB2 の再インストールのため環境設定
# mount -t devtmpfs devtmpfs /mnt_sda1/dev
# mount -t devpts devpts /mnt_sda1/dev/pts
# mount -t sysfs sysfs /mnt_sda1/sys
# mount -t proc proc /mnt_sda1/proc

※initramfs の再作成
# chroot /mnt_sda1 /bin/bash
# ls /boot/initramfs-3*  
/boot/initramfs-3.9.5-301.fc19.x86_64.img  ※カーネルバージョン確認
# dracut -f /boot/initramfs-3.9.5-301.fc19.x86_64.img  3.9.5-301.fc19.x86_64

※GRUB2 の再インストール
# grub2-mkconfig > /boot/grub2/grub.cfg
# grub2-install /dev/sda
# exit  ※chroot を抜ける
# 
ライブ DVD を抜けて、sda から起動できれば成功です。
現在の私の環境での、ディスク空き状況は次の通りです。
# cat /etc/redhat-release 
Fedora release 19 (Schrödinger’s Cat)
# df -kT /
Filesystem     Type  1K-blocks    Used Available Use% Mounted on
/dev/sda1      btrfs  10240000 3888960   5950044  40% /

2013-07-08追記
btrfs は swapfile には対応していないそうなので、ご注意を。
https://btrfs.wiki.kernel.org/index.php/FAQ#Does_btrfs_support_swap_files.3F
実際、fallocate , mkswap までは出来ますが、swapon でエラー(invalid argument)になるようです。わたしのマシンはメモリを 8G 積んでおり、swap の必要性を感じませんので、swap レスでいいやと思いましたが、用途によっては zram を使ってもいいかもしれません。
もちろん、別途swapパーティションを作ってもいいわけですが。

2013-10-12追記
まだアルファ版ですが、Fedora 20 でもインストール時には btrfs は指定できず、上記の手順でいけました。

2013-12-07追記
CentOS 6.5 でも、同様の手順で出来ました。Btrfs は RHEL 6.5 においても、まだ Technology Preview 扱いとなっており、安定性がクエスチョンですが、SSD の節約に compress-force=lzo が役立ちます。

2014-04-27追記
RHEL7 beta をインストールしたのですが、やはりインストーラからは btrfs を指定できず。Fedora 19/20 と同様に、いったん ext4 でインストールしたあとに btrfs 化しました。
ただし、今回は試しに btrfs-convert を使ってみました。使い方はいたって簡単で、レスキューモードで起動後に、ext4 としてインストールしたパーティションを指定して実行するだけです。あっという間に変換が完了します。変換すると UUID が変わってしまうので、この記事の手順の fstab の変更の箇所から同様に操作して、btrfs 化に成功しました。
compress-force=lzo を活用したければ、やはりバックアップからリストアしないといけませんが、透過圧縮を使わないなら btrfs-convert のほうが手っ取り早いかと思います。btrfs-convert の仕組みは、次の URL に解説があります。すごい、賢いです。
https://btrfs.wiki.kernel.org/index.php/Conversion_from_Ext3
このように、変換前のイメージが、サブボリューム ext2_saved に保持される方式になっているので、btrfs-convert を利用した場合には、ext2_saved の削除をお忘れなく。

2013年6月29日土曜日

zfs-fuse を使って CentOS 5 でも透過圧縮を利用

CentOS 5 で運用しているサーバで、容量を稼ぐのに透過圧縮可能なファイルシステムを使いたいのですが、ZFS on Linux は非対応(カーネルが古くコンパイル不可)なので、zfs-fuse を利用しようかと思います。しかし、CentOS 5 の fuse は、NFS export に対応していません。
そこで、一工夫して、透過圧縮指定した ZFS 領域にスパースファイルを作って XFS 化して、loop マウントすることで、NFS export することにしました。
※まず圧縮指定
# zfs set compression=gzip-1 tank5/test
# zfs get compression tank5/test
NAME        PROPERTY     VALUE     SOURCE
tank5/test  compression  gzip-1    local

※スパースファイル作成。CentOS 5 では truncate が用意されてないので dd 利用
# dd if=/dev/zero of=/tank5/test/sparsefile bs=1M seek=4096 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 2.2e-05 seconds, 0.0 kB/s

# ls -lsh /tank5/test/sparsefile 
512 -rw-r--r-- 1 root root 4.0G Jun 29 10:21 /tank5/test/sparsefile

※ext4 でもいいけれど、XFS を試したいという気持ちもありまして
# mkfs -t xfs /tank5/test/sparsefile 
meta-data=/tank5/test/sparsefile isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096  
log      =internal log           bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0

# mount -t xfs -o loop /tank5/test/sparsefile /mnt_temp
# df
...
/tank5/test/sparsefile
                       4184064      4384   4179680   1% /mnt_temp

※テスト書き込み
# dd if=/dev/sda of=/mnt_temp/test.dd bs=1M count=500 conv=fsync
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 16.7982 seconds, 31.2 MB/s
# ls -lsh /tank5/test/sparsefile 
211M -rw-r--r-- 1 root root 4.0G Jun 29 10:24 /tank5/test/sparsefile
この実験では、500M が 211M に圧縮されました。書き込み速度は、zfs-fuse の遅さに引きずられますが、NFS (NW が 100Mbps の環境) 経由で利用する予定なので、十分そうです。
なお、NFS のセッティング方法等は、普通にやればいいので割愛します。

2013-06-30追記
XFS のサイズ拡張(xfs_growfs)を試してみました。マウントしたまま可能でした。
スパースファイルの拡張、loop デバイスのサイズ拡張、xfs_growfs の順に行います。
※losetup -c も初めてなので、予め loop デバイスのサイズを確認
# grep loop0 /proc/partitions 
   7        0    4194304 loop0

※スパースファイルの拡張、サイズ指定を誤っても変なところに書き込まないように if=/dev/null でね
# dd if=/dev/null of=/tank5/test/sparsefile bs=1M seek=8192 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.646e-05 s, 0.0 kB/s
# ls -lsh /tank5/test/sparsefile 
236M -rw-r--r-- 1 root root 8.0G Jun 30 06:06 /tank5/test/sparsefile

※loop デバイスのサイズ認識は自動ではないので、変化なし
# grep loop0 /proc/partitions 
   7        0    4194304 loop0
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       4184064    545056   3639008  14% /mnt_temp

※loop デバイスのサイズ再認識を実行
# losetup -c /dev/loop0 
# grep loop0 /proc/partitions 
   7        0    8388608 loop0
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       4184064    545056   3639008  14% /mnt_temp

※XFS のサイズ拡張を実行
# xfs_growfs /mnt_temp
meta-data=/dev/loop0             isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0, projid32bit=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal               bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 1048576 to 2097152
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       8378368    545312   7833056   7% /mnt_temp
実験の範囲では大丈夫そうです。

2013-07-03追記
サイズ拡張の検証を、間違って CentOS 6 でやってしまっていました。通常、CentOS 6 を使うことが多いもので・・・
で、残念ながら、CentOS 5 では losetup -c オプションは使えず、いちおう 2.6.18-348.el5 のソースも見てみましたが、サイズ拡張を行うためのインターフェースが未実装でした。したがって、マウントしたまま拡張は不可でした。もちろん、いったんアンマウントしてから、スパースファイル拡張して、再度マウントすればいけます。

2013-08-09追記
この形態で実際使い始めたのですが、ファイル削除の際に一工夫すると、より効果的に運用できます。具体的には次のように、削除対象ファイルをゼロ埋め後に削除するようにします。
# find remove-target-dir -type f -exec shred -n 0 -z -u {} \;
これで不要となったブロックについて、XFS から ZFS へゼロ書き込みが行われ、ZFS 側の圧縮機能により元データが使用していたブロックの大半が回収されることになります。したがって、シン・プロビジョニング(Thin Provisioning)が、より効果的に行えることになります。
なお、上記の find 後には、抜けがら(通常ファイル以外のディレクトリその他のことを言ってます:-)が残りますので、最後に rm -rf remove-target-dir もお忘れなく。

2013-10-22追記
オラクル社提供の UEK を使うことで、CentOS 5 でも ZFS on Linux や btrfs が利用できました。
こちらの記事を参照。

2013年6月11日火曜日

バックアップの暗号化運用手法

ZFS on Linux 上に、バックアップを採っているのですが、暗号化のため sparse ZVOL + cryptsetup + ext4 を使っていました。
しかし、ZVOL 直上の ext4 ならば fstrim が使えるのですが、cryptsetup を挟んだ場合は fstrim を利用できず、使いまわしていると、ZVOL が肥大化してしまいます。ZVOL を再作成するという運用もできますが、ZVOL の解放 (zfs destroy) に結構な時間がかかるようです。わたしの環境では、100GiB 解放するのに 7 分程度かかるようでした。

というわけで、別の方法に切り替えることにしました。

いろいろと調べ、考えた挙句に辿りついた方式は、sparse file + losetup + cryptsetup + xfs です。 sparse file の作成には、truncate コマンドが利用できます。操作手順は、次のようになります。
# truncate -s $((65*1024*1024*1024)) /tank1/backup/vault-2013-06-11
# losetup /dev/loop0 /tank1/backup/vault-2013-06-11
# cryptsetup create -y vault-2013-06-11 /dev/loop0
# mkfs -t xfs /dev/mapper/vault-2013-06-11
# mkdir /mnt_vault-2013-06-11
# mount /dev/mapper/vault-2013-06-11 /mnt_vault-2013-06-11
ファイルシステムには、mkfs が高速で、スペース効率が良い xfs を使うことにしました。
わたしの当該バックアップ運用では、1回のバックアップデータ量が 60GiB ほどで、過去3世代保存できればよいので、毎回、上記操作で 65GiB の暗号化スペースを作って利用することにしました。
なお、バックアップ後には、次の操作を行います。
# umount /mnt_vault-2013-06-11
# cryptsetup remove /dev/mapper/vault-2013-06-11
# losetup -d /dev/loop0
比較的多くのコマンドを、順序を違えずに実行する必要があり、実際やってみると誤操作しがちでしたので、簡単な支援スクリプトを3つ作成しました。ご参考まで。
#!/bin/bash
#
# Name: my-vault-setup
#
# Authors: luna2 <blue3waters at gmail dot com>
#
# This file is subject to the GNU General Public License.
# It comes with NO WARRANTY.
#

usage_exit() {
        echo "Usage: my-vault-setup [-d dir] [-t fs-type] size" 1>&2
        exit 1
}

FS_TYPE=xfs
TARGET_DIR=.

while getopts ":d:t:" opt
do
  case $opt in
  d)
        TARGET_DIR=${OPTARG%/}
        ;;
  t)
        FS_TYPE=$OPTARG
        ;;
  *)    usage_exit
  esac
done

shift $((OPTIND - 1))

if [ $# -ne 1 ] ; then
        usage_exit
elif expr "$1" : '[0-9]*' > /dev/null ; then
        TARGET_SIZE=$1
else
        usage_exit
fi

if [ ! -d $TARGET_DIR ] ; then
        usage_exit
fi

TARGET_NAME=vault-`date +%F-%H%M`
TARGET=$TARGET_DIR/$TARGET_NAME

echo "TARGET=$TARGET  SIZE=$TARGET_SIZE (GiB)"

truncate -s $((${TARGET_SIZE}*1024*1024*1024)) $TARGET
if [ $? -ne 0 ] ; then
        echo "ERROR: truncate fail" 1>&2
        exit 1
fi

losetup -f $TARGET
if [ $? -ne 0 ] ; then
        echo "ERROR: losetup fail" 1>&2
        exit 1
fi

LOOP_DEV=`losetup -j $TARGET | egrep -o '/dev/loop[0-9]+'`

echo "LOOP_DEV=$LOOP_DEV"

cryptsetup create -y $TARGET_NAME $LOOP_DEV
if [ $? -ne 0 ] ; then
        echo "ERROR: cryptsetup fail" 1>&2
        exit 1
fi

mkfs -t $FS_TYPE /dev/mapper/$TARGET_NAME >/dev/null 2>&1
if [ $? -ne 0 ] ; then
        echo "ERROR: mkfs fail" 1>&2
        exit 1
fi

mkdir /mnt_$TARGET_NAME
mount /dev/mapper/$TARGET_NAME /mnt_$TARGET_NAME
if [ $? -ne 0 ] ; then
        echo "ERROR: mount fail" 1>&2
        exit 1
fi

echo "/mnt_$TARGET_NAME is usable for your backup"

exit 0
#!/bin/bash
#
# Name: my-vault-umount
#
# Authors: luna2 <blue3waters at gmail dot com>
#
# This file is subject to the GNU General Public License.
# It comes with NO WARRANTY.
#

usage_exit() {
        echo "Usage: my-vault-umount target_dir" 1>&2
        exit 1
}

if [ $# -ne 1 ] ; then
        usage_exit
fi

TARGET=${1%/}

if [[ $TARGET != /mnt_vault-* ]] ; then
        usage_exit
fi

TARGET_NAME=${TARGET#/mnt_}

if ! grep -wq $TARGET /proc/mounts ; then
        echo "ERROR: $TARGET is not a mount point" 1>&2
        exit 1
fi

umount $TARGET
if [ $? -ne 0 ] ; then
        echo "ERROR: umount fail" 1>&2
        exit 1
fi

LOOP_DEV=`cryptsetup status /dev/mapper/$TARGET_NAME | awk '$1 == "device:" {print $2}'`

cryptsetup remove /dev/mapper/$TARGET_NAME
if [ $? -ne 0 ] ; then
        echo "ERROR: cryptsetup fail" 1>&2
        exit 1
fi

VAULT_FILE=`losetup $LOOP_DEV | awk '{print $NF}'`
VAULT_FILE=${VAULT_FILE#(}
VAULT_FILE=${VAULT_FILE%)}

losetup -d $LOOP_DEV
if [ $? -ne 0 ] ; then
        echo "ERROR: losetup fail" 1>&2
        exit 1
fi

rmdir $TARGET

echo "$VAULT_FILE was locked"

exit 0
#!/bin/bash
#
# Name: my-vault-mount
#
# Authors: luna2 <blue3waters at gmail dot com>
#
# This file is subject to the GNU General Public License.
# It comes with NO WARRANTY.
#

usage_exit() {
        echo "Usage: my-vault-mount vault_file" 1>&2
        exit 1
}

if [ $# -ne 1 ] ; then
        usage_exit
fi

TARGET=$1
if [ ! -f $TARGET ] ; then
        usage_exit
fi

TARGET_NAME=${TARGET##*/}

losetup -f $TARGET
if [ $? -ne 0 ] ; then
        echo "ERROR: losetup fail" 1>&2
        exit 1
fi

LOOP_DEV=`losetup -j $TARGET | egrep -o '/dev/loop[0-9]+'`

echo "LOOP_DEV=$LOOP_DEV"

cryptsetup create $TARGET_NAME $LOOP_DEV
if [ $? -ne 0 ] ; then
        echo "ERROR: cryptsetup fail" 1>&2
        exit 1
fi

mkdir /mnt_$TARGET_NAME
mount /dev/mapper/$TARGET_NAME /mnt_$TARGET_NAME
if [ $? -ne 0 ] ; then
        echo "ERROR: mount fail" 1>&2
        exit 1
fi

echo "/mnt_$TARGET_NAME is usable"

exit 0

2013-06-22追記
上に書いたバックアップ運用に加えて、圧縮処理について、最終格納先 ZFS の透過圧縮 (compression=on) に期待するとうまく行きません。暗号化後のデータは圧縮しにくいためです。そこで、dm-crypt デバイスの上で使うファイルシステムを xfs から Btrfs に変更して、compress=lzo オプションで圧縮を試みました。しかし、残念ながら現状の Btrfs では全くといっていいほど圧縮できませんでした(圧縮オプションを zlib に変えても結果は同じ)。
他に透過圧縮できるファイルシステムは何があるだろ?とサーチしてみて、ntfs-3g でも透過圧縮できるようなので、試してみました。
# mkntfs -Q -C /dev/mapper/vault-xxx
# mount -t ntfs -o compression /dev/mapper/vault-xxx /mnt
# mkdir /mnt/compress_folder
# setfattr -h -v 0x10080000 -n system.ntfs_attrib /mnt/compress_folder
ntfs-3g の場合、こんな具合にセットアップするようです。実際動かしてみると、圧縮はそこそこ出来たのですが、処理スピードは相当に遅めでした。Windows で NTFS 圧縮した経験からも遅いだろうとは予想してましたが、ちょっと、自分の運用には耐えらないほど遅かったです。

2013-06-23追記
ZFS 二段重ねは重いような気がしてましたが、dm-crypt デバイス上で使うファイルシステムも ZFS にして、compression=lz4 を使うとなかなか良好な結果でした。一時もうそれで十分と思いましたが、さらに調べたところ、Btrfs には compress-force というオプションもあることを知りました。試してみると、ZFS 二段重ねよりも高速に処理可能で、compress-force=zlib が最も良好な結果(処理時間が短くて圧縮率高い)でした。compress-force=lzo も試しましたが、処理時間はさほど短くならず、圧縮率も ZFS (compression=lz4) より下でした。なお、Btrfs (compress-force=zlib) の圧縮率は、ZFS (compression=gzip-1) とほぼ同じでした。
以上から、Btrfs (compress-force=zlib) を利用しようかと思います。初めて Btrfs に利点を感じました。

2013年5月31日金曜日

ZFS on Linux 0.6.1 の性能を OpenIndiana 151a7 と比較

ZFS on Linux を使い始めて約1年、始祖の Solaris 実装とどの程度性能が違うのか知りたくなり、試してみました。

Solaris 系は、初挑戦でしたが、インストールはさほど難しくなかった印象です。むしろ、その前準備(マルチブートのためのパーティション構成変更作業)に手間がかかりました。特に、ディスク先頭の Windows7 のパーティションをいじるのに苦労しました。実験に使ったマシンは ThinkPad T510 ですが、プリインストールされていた Windows7 環境では、C: の他にシステムパーティションと呼ばれる領域がもう1つ確保されていて、これを削除するのが手間でした。ZFS本(ISBN-13: 978-4048676540)によると、OpenSolaris は、基本パーティションにインストールする必要があるということで、Windows7 のシステムパーティションが邪魔になったのです。そこは本題ではないので、詳細は割愛しますが、最終的に次のようなパーティション構成となりました。

今回の測定環境は ThinkPad T510 + 古い SAMSUNG SSD (eSATA接続) です。
# zdb
tankM:
    version: 23
    name: 'tankM'
    state: 0
    txg: 194345
    pool_guid: 17978947249853082376
    hostid: 8323328
    hostname: 'my42'
    vdev_children: 1
    vdev_tree:
        type: 'root'
        id: 0
        guid: 17978947249853082376
        children[0]:
            type: 'disk'
            id: 0
            guid: 2831835469869973055
            path: '/dev/disk/by-id/ata-SAMSUNG_MCCOE64G8MPP-0VA_SE809N0057-part1'
            phys_path: '/dev/ada1s1'
            whole_disk: 0
            metaslab_array: 24
            metaslab_shift: 29
            ashift: 12
            asize: 64017399808
            is_log: 0
            DTL: 73
            create_txg: 4
    features_for_read:
# zpool get all tankM
NAME   PROPERTY               VALUE                  SOURCE
tankM  size                   59.5G                  -
tankM  capacity               32%                    -
tankM  altroot                -                      default
tankM  health                 ONLINE                 -
tankM  guid                   17978947249853082376   local
tankM  version                23                     local
tankM  bootfs                 -                      default
tankM  delegation             on                     default
tankM  autoreplace            off                    default
tankM  cachefile              -                      default
tankM  failmode               wait                   default
tankM  listsnapshots          off                    default
tankM  autoexpand             off                    default
tankM  dedupditto             0                      default
tankM  dedupratio             1.00x                  -
tankM  free                   39.9G                  -
tankM  allocated              19.6G                  -
tankM  readonly               off                    -
tankM  ashift                 12                     local
tankM  comment                -                      default
tankM  expandsize             0                      -
tankM  freeing                0                      local
tankM  feature@async_destroy  disabled               local
tankM  feature@empty_bpobj    disabled               local
tankM  feature@lz4_compress   disabled               local
# zfs get all tankM -s local
NAME   PROPERTY              VALUE                  SOURCE
tankM  mountpoint            /tankM                 local
tankM  atime                 off                    local
zpool の構成は前記のとおりのシングル構成です。

SAMSUNG SSD の基本性能は次のような具合(Disk Utility のベンチマーク結果)です。

以下、bonnie++ 1.96 のデータです。

■CentOS 6.4
# uname -a
Linux xxxx 2.6.32-358.6.2.el6.x86_64 #1 SMP Thu May 16 20:59:36 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# bonnie++ -u root -d /tankM
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15464M   151  99 68485  12 40237   9   319  84 108505  11 910.6  26
Latency             73426us     146ms    1240ms     842ms     302ms     480ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 17826  84 +++++ +++  4228  29 19977  85 +++++ +++ 21914  96
Latency             31300us     332us   77141us   31685us      67us     912us
1.96,1.96,xxxx,1,1369835550,15464M,,151,99,68485,12,40237,9,319,84,108505,11,910.6,26,16,,,,,17826,84,+++++,+++,4228,29,19977,85,+++++,+++,21914,96,73426us,146ms,1240ms,842ms,302ms,480ms,31300us,332us,77141us,31685us,67us,912us

■OpenIndiana 151a7
# uname -a
SunOS xxxx 5.11 oi_151a7 i86pc i386 i86pc Solaris
# ./bonnie++ -u root -d /tankM
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx            16G   209  96 75797  12 42079  10   606  99 102241  10  2499  34
Latency             43718us     190ms    1469ms   18081us     545ms   45179us
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  5706  15 +++++ +++ +++++ +++ 24358  53 +++++ +++ +++++ +++
Latency              1686ms     144us     102us    7317us      27us      92us
1.96,1.96,xxxx,1,1369836787,16G,,209,96,75797,12,42079,10,606,99,102241,10,2499,34,16,,,,,5706,15,+++++,+++,+++++,+++,24358,53,+++++,+++,+++++,+++,43718us,190ms,1469ms,18081us,545ms,45179us,1686ms,144us,102us,7317us,27us,92us

■FreeBSD 9.1
# uname -a
FreeBSD xxxx 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r243825: Tue Dec  4 09:23:10 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
# bonnie++ -u root -d /tankM
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx            16G   174  99 69411  11 38889   7   414  91 104735   5  1040   8
Latency             50405us    3339ms    2989ms     628ms     620ms    1002ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 31430  95 +++++ +++ 16114  62 32265  96 +++++ +++  4389  93
Latency             13375us     118us     118ms   13380us     115us     447us
1.96,1.96,xxxx,1,1369838677,16G,,174,99,69411,11,38889,7,414,91,104735,5,1040,8,16,,,,,31430,95,+++++,+++,16114,62,32265,96,+++++,+++,4389,93,50405us,3339ms,2989ms,628ms,620ms,1002ms,13375us,118us,118ms,13380us,115us,447us

■Fedora18
# uname -a
Linux xxxx 3.9.3-201.fc18.x86_64 #1 SMP Tue May 21 17:02:24 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# bonnie++ -u root -d /tankM
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15688M   149  95 74100  13 42477  10   362  87 108047  11 946.6  30
Latency             98607us     170ms    1224ms     733ms     433ms     621ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 13264  56 +++++ +++ 10665  70 19831  85 +++++ +++ 24615  94
Latency               310ms    7156us   49153us   39069us      80us     551us
1.96,1.96,xxxx,1,1369840982,15688M,,149,95,74100,13,42477,10,362,87,108047,11,946.6,30,16,,,,,13264,56,+++++,+++,10665,70,19831,85,+++++,+++,24615,94,98607us,170ms,1224ms,733ms,433ms,621ms,310ms,7156us,49153us,39069us,80us,551us

測ってみた感想としては、わたしの利用範囲においては、OpenIndiana , FreeBSD と比較して、Linux 実装のパフォーマンスは遜色ない(若干劣る程度)と感じました。ただ、普段使いは CentOS6 なのですが、最新カーネルの恩恵を受けられる Fedora18 のほうがパフォーマンス発揮できるようです。

Fedora, CentOS 等の iso イメージ格納庫、調査用ソース展開場所(主にカーネル)、自作開発ソース格納庫、バックアップイメージ格納庫、KVM ゲスト用ディスク割り当て(スパース zvol)が、わたしの現在の用途です。

本格的に使っている zpool の形態は、RAIDZ(HDDx4 , バックアップ, iso格納用)、RAIDZ2(HDDx6+zram(L2ARC), ソースコード格納用)、mirror+stripe(HDDx2+HDDx2+SSDx2(ZIL&L2ARC), 大容量バックアップ用NFS)、HW-RAID上のシングル(KVM ゲスト向けzvol切り出し用)といったところです。すっかり、どっぷりと使っています。
仕事では、SAN ストレージ+multipath+LVM2+ext4 領域も使っていますが、ZFS と比べて、運用・操作性が格段にヤヤコシイく感じます。

■関連記事
3つのOSでZFSの性能を比較

2013年5月26日日曜日

ゆっくりとIOさせるツール

ときおり使うコマンドなのですが、ときおり過ぎてコマンド名を思い出せなくなるので、自分向けのメモです。
# cat /etc/centos-release 
CentOS release 6.4 (Final)
# rpm -qi pv
Name        : pv                           Relocations: (not relocatable)
Version     : 1.1.4                             Vendor: Fedora Project
Release     : 3.el6                         Build Date: Mon 05 Jul 2010 09:29:34 PM JST
Install Date: Sat 15 Sep 2012 02:22:36 PM JST      Build Host: x86-17.phx2.fedoraproject.org
Group       : Development/Tools             Source RPM: pv-1.1.4-3.el6.src.rpm
Size        : 68426                            License: Artistic 2.0
Signature   : RSA/8, Tue 06 Jul 2010 11:11:06 AM JST, Key ID 3b49df2a0608b895
Packager    : Fedora Project
URL         : http://www.ivarch.com/programs/pv.shtml
Summary     : A tool for monitoring the progress of data through a pipeline
Description :
PV ("Pipe Viewer") is a tool for monitoring the progress of data through a
pipeline.  It can be inserted into any normal pipeline between two processes
to give a visual indication of how quickly data is passing through, how long
it has taken, how near to completion it is, and an estimate of how long it
will be until completion.
CentOS 6 の場合、EPEL に収録されています。

使用例です。
# dd if=backup.sdX bs=64k | pv --rate-limit 35m --buffer-size 64k | dd of=/dev/sdX bs=1M oflag=direct
 124GB 1:03:10 [33.9MB/s] [                          <=>                      ]
この例では、pv の出力を 35MB/s に制限しています。

隠れた逸品と思うのですが、ネーミングが覚えにくいと思う。

2013年4月2日火曜日

ZFS on Linux 0.6.1 を CentOS 6.4 にインストール

ZFS on Linux 0.6.1 がリリースされたので、rc14 からアップデートしました。
これまでは、自分でビルドする必要がありましたが、0.6.1 からはバイナリの yumリポジトリ (但しx86_64のみ) が提供されたため、導入が簡単になりました。

まず、rc14 をアンインストールします。
# yum remove zfs-modules-dkms spl-modules-dkms
あとは、http://zfsonlinux.org/epel.html に記載されている通り、2つコマンドを実行するだけです。
ただし、もしまだ dkms を未導入の場合は、EPEL からインストールしておく必要があります。
2013-04-06追記、すみません。誤解だったようで、EPEL と同じバージョンの dkms パッケージが一緒に提供されているようです。
# yum localinstall --nogpgcheck http://archive.zfsonlinux.org/epel/zfs-release-1-2.el6.noarch.rpm
# yum install zfs
アップデート後の状態です。
# rpm -q zfs
zfs-0.6.1-1.el6.x86_64
# zpool list
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank1  59.5G  19.7G  39.8G    33%  1.88x  ONLINE  -
# dkms status
nvidia, 310.40, 2.6.32-358.2.1.el6.x86_64, x86_64: installed
spl, 0.6.1, 2.6.32-358.2.1.el6.x86_64, x86_64: installed
zfs, 0.6.1, 2.6.32-358.2.1.el6.x86_64, x86_64: installed
nvidia, 310.40, 2.6.32-279.22.1.el6.x86_64, x86_64: installed-weak from 2.6.32-358.2.1.el6.x86_64
spl, 0.6.1, 2.6.32-279.22.1.el6.x86_64, x86_64: installed-weak from 2.6.32-358.2.1.el6.x86_64
zfs, 0.6.1, 2.6.32-279.22.1.el6.x86_64, x86_64: installed-weak from 2.6.32-358.2.1.el6.x86_64
bonnie++ をやってみました。
# uname -a
Linux xxxx 2.6.32-358.2.1.el6.x86_64 #1 SMP Wed Mar 13 00:26:49 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# bonnie++ -u root -d /tank1
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx         15464M   139  99 44588   8 32117   8   303  85 121737  14 967.0  26
Latency             82893us    1726ms    1886ms    1058ms     262ms    1033ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 22649  88 +++++ +++ 23708  96 13849  93 +++++ +++ 14393  92
Latency             16742us    1011us     694us   38179us      25us     549us
1.96,1.96,xxxx,1,1364662071,15464M,,139,99,44588,8,32117,8,303,85,121737,14,967.0,26,16,,,,,22649,88,+++++,+++,23708,96,13849,93,+++++,+++,14393,92,82893us,1726ms,1886ms,1058ms,262ms,1033ms,16742us,1011us,694us,38179us,25us,549us
このマシン (ThinkPad T510) には、マルチブートで FreeBSD 9 も入っているので、比較データです。
# uname -a
FreeBSD xxxx 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
# bonnie++ -u root -d /tank1
...
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
xxxx            16G   172  99 42036   8 29989   6   331  71 128285   9 940.2  11
Latency             62539us    6315ms    6148ms    1721ms     260ms     934ms
Version  1.96       ------Sequential Create------ --------Random Create--------
xxxx                -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 29849  95 +++++ +++ 29585  98 25541  94 +++++ +++ 18384  86
Latency             16274us     102us     135us   26201us     143us     286us
1.96,1.96,xxxx,1,1364660246,16G,,172,99,42036,8,29989,6,331,71,128285,9,940.2,11,16,,,,,29849,95,+++++,+++,29585,98,25541,94,+++++,+++,18384,86,62539us,6315ms,6148ms,1721ms,260ms,934ms,16274us,102us,135us,26201us,143us,286us
わたしの限られた実験環境においてはということですが、以前に測った時と変わらず、FreeBSD 9 のほうが若干性能が上のようです。ただし、FreeBSD は現在は 9.1 がリリースされているので、近いうちにアップデートして、再度測定してみようかと思います。

2013-04-03追記
システム起動時に zfs 領域を自動マウントしてくれるサービスが、デフォルトでは chkconfig に登録されないようです。自動マウントしたい場合は、次のようにして登録すればよいです。rc時代にはデフォルトで登録されていました。ただ、sharenfs プロパティを使う場合に都合悪かったですが・・・
# ls /etc/init.d/zfs 
/etc/init.d/zfs
# chkconfig --list zfs
service zfs supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add zfs')
# chkconfig --add zfs
# chkconfig --list zfs
zfs             0:off 1:off 2:on 3:on 4:on 5:on 6:off

■関連記事
第2水曜日にcronスケジュールしたい
ZFS の L2ARC に zram を利用する
ZFS on Linux 0.6.1 の性能を OpenIndiana 151a7 と比較

2013年4月1日月曜日

メインマシン ThinkPad T510 に R2021D を搭載

メインマシンとして ThinkPad T510 で、Windows 7 Professional と CentOS 6 をマルチブートで使用しています。純粋な Linux サーバであれば、md を使ってソフトウェア RAID1 にして運用するところですが、ノートPCで かつ Windows も使う環境ということで、OS 領域の RAID 化は諦めていました。データ領域については、eSATA 接続の ハードウェア RAID1 を利用しています。

もしメインマシンの OS ディスクが壊れたら、復旧が面倒だし結構ダメージ受けるなあとは思っていたのですが、先日、mSATA SSD 2枚で、2.5 inch ディスクサイズの RAID1 を構築できるユニット R2021D が発売され、面白そうだったのもあり、導入してみることにしました。
以下、少しレビューです。

まず、変換基盤裏面はこんな感じです。RAID のモードを設定するディップスイッチがあるのですが、ON / OFF の説明と逆向きになっています。


次は、表面に mSATA SSD 2枚 を搭載した状態です。今回は、PLEXTOR M5M 256G をチョイスしました。添付されていた説明書では、どのネジで mSATA SSD を留めるのかが分からず、意外と苦戦しました。加えて、mSATA SSD は初めて取り扱ったので神経使いました。


Windows 領域の引越しのため、ThinkPad の 2nd HDD アダプターに載せた状態です。

こちらを、DVD ドライブベイに差し込んで、元ディスク (Intel SSD 520 240G) 上の CentOS 6 を起動して、dd で丸ごと OS の引越しを行いました。
# dd if=/dev/sda of=/dev/sdb bs=1M  ※この類の操作をする際は、hdparm -I 等で個体確認必須です

メインディスクを入れ替えて、換装終了です。

この画像は、当初搭載されていた HDD のマウンタを R2021D に着けた状態です。

Windows 7 を起動して、RAID 管理ツールから状態を確認。


参考までに、CrystalDiskMark の数値はこの程度でした。


載せ換える前まで使っていた Intel 520 よりは性能が劣りますが、OS 起動時間はほとんど変わりませんでした。
マルチブートの CentOS 5 および 6、それと FreeBSD 9 の起動にも支障ありませんでした。

CentOS 6 からは、次のように見えます。
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ACPI cmd ef/02:00:00:00:00:a0 (SET FEATURES) succeeded
ata1.00: ACPI cmd f5/00:00:00:00:00:a0 (SECURITY FREEZE LOCK) filtered out
ata1.00: ATA-7: JMicron H/W RAID1, 0959, max UDMA/133
ata1.00: 500039680 sectors, multi 1: LBA48 
ata1.00: ACPI cmd ef/02:00:00:00:00:a0 (SET FEATURES) succeeded
ata1.00: ACPI cmd f5/00:00:00:00:00:a0 (SECURITY FREEZE LOCK) filtered out
ata1.00: configured for UDMA/133
ata1.00: configured for UDMA/133
ata1: EH complete
scsi 0:0:0:0: Direct-Access     ATA      JMicron H/W RAID 0959 PQ: 0 ANSI: 5

2013-05-31追記
M5M (FW 1.02) は、かなり熱を発っするようでしたが、FW を 1.03 にアップデートしたところ、改善されたように思われます。FW アップデートには、AREA の上用賀というアダプタを利用しました。

2013-10-26追記
M5M の FW 1.04 が出ていたので、アップデートしました。更新履歴には4点ほど改善点が書いてありました。
2013/10/11 1.04 
This firmware revision improves: 
1. Drive compatibility with Lenovo/Dell NB. 
2. Data error recovery capability 
3. Drive health on platform which support DEVSLP. 
4. Drive stability when execute GC 
R2021D との組み合わせでは、負荷が掛かると不安定 (mirror が外れる) な時がありましたが、負荷に強くなったように思われます。

2013-11-27追記
M5M の FW を 1.04 にアップデートしてから1ヶ月経過しましたが、実に快調で、1度も mirror が外れることはありませんでした。それと、1.03 と比べても発熱し難くなった感じです。ThinkPad T510 の HDD ベイ位置は左手の下あたりで、M5M 2枚ということもあり、初期の FW では物凄く熱くなってましたが、現在の FW 1.04 では、元々載っていた HDD よりも冷たいぐらいな感触です。Plextor さんのエンジニアに感謝です!
mSATA SSD を使うマシン環境が他にありませんが、もし新規のマシンで mSATA 使うんなら、現時点なら、迷わず M5M を選ぶと思います。DEVSLP にも対応してますしね。

2014-01-25追記
M5M の FW 1.05 が出ているようです。
20140109 1.05 
This firmware revision improves: 
1. Drive stability while computer be accidentally powered off due to 
unexpected external operations. 
2. Read and write performance 
consistency on Linux operating systems 
Linux 向けの修正が入っているようで興味を惹かれますが、現在 1.04 で不都合は無く、アップデート作業は結構手間 (R2021D からの mSATA 取り出し、バックアップ/リストア) なので、今回は見送りたいと思います。

2014-02-26追記
玄人志向から出た mSATA RAID アダプタ(KRHK-mSATAX2/S7)を試してみました。
私のマシンは SATA2 までなので、M5M を十分活かせていませんが、R2021D よりも性能アップするのでは?と思ったのですが、結果は大して変わらず。

さらに、残念ながら私のマシン環境(ThinkPad T510 + KRHK-mSATAX2/S7 + M5M 256G x 2枚)では安定動作せず、マシンを再起動するとディスク(RAID1 ボリューム)を見失うことがあり、常用できませんでした。
加えて言うと、JMicron のチップ JMS562 が載っているのですが、RAID 管理ツールが使えず(説明書にも記載なし)、動作状況を把握するのに基板上の LED を見ないといけませんので、その点でも常用は無理でした。
ということで、結局 R2021D に戻しました。3千円台というお手頃値段でしたし、あきらめて、お蔵入りです。

2014-03-01追記
KRHK-mSATAX2/S7 を試行した際に、M5M の FW を 1.05 にアップデートしていたのですが、R2021D に戻してから性能が落ちた状態(seq READ/WRITE が 120MB/s くらいだったので RAID アダプタと mSATA の間のリンクが 1.5Gbps に落ちていた?)になり、secure erase を行ったり、RAID ボリュームを再作成したりしましたが回復せず、まさかとは思いつつも、M5M の FW を 1.04 に戻してみたら、以前の性能に戻りました。自分には分かりませんが FW 開発(各種チューニング、トレードオフ)は難しいのだろうなと想像します。なお、Plextor さんの場合、古い FW は公開されてないようで、以前ダウンロードしたのを消さないで放置していてよかったです。

2014-03-12追記
ディップスイッチの状態です。


2014-07-29追記
M5M の FW 1.06 が出ているようなのですが、いつの間にか、名前と Email アドレス(必須)を入力しないとダウンロードできなくなったようです。これは、結構がっかりです。次回以降 SSD を調達する際、マイナスポイントとして考慮してしまうと思います。修正内容は、公開されている PDF (こちらは Email アドレス入力不要)に、次のように記載されてます。
2014/07/08 1.06
This firmware revision improves:
1. Response ability during executing GC and operating.
2. Lag problem when doing S4/S5 under few specific situations and platforms.
わたしの環境では、1.05 で問題があり、1.04 に戻した経緯があり、その後は、全く問題ないので、1.06 のダウンロードは見送りたいと思います。


2015-10-25追記
T510 も、まだまだ現役で利用していますが、メインマシンは W520 に変更しました。
ThinkPad W520 で SSD 2台で IRST(インテルラピッドストレージテクノロジー)RAID1
ThinkPad W520 の HDD を SSD へ引越し

2013年3月24日日曜日

ThinkPad T510 + CentOS 6.4 に NVIDIA ドライバを導入する手順

現在、ThinkPad T510 をメインマシンとして利用しています。このマシンにはディスクリートGPU (NV3100M Optimus対応) が載っています。CentOS 6.4 の標準ドライバでも、とりあえずは X の起動に支障はないのですが、Desktop Effects を使いたいため、NVIDIA のドライバを導入してみました。以下、その手順です。

あらかじめ、NVIDIA のドライバをダウンロードしておきます。
# ls -l NVIDIA-Linux-x86-310.40.run 
-rwxr-xr-x 1 root root 38883580 Mar 24 11:51 NVIDIA-Linux-x86-310.40.run
NVIDIA ドライバは、dkms に対応しているので、もし dkms が未導入の場合は、EPEL から dkms を入れておきます。
# yum install dkms --enablerepo=epel
標準ドライバがロードされないように、/etc/modprobe.d/myblacklist.conf を新規作成して次のように設定します。
blacklist i915
blacklist nouveau
initramfs に反映するため、dracut コマンドを実行します。
# dracut -f /boot/initramfs-`uname -r`.img `uname -r`
再起動して、BIOS の設定を次のように変更します。
ランレベル3で起動して、ドライバをインストールします。
# ./NVIDIA-Linux-x86-310.40.run
簡単な英語で、いくつか尋ねられますが、特に dkms にするかどうかに注意すればよいかと思います。
# dkms status
nvidia, 310.40, 2.6.32-358.el6.nonpae.i686, i686: installed
spl, 0.6.0, 2.6.32-358.el6.nonpae.i686, i686: installed
zfs, 0.6.0, 2.6.32-358.el6.nonpae.i686, i686: installed

省電力機能も、ちゃんと動いている様子です。

2013-06-30
利用頻度は低いのですが、まだ CentOS 5 にも用があり、久々にマルチブート環境を起動していじくってましたが、FireFox のスクロールが遅くて耐えられず、CentOS 6 と同様に NVIDIA ドライバをインストールしてみたのですが、特に障壁はなく、すんなりインストールできました。

2014-11-14
CentOS 7 の場合については、こちらを参照。
ELRepo の kmod-nvidia を利用すると らくちん です。

2013年2月24日日曜日

NIC の ifup の際に eth パラメータを調整したい

CentOS 6 において、サーバ起動時の eth0 初期化時に、ethtool による調整を行いたいのですが、/etc/sysconfig/network-scripts/ifcfg-eth0 に指定可能な ETHTOOL_OPTS は、ethtool -s に対応しており、それ以外の ethtool 調整には対応していません。今回、ethtool -G による調整を行いたかった為、その方法について調べてみました。
真っ先に思いつく方法は、rc.local に書いてしまえばいいということなんですが、/sbin/ifup の内容を読んでみると、ローカルな設定を行えるようにする仕掛けがありました。次は、ifup から抜粋です。
...

if [ -x /sbin/ifup-pre-local ]; then
    /sbin/ifup-pre-local ${CONFIG} $2
fi

OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${DEVICETYPE}"

if [ ! -x ${OTHERSCRIPT} ]; then
    OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-eth"
fi

exec ${OTHERSCRIPT} ${CONFIG} $2

ということは、自分で /sbin/ifup-pre-local を用意すれば、所望の設定が出来そうです。次のような具合。
#!/bin/bash

DEV=${1/ifcfg-/}

if [ "$DEV" = "eth0" ] ; then
    ethtool -G $DEV rx 4096 tx 4096 2>/dev/null
fi
これで、うまくいきました。
# ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX:  4096
RX Mini: 0
RX Jumbo: 0
TX:  4096
Current hardware settings:
RX:  4096
RX Mini: 0
RX Jumbo: 0
TX:  4096

この黄色の部分を調整したかった。

2013-02-26追記
匿名さま、コメント(Bugzilla情報)をありがとうございました。ifcfg-eth0 に次のように指定すれば、ethtool -G も指定可能だったのですね。確認足りませんでした。orz
ETHTOOL_OPTS="-G \$REALDEVICE rx 4096 tx 4096"

2013-02-27追記
匿名さま、たびたびコメントを頂きありがとうございました。network-functions を見てみたら、ご指摘のとおり、eval のアイデアは取り込まれておりませんでした。というわけで、こうなってしまうのですね。
ETHTOOL_OPTS="-G eth0 rx 4096 tx 4096"
コピーして間違いを犯しそうではありますが。。

2013年1月17日木曜日

CentOS6 の cron.daily 実行時刻を CentOS5 以前と同様に設定する

CentOS6 の cron.daily 実行時刻は、CentOS5 以前とは異なります。
※この記事に書いた手順は、RHEL8 / RHEL7 / RHEL6でも通用します。末尾参照
CentOS5 以前であれば、デフォルトでは午前4:02にスケジュールされていましたが、CentOS6 のデフォルトでは、ある幅の範囲内でランダム化されています。
まずは、このランダム化の内容を確認してみます。

最初に /etc/crontab を見てみますと、次のように空っぽです。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

CentOS5 以前であれば、次のようにエントリーされていました。
02 4 * * * root run-parts /etc/cron.daily

ランダム化は、anacron (cronie-anacron) により行われており、設定内容は /etc/anacrontab に記述されています。デフォルトの /etc/anacrontab は、次の通りです。
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days   delay in minutes   job-identifier   command
1       5       cron.daily              nice run-parts /etc/cron.daily
7       25      cron.weekly             nice run-parts /etc/cron.weekly
@monthly 45     cron.monthly            nice run-parts /etc/cron.monthly
いくつかのパラメータがあり、man anacrontab(5) に解説がありますが、概説しますと、赤字の 1 (左端) が実行周期 (日次実行=1) で、次の数字 5 は、実行開始タイミングになってから、5 分間の遅延を入れる指定です。実行開始する時間帯は START_HOURS_RANGE で制御され、3-22 とは、3時から22時までの範囲 (3:00 ≦ t < 22:00) を指定しています。ランダム化の幅は RANDOM_DELAY で制御され、45 とは 0~45 分の範囲 (乱数計算の実装上、正確には 44 分まで) でランダムに遅延を行うことを指定しています。
やや複雑ですが、このデフォルト設定で 24H 運用した場合、cron.daily は午前3:06から3:50の間でランダム実行されることになります。ここで 3:06 なのは、そもそも anacron が動作する周期が毎時01分であるためです。/etc/cron.d/0hourly および /etc/cron.hourly/0anacron 参照。
また、もし毎日シャットダウン電源OFF運用を行う場合、例えば、午前6:00にブートすると、その直後の午前6:06から6:50の間でランダムに cron.daily が実行されることになります。
もしも、1日以上シャットダウンしていて、午後23:00にブートした場合には、START_HOURS_RANGE の範囲外であるため、cron.daily の実行は、翌日の午前3:06から3:50の間ということになります。

このランダム化は、仮想化環境を考慮してのこと (ゲストOSの cron.daily が重ならないようにする意図) とは思いますが、ランダムに動作されるのは運用上よろしくない (混乱要因となる) と考える方も居るかと思います。CentOS6 では、CentOS5 以前のように固定の時刻に cron.daily を行わせるようにする方法も用意されており、デフォルトでインストールされる cronie-anacron パッケージの代わりに、cronie-noanacron をインストールすればよいです。

パッケージの依存関係のため、事前に cronie-noanacron をインストールし、その後に cronie-anacron を削除するという手順を踏みます。
# yum install cronie-noanacron
...途中省略...
Installed:
  cronie-noanacron.x86_64 0:1.4.4-7.el6

Complete!

# rpm -e cronie-anacron
この cronie-noanacron は、ちっぽけなパッケージで、/etc/cron.d/dailyjobs ファイルだけを含んでいます。
# rpm -qi cronie-noanacron                                                   
Name        : cronie-noanacron             Relocations: (not relocatable)
Version     : 1.4.4                             Vendor: CentOS
Release     : 7.el6                         Build Date: Tue 19 Jul 2011 01:55:56 PM JST
Install Date: Thu 17 Jan 2013 12:02:39 AM JST      Build Host: c6b5.bsys.dev.centos.org
Group       : System Environment/Base       Source RPM: cronie-1.4.4-7.el6.src.rpm
Size        : 326                              License: MIT and BSD and ISC and GPLv2
Signature   : RSA/SHA1, Mon 26 Sep 2011 01:17:22 PM JST, Key ID 0946fca2c105b9de
Packager    : CentOS BuildSystem 
URL         : https://fedorahosted.org/cronie
Summary     : Utility for running simple regular jobs in old cron style
Description :
Old style of {hourly,daily,weekly,monthly}.jobs without anacron. No features.

# rpm -ql cronie-noanacron
/etc/cron.d/dailyjobs    ※パッケージの中身はこれ1個
/etc/cron.d/dailyjobs の中身は次のようになっています。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
02 4 * * * root [ ! -f /etc/cron.hourly/0anacron ] && run-parts /etc/cron.daily
22 4 * * 0 root [ ! -f /etc/cron.hourly/0anacron ] && run-parts /etc/cron.weekly
42 4 1 * * root [ ! -f /etc/cron.hourly/0anacron ] && run-parts /etc/cron.monthly
CentOS5 以前での運用経験があれば、見慣れた実行時刻かと思います。ただし、0anacron の存在チェックが行われており、cronie-anacron パッケージを削除しないと有効化されないようにガードされています。ご注意を。

すでにお分かりかとは思いますが、cron.weekly および cron.monthly も同様です。ただ、cron.hourly はランダム化されておらず、次のように /etc/cron.d/0hourly に設定が書かれています。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
01 * * * * root run-parts /etc/cron.hourly

最後に、いわずもがなですが、RHEL6 でも同様です :-p

2013-01-18追記
境界値がはっきりしないので、いちおう cronie-1.4.4-7.el6 のソースを見てみました。

START_HOURS_RANGE に対応する処理は、次の通りです。こちらは簡単ですね。
    422             t = localtime(&jobtime);
    423             if (range_start != -1 && range_stop != -1 &&
    424                 (t->tm_hour < range_start || t->tm_hour >= range_stop))
    425             {
    426                 Debug(("The job `%s' falls out of the %02d:00-%02d:00 hours range, skipping.",
    427                         job_array[j]->ident, range_start, range_stop));
    428                 job_array[j]->drop_job = 1;
    429             }
    430             else
"anacron/main.c"

RANDOM_DELAY に対応する処理は、次の通りです。
    279         if (strncmp(env_var, "RANDOM_DELAY", 12) == 0) {
    280             r = match_rx("^([[:digit:]]+)$", value, 0);
    281             if (r != -1) {
    282                 int i = random();
    283                 double x = 0;
    284                 x = (double) i / (double) RAND_MAX * (double) (atoi(value));
    285                 random_number = (int)x;    ※ここで小数点以下切捨てだからvalueは含まない?
    286                 Debug(("Randomized delay set: %d", random_number));
    287             }
    288         else goto reg_invalid;
    289         }
"anacron/readtab.c"
これを見ても、生成される random_number の範囲に value が含まれるのか否か、頭の中だけでは判然とせず。手間ですが、実験プログラムを一筆書いてみました。
/*
        test_random.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>

get_random_number(char *value)
{
        int random_number;

        // next 4 lines are copied from anacron/readtab.c:parse_tab_line()
        int i = random();
        double x = 0;
        x = (double) i / (double) RAND_MAX * (double) (atoi(value));
        random_number = (int)x;

        return random_number;
}

main(int argc, char* argv[])
{
        int i ;
        int random_number ;
        struct timeval tv ;
        struct timezone tz ;

        if (argc <= 1) exit(1) ;

        gettimeofday(&tv, &tz) ;
        // cronie uses this method
        srandom(getpid()+tv.tv_usec) ;

        for (i = 0; i < 10000; i++) {
                random_number = get_random_number(argv[1]) ;
                printf("%d\n", random_number) ;
        }
}
# gcc -o test_random test_random.c 
# ./test_random 10 | sort -n | uniq -c
    993 0
   1028 1
   1006 2
   1011 3
    998 4
   1030 5
    999 6
    966 7
    985 8
    984 9
# ./test_random 45 | sort -n | uniq -c | tail 
    210 35
    207 36
    218 37
    250 38
    197 39
    221 40
    217 41
    217 42
    209 43
    233 44
というわけで、0 ≦ random_number < value ですね。

2014-05-05追記
RHEL7.0 RC を試しましたが、RHEL6/CentOS6 と同様で、もし cron.daily 実行時刻を固定化したい場合は、cronie-noanacron と入れ替えれば良いようです。デフォルトの /etc/anacrontab の設定にも変更は無いようです。

2014-07-21追記
いちいち書くまでもないと思いつつ、RHEL7/CentOS7 でも同様です。

2019-05-26追記
CentOS8 は、現在のところ準備中のようです。
https://wiki.centos.org/About/Building_8
確認したところ RHEL8 でも、cronie-noanacron は存在しており、ここに書いた手順が通用するようです。
人気ブログランキングへ にほんブログ村 IT技術ブログへ