FreeBSD初めました。

ZFSを使ったStorage Tankを作りたくて、FreeBSDに手を出してしまいました。
ZFSを使うのであれば、Solarisを使ってiSCSIと連携することも考えたのですが、Solarisには未来が無さそうなので、FreeBSDでいきたいと思います。
また、FreeBSDは最新のRelease版である9.0を使いたいと思います。

筐体としては、手持ちのデスクトップPCを最近使わなくなったので、これを流用する予定です。
Hardware構成は大体こんな感じです。

  • Memory: 12GB(2GB * 2, 4GB * 2)
  • Hard Disk: Total 16TB
    • 1.5TB * 2
    • 2.0TB * 2
    • 3.0TB * 3
  • SSD: 64GB
  • 追加購入予定の物品
    • ZIL/L2ARK用 SSD 60GB(Made by Intel)
    • 古いHDD置き換え用 HDD 3.0TB * 4

ZFSで以下のような構成にする予定です。
せっかくなので、SystemはZFS Bootにする想定です。
手持ちのHDDの容量がバラバラなので、今後サイズを揃えたらESXi_Pool, Shared_Poolは統合してRAIDZ2で組もうかと思っています。

  • System_Pool
    • 1.5TB * 2 RAID1(Mirror)
  • ESXi_Pool
    • 2.0TB * 2 RAID1(Mirror)
  • Shared_Pool
    • 3.0TB * 3 RAIDZ1(Parity)
  • ZIL/L2ARC

とりあえずFreeBSD9.0のインストールまで完了しました。
FreeBSDはハンドブックがあり、内容がたいへん充実しているので、こちらを見て進めれば特に困ることは無いと思います。

bannerコマンドを入れる。

驚くべきことですが、CentOSにはBannerコマンドが入っていないようです。
しばらく使っていなかったのですが、ふとした時に冗談で使おうとしてコマンドが入っていないことに愕然としました。
という訳でインストールしようとしたのですが、CentOS 6.3ではyumコマンドでインストールできなかったので、ソースからインストールしました。

ダウンロード

以下のサイトからダウンロードします。

# pwd
/usr/local/src
# wget http://software.cedar-solutions.com/ftp/software/banner-1.3.2.tar.gz
インストール
# tar xvfz banner-1.3.2.tar.gz
# cd banner-1.3.2
# ./configure
# make
# make install
インストールされていることを確認
# which banner
/usr/local/bin/banner
# banner a

      #     
   #     #    
 #         #   
#           #  
#######  
#           #  
#           #  

配列の違うキーボードを同時に使う。

おぼうなす様の時期なので、ずっと欲しかったHappy Hacking Keyboard Type-Sを買いました。
オフィスでは主に日本語キーボードのノートPCをメインに利用しているのですが、今回は英字配列のものを購入し、外付けキーボードとして利用します。

英字キーボードを直接接続しても日本語キーボードとして認識されてしまうため、レジストリを変更して英字キーボードとして認識させる必要があります。
また、今回はノートPCの内蔵キーボードと外付けキーボードの配列が違うため、それぞれ別のキーボードとして動作してもらわねばなりません。

調べてみると、やはりこのような使い方をしている方は多いようです。
今回は、下記のサイトを参考に設定してみました。

http://se-suganuma.blogspot.jp/2011/03/lets-note-cf-s9usb.html

私はノートPCにWindows Server 2008 R2をインストールして利用していますが、レジストリは同様の変更で無事に設定できました。

以下、手順です。

  1. regeditで以下のキーを開く。
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\i8042prt\Parameters

※念のため、"キーの名前を右クリック -> エクスポート"で変更前にバックアップを推奨。

  1. LayerDriverの値を次の通り変更。
    • JPN kbd106.dll -> kbd101.dll
  2. OverideKeyboardIdentifierの値を次の通り変更。
    • PCAT_106KEY -> PCAT_101KEY
  3. OS再起動。

なお、内蔵キーボードも変更したい場合は、以下のパラメータも変更する。

  • OverrideKeyBoardSubtyp
    • 2 -> 0

これで無事に、内蔵キーボード:日本語配列、外付けキーボード:英語配列として利用することができました。
英語配列で使うと全角/半角キーが無くてIMEの切り替えが不便ですが、私の場合はずっとCtrl+SpaceをIME切り替えに割り当てて使っていたため、特に問題ありませんでした。

蛇足ですが、変更前後の設定を両方ともエクスポートしてバックアップしておけば、外付けキーボードを状況によって付け替えたとしても、regファイルを実行して再起動すれば切り替えられるようになりますね。

expect内でループ処理をする。

Linux等のリモートサーバ上で自動的に処理をさせたい場合、expectを使うのが一般的です。
今回はexpectを使って、リモートサーバ側でwhileを使った処理をさせた時のメモです。
今回やりたかったことは、サーバAからサーバBにログインし、複数ノードにPingを打つ、というような処理です。

expectの構文はtcl文法

今までよく知らずに使っていましたが、expectはtcl文法を使っていたので、下記の書式でループを作ることができました。

while { 条件式 } {
    処理
}

例) sshで入ったサーバから、192.168.1.0-128のノードにPingを打って抜ける。
こんな感じで出来ました。

#!/bin/bash

SSHHOST=hoge001
password="hogehoge"
PINGHOST="192.168.1."

expect -c "
    spawn ssh -l root $SSHHOST
    expect \"password:\" {
    send \"$password\n\"
    } \"Are you sure you want to continue connecting (yes/no)?\" {
    send \"yes\n\"
    expect \"password:\"
    send \"$password\n\"
    }
 
    set i 0
    while {\$i <= 128} {
        send \"sleep 1\n\"
        expect \"\[$username@$hostname ~\]$\"
        send \"/bin/ping -c $PINGHOST\$i\n\"
        expect \"\[$username@$hostname ~\]$\"
        incr i 1
    }

    send \"sleep 1\n\"
    expect \"\[$username@$hostname ~\]$\"
    send \"exit\n\"

    interact
"

ハマったところ

expect内で定義した変数(上記の例では"i")は、変数を使う時、事前にバックスラッシュ or 円記号を付けないとダメでした。
expect外で定義した変数は"$username"といった形で呼び出せます。

expect内で定義した変数は \$変数名 とする。

i => \$i

expect外で定義した変数は $変数名 でOK。

username => $username

桁合わせした数字の出力。

最近テスト用のシェルスクリプトを書く機会が多く、ホスト名の生成等で数字の桁合わせをしなければならなかったので、方法を調べてみました。

Linuxで桁合わせをした数字を出力する方法

seqを使う。
  • 今まで知らなかったのですが、seqというコマンドがありました。これは特定範囲の数字を生成するコマンドとのことです。
$ seq 5 10
5
6
7
8
9
10
  • "-w" オプションを使うと、桁合わせができます。
$ seq -w 5 10
05
06
07
08
09
10
  • forを使って文字列と組み合わせ
for i in `seq -w 5 10`
do
    echo "hogehost$i"
done
  • こんな感じで出力されます。
hogehost05
hogehost06
hogehost07
hogehost08
hogehost09
hogehost10
printfを使う。
  • 先ほどまで上記の方法を知らなかったので、whileとprintfを使って桁合わせをしていました。
HOSTNAME=()
i=0
while [ $i -ne 10 ]
do
    i=`expr $i + 1`
    HOSTNAME[$i]="hogehost`printf %02d $i`"
    echo ${HOSTNAME[$i]}
done
  • printfを使った方がプログラマっぽい書き方でしょうか。出力するとこうなります。
hogehost01
hogehost02
hogehost03
hogehost04
hogehost05
hogehost06
hogehost07
hogehost08
hogehost09
hogehost10

logrotateしているログファイル名に日付を付与する。

さくらのVPS契約してみたら設定されていた、なんていう恥ずかしい理由で知りました。

普通のlogrotateの設定だと、ローテートしているログファイルはmessages.1みたいな感じで一体いつ出たログなのか、よくわかりません。
最近のlogrotateにはdateextというオプションがあるようで、これを設定することでローテートしたログファイルに日付を付けられるようです。
こんな感じ。

 # see "man logrotate" for details
 # rotate log files weekly
 weekly
 
 # keep 4 weeks worth of backlogs
 rotate 4
 
 # create new (empty) log files after rotating old ones
 create
 
 # use date as a suffix of the rotated file
 dateext
 
 # uncomment this if you want your log files compressed
 #compress
 
 # RPM packages drop log rotation information into this directory
 include /etc/logrotate.d
 
 # no packages own wtmp and btmp -- we'll rotate them here
 /var/log/wtmp {
     monthly
     create 0664 root utmp
         minsize 1M
     rotate 1
 }
 
 /var/log/btmp {
     missingok
     monthly
     create 0600 root utmp
     rotate 1
 }
# system-specific logs may be also be configured here.

こんな感じでローテートされます。

 [root@localhost log]# ls -ltr messages*
 -rw------- 1 root root 1588 Apr 29 03:17 messages-20120429
 -rw------- 1 root root  517 May  6 04:29 messages-20120506
 -rw------- 1 root root  448 May 13 04:00 messages-20120513
 -rw------- 1 root root  448 May 20 04:50 messages-20120520
 -rw------- 1 root root  219 May 20 04:50 messages

RHELで大量のユーザパスワードを設定する。

RHELで大量のユーザを作成、初期パスワードを設定する、ということがあり、めんどうなのでシェルスクリプトでやりました。

シェルスクリプトでパスワードを設定するには chpasswd コマンドを使う。

今回は取り急ぎユーザ名とパスワードを同一のものとしたため、スクリプト自体は非常に簡単なものになりました。

なお、シェルスクリプトでパスワードを設定する場合、passwd コマンドでは、結局手入力になってしまいます。
大変便利なことに、シェルスクリプトでパスワードを設定するために(?)用意されているchpasswdというコマンドがあります。

chpasswdコマンドは、普通に実行すると入力待ちとなり、
ユーザ名:パスワード
という形式で入力するだけでたくさんのユーザのパスワードを一気に変更することができます。

[root@localhost ~]# chpasswd
user1:pass1
user2:pass2
user3:pass3

という訳で/etc/passwdからユーザを抜き出して、こんな感じで作成しました。

 #!/bin/sh
 user=`cat /etc/passwd | grep -e hoge -e piyo | awk -F":" '{print $1}'`
 
 for i in $user
 do
    echo $i":"$i | /usr/sbin/chpasswd
 done