linuxの最近のブログ記事

5台で運用してるdebianサーバのカーネルを合わせるために、うち1台でビルドしたカーネルはdebパッケージにして配布してるのですがね。e1000eドライバはIntelのダウンロードセンターから取り寄せて組み込んでいるので、ちょっと手順が複雑な上に間隔が空くとすぐに忘れちゃうんですよ。いやだわおぢいちゃんたら晩ご飯ならさっき食べたでしょ。

なお、前段階として

とかも忘れないでね。良い子のお約束だゾ。

$ tar jxf linux-x.y.z.tar.bz2 -C /usr/src
$ tar zxf e1000e-p.q.r.tar.gz -C ~
$ cd /usr/src/linux-x.y.z
$ make menuconfig
$ make-kpkg clean
$ fakeroot make-kpkg --initrd --revision=abc.0.1 kernel_image
(ここで途中、include/generatedに生成された?ヘッダファイルがinclude/linuxに無いのでとエラーが起こるので)
$ cd ~/e1000e-p.q.r/src/
$ env BUILD_KERNEL=x.y.z make
$ cd /usr/src/linux-x.y.z/drivers/net/
$ mv ./e1000e ~/e1000e.old && cp -r ~/e1000e-p.q.r/src ./e1000e
$ cd ../../include/generated/
$ mv * ../linux/
$ cd ../..
$ fakeroot make-kpkg --initrd --revision=abc.0.1 kernel_image
(で、~hoge/直下にlinux-image-x.y.z_abc.0.1_amd64.debとか何か出来てないか確認したまへ)

で、完成のもより。

おうちでgangliaとか

| コメント(0) | トラックバック(0)

結局スイッチの件は無事発注しなおしができましたよということで、気を取り直して次のネタ。

せっかく何台もサーバを揃えたのでやってみたいじゃないですかとgangliaを入れてみた。

http://ganglia.sourceforge.net/
Ganglia Monitoring System

インストール時につっかえたのは「date.timezone」の設定を明示的に行っておかないとphpがだだをこねてwarningを出しまくると言う点。ちなみにうちのphpは現時点最新の5.3.2。php.iniを作成してそこで指定しておくことにした。

あと、GDモジュールが必要。と言っても円グラフを少し入れたりするのに使ってる程度だけど、うちではphpのconfigureしてたときに--with-gdオプションを付けてなかったこともあってインストールされていなかった模様。GDはdebパッケージなので(libgd2-xpm)、開発用パッケージ(libgd2-xpm-dev)も忘れずにインストール。その後--with-gd付きで再度ビルドしなおして事なきを得た。

ganglia自体もsqueezeには入ってるらしいganglia-webfrontendパッケージはまだlennyには降りて来ていないっぽく、またdeb自体もバージョン2.5.xとやや古めで設定ファイルの書式なども違っていたので、3.1.7をこちらもソースからビルドしてインストール。こちらもそんなに引っかかること無くインストールできました。 

さて、ここまでUnix Benchをただ走らすだけ走らせてみたけど、内容にもちゃんと踏み込まないと逝けませんよねということでソースの中身を検証してみます。

まず何より気になっていたのがAMD系からIntel系に切り替えて歴然と違いが出たSystem Call Overhead。Unix Benchのテストはtarballを解凍した中にある"Run"スクリプトから全てが始まりますが、こいつは配下にpgmsディレクトリを持っていて、そこに配置された各テストプログラムを起動するだけです。

Runスクリプトの中ではそれらテストプログラムとその説明や起動時のオプション(何回・何秒ループさせるとか、テストの種類を指定する)の情報をハッシュで保持しています。

# Individual parameters for all benchmarks.
my $testParams = {

    ##########################
    ## System Benchmarks    ##
    ##########################

    "dhry2reg" => {
        "logmsg" => "Dhrystone 2 using register variables",
        "cat"    => 'system',
        "options" => "10",
        "repeat" => 'long',
    },
    "whetstone-double" => {
        "logmsg" => "Double-Precision Whetstone",
        "cat"    => 'system',
        "repeat" => 'long',
    },
    "syscall" => {
        "logmsg" => "System Call Overhead",
        "cat"    => 'system',
        "repeat" => 'long',
        "options" => "10",
    },
    "context1" => {
        "logmsg" => "Pipe-based Context Switching",
        "cat"    => 'system',
        "repeat" => 'long',
        "options" => "10",
    },
...
};

"System Call Overhead"、つまりsyscallの項目に格納されていることになります。そしてこの場合、"syscall"のキーが起動するテストプログラム名に対応付けされていて、それは(unixbenchディレクトリ)/pgms/syscallとなります。またこれのソースが(unixbenchディレクトリ)/src/syscall.cとなります。

また起動時の引数はさらに下位ハッシュの"options"に格納されていますがこちらは"10"となっています。つまりここから"System Call Overhead"のテストを起動するときは、コマンドラインで仮定すれば"./pgms/syscall 10"として起動することになります。

        switch (test[0]) {
        case 'm':
           while (1) {
                close(dup(0));
                getpid();
                getuid();
                umask(022);
                iter++;
           }
           /* NOTREACHED */
        case 'c':
           while (1) {
                close(dup(0));
                iter++;
           }
           /* NOTREACHED */
        case 'g':
           while (1) {
                getpid();
                iter++;
           }
           /* NOTREACHED */
           ...
        }
        ...

syscallテストプログラムでは第2引数でテストの種類を指定することができ、それが上のコードサンプルのswitch(test[0])の行に対応しています。無指定の場合は"mix"が指定されたのと同じとなっていて、上記サンプルで言えば続くcase 'm':行以下のwhileループがそれに相当することになります。ループが1回回るたびにiter変数がインクリメントされるので、最終的にこのiterの値がいくつになったかがテスト結果となります。whileは見た目上永久ループになっていますが、SIGALRMによって抜け出すようになっています。テスト起動時の第1引数がテストの継続時間となっていて、これがalarm()に使われている訳です。

つまり、上記のコードサンプルからすると、close()/dup()/getpid()/getuid()/umask()の5つのシステムコール関数のいずれかがAMD/Intel両アーキテクチャ間での性能差を引き出していたことになるわけです。うーん。惜しむらくはここを気にする前にAthlon/Phenomとも手放してしまったことですが...。こちらを見る限り、これはAthlon/Phenom共々出ている傾向のようなんですよね。

PC内温度を監視するよ

| コメント(1) | トラックバック(0)

OCなんてCPUを早くダメにするだけだと思ってる(本当の所は知らないが)くらいなので、今までPC組むのに冷却なんてほとんど考えてなくて、というか考えるような攻めの構成はほとんどやったことがない。ので、今回Phenom II X4の965BEは爆熱だよなんて話を聞いてちょっと青ざめたのは確かだ。

というか、冷却のためのCPUクーラーがえらいうるさい。リテールクーラーの悪評は紛々たるものらしく、ちょっとぐぐっただけでもブログ記事とか実証動画だとかがアホの子のごとく出てくる。

で、気になって色々と調べてみた。いずれもdebian lenny(kernel: 2.6.26.2)。

まずAMD組、lm-sensorsをつっこもうとしたら、AMD系ではそのままでは温度が取得できないらしい。k10tempというのを持って来てmake & install。すると1ヶ所しか取れないのは何だろう。CPU温度かな。

http://khali.linux-fr.org/devel/misc/k10temp/
Index of /devel/misc/k10temp

# aptitude install linux-headers-2.6.26-2-amd64 (←/lib/modules/2.6.26.2-amd64/buildを見るので)
# mkdir k10temp
# cd k10temp
# wget http://khali.linux-fr.org/devel/misc/k10temp/Makefile
# wget http://khali.linux-fr.org/devel/misc/k10temp/k10temp.c
# make 
# make install
# depmod -a (←make installの途中でdepmodのところでミスるので手でやりなおした)
hironobu@emma:~$ sensors
k10temp-pci-00c3
Adapter: PCI adapter
temp1:       +38.1°C  (high = +70.0°C, crit = +72.0°C)  

Atom組の方も見てみると、こちらはlm-sensorsのインストールのみですぐ出て来たものの、M/B温度が70度近くとか言っちゃってこっちもこっちで結構な数字が出ているじゃないか。まあファンレスだから仕方ないんだと思うけども。

hironobu@shirley:~$ sensors
w83627thf-isa-0290
Adapter: ISA adapter
VCore:       +1.15 V  (min =  +0.00 V, max =  +3.84 V)   
+12V:        +3.83 V  (min = +15.44 V, max =  +2.37 V)   ALARM
+3.3V:       +1.89 V  (min =  +1.87 V, max =  +3.10 V)   
+5V:         +4.91 V  (min =  +1.25 V, max =  +2.56 V)   ALARM
-12V:        +2.03 V  (min =  +6.06 V, max =  -2.74 V)   ALARM
V5SB:        +4.95 V  (min =  +2.34 V, max =  +2.96 V)   ALARM
VBat:        +3.23 V  (min =  +2.91 V, max =  +2.00 V)   ALARM
fan1:          0 RPM  (min =  827 RPM, div = 8)  ALARM
CPU Fan:       0 RPM  (min = 2343 RPM, div = 4)  ALARM
fan3:          0 RPM  (min = 6026 RPM, div = 2)  ALARM
M/B Temp:    +67.0°C  (high = -33.0°C, hyst = +32.0°C)  ALARM  sensor = thermistor
CPU Temp:    +53.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = diode
temp3:       +53.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = diode
beep_enable:enabled

さて、旧サーバ(old shirley)を退役させるためにHDDを掃除しなきゃいけないわけですが、以前はUSBフロッピードライブをもってきてDESTROYとかやってたんですけど、先日から探してるのに肝心のドライブが出てこない(何)。そんなわけで、Knoppixを使ってUSBメモリにブートイメージをつっこんでshredすることに。

というわけで皆様材料はこちらになります。鶏肉に卵と玉ねぎ、お醤油みりん砂糖...あれ。

  • USBメモリ (容量1GBもあればOK、FATでフォーマット済みの)
  • KnoppixのISOイメージ(最新)
  • SYSLINUX(最新)
  • Linux PC 1台

ぐぐると結構皆さんCD-Rを使って焼いたりとかそうでなくてもDaemontoolsを持って来たりとかやってますが、WindowsでなくてLinuxでやれば、それらと同じ作業はすべて標準で入ってるので、格段に簡単にできます。っていうか、本当は簡単にできるはずなんだけどついつい手順を忘れて何となくめんどくさがりがち...。全然むずかしいこっちゃないですよと、備忘録として記して忘れないようにしておくのでござるよ。

http://www.knopper.net/knoppix-mirrors/
KNOPPIX - Mirrors

Knoppixはこのミラーリストからダウンロード。日本語サイトがなんかやたら古かったりデッドリンクばかりと不安な空気を醸し出しているので、そちらは振り切って本家サイトに逝くでござるよ。

http://www.kernel.org/pub/linux/utils/boot/syslinux/
Index of /pub/linux/utils/boot/syslinux

SYSLINUXも同じく最新を。tar+gzでもtar+bz2でもzipでもどれでもござれ。であとは下のように1)USBメモリをマウント、2)KnoppixのISOもマウント、3)Knoppixの内容物(/boot/isolinux/*,/KNOPPIX)をUSBメモリにコピー、4)USBメモリ内にコピーした/isolinux.cfgを/syslinux.cfgにリネーム、5)SYSLINUXをUSBメモリにインストール、で完了。

~# mkdir ./tmp
~# mount -o loop ./KNOPPIX_V6.2CD-2009-11-18-EN.iso ./tmp
~# mount /dev/sdb /mnt
~# cp -pr ./tmp/boot/isolinux/* /mnt/
~# cp -pr ./tmp/KNOPPIX /mnt/
~# cd /mnt
~# mv isolinux.cfg syslinux.cfg
~# ~/syslinux-3.86/linux/syslinux /dev/sdb
(※USBメモリを/dev/sdb、またisoとsyslinuxのtarballをrootのホームディレクトリに置いて解凍したとして仮定。)

あとはKnoppixのisoイメージ(~/tmp)とUSBメモリ(/mnt)をアンマウントして、目的のPCにUSBメモリを刺して起動すればいいだよ。

Receive-Side Scalingとな?

| コメント(0) | トラックバック(0)

(11:48訂正、shirley(M/B:D510MO/NIC:Realtek8111DL)だと無手順でばらけました。)

前のエントリで書いたApache Benchの件は、ちと早計というか、違う問題のようだということが分かって来た。あのあとぐぐってみると、気になる記事を見つけたの。

http://blog.nomadscafe.jp/2010/01/cpu.html
アプリケーションがマルチスレッドでもマルチコアCPUを活かせない件 - blog.nomadscafe.jp

memcachedの通信は主にeth1で行われるのですが、このeth1に関する割り込み処理がCPU1でしか行われていません。ソフトウェア割り込みはハードウェア割り込みが行われたCPUでしか行われないのもこの傾向を強めます。

マルチコアCPUの性能を活かすために考えられることは、ネットワークの割り込み処理を複数のCPUに分散することだと思うのですが、最新のNICにはRX/TX Multiple Queue(正式名称がわからない。Receive Side ScalingとかScalable I/O?)機能が備わっています。もともとRX/TX Multiple Queueは10GbpsのNICなどに備わっていた機能で、複数の割り込みチャンネルを持つことでネットワーク処理の分散を実現しています。最近のIntelやBroadcomの1GbpsのNICにも同じ機能があります。

emma:~# cat /proc/interrupts 
            CPU0       CPU1       CPU2       CPU3       
   0:         45          0          6          0   IO-APIC-edge      timer
   1:          0          0          8          0   IO-APIC-edge      i8042
   6:          1          0          2          0   IO-APIC-edge      floppy
   7:          0          0          0          0   IO-APIC-edge      parport0
   8:          0          0          1          0   IO-APIC-edge      rtc0
   9:          0          0          0          0   IO-APIC-fasteoi   acpi
  14:          0          0          0          0   IO-APIC-edge      ide0
  15:          0          0          0          0   IO-APIC-edge      ide1
  16:          0          0        236          0   IO-APIC-fasteoi   ohci_hcd:usb1, ohci_hcd:usb3, hda_intel
  17:          0          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb2
  18:          0          0          0          0   IO-APIC-fasteoi   ohci_hcd:usb5, ohci_hcd:usb6, ohci_hcd:usb7
  19:          0          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb4
  22:          0          0       2002          2   IO-APIC-fasteoi   ohci1394, ahci
  25:          0          0       3150          0   PCI-MSI-edge      eth0
  26:          0          0          0          0   PCI-MSI-edge      hda_intel
 NMI:          0          0          0          0   Non-maskable interrupts
 LOC:       8113      12668       9084       7116   Local timer interrupts
 SPU:          0          0          0          0   Spurious interrupts
 PMI:          0          0          0          0   Performance monitoring interrupts
 PND:          0          0          0          0   Performance pending work
 RES:       3646       3930       2110       2260   Rescheduling interrupts
 CAL:         42        124        135        122   Function call interrupts
 TLB:          4          0          3          7   TLB shootdowns
 TRM:          0          0          0          0   Thermal event interrupts
 THR:          0          0          0          0   Threshold APIC interrupts
 MCE:          0          0          0          0   Machine check exceptions
 MCP:          6          6          6          6   Machine check polls
 ERR:          4
 MIS:          0

確かにこのページで語られてるのと同じ状況。mary,emmaでも同じだった。httpdを入れてないので確認してないけど、/proc/interruptsを見る限りnellyでも同じっぽい。shirleyではばらけたぞ。

うちのマシンは揃ってRealTek製の8111C(shirleyだけ8111DL)のチップだったのだけど、これらは"Receive-Side Scaling"の機能であれば対応しているらしい。

http://www.realtek.com.tw/products/productsView.aspx?Langid=1&PFid=5&Level=5&Conn=4&ProdID=142
Realtek (8111C)

http://www.realtek.com.tw/products/productsView.aspx?Langid=1&PNid=13&PFid=5&Level=5&Conn=4&ProdID=193
Realtek (8111DL)

これがLinux上でどう対応づけすればいいのか調べ中でござる...。

手元のテキストファイルでUTF-8のがあって、適当なスクリプトやアプリケーションに渡してテキスト処理を行っていたのがどうもうまくいかないことがあったので、よく見てみたら先頭にBOMがついていたときの話。

nkfのマニュアルを見たところ、-wと-w8とでBOMの有無を区別してくれるので、こいつに通せばよしなに変換してくれるかと思ったけども、どうやら入力ではBOMを判別してはくれないらしい。変化はなかった。ちなみにバージョンは2.0.7。

ここで変換によるBOM取りをあきらめてエディタで削除する方針に変更。何もしないとvimはBOM付きでもちゃんと認識して表示を隠してくれるので、隠さず見せるようにバイナリモードで読む必要があり。

$ vim -b hogehoge.txt

これでok。

<feff>hoge
このようにして見せてくれるので、<feff>を消せばよい。
最近tinydnsでのDNS管理のが多いんだけど一方でBINDも使ってたりするので、両者の間で移管作業とかなるとちょっとくらくらする。しかも趣味でなく業務だったりすると一個でもRR抜けたりすると下手すりゃ血を見るのでまあがくぶるなわけで。

configureのパラメータ設定

やっぱりこれもSRPMのspecから。でもこれいくら何でも冗長すぎだよなあ。

./configure \
        --prefix=/usr/local/app/php-5.2.3/ \
        --with-layout=GNU \
        --with-libdir=lib64 \
        --with-config-file-path=/usr/local/etc/php \
        --with-exec-dir=/usr/local/app/php-5.2.3/bin \
        --includedir=/usr/local/app/php-5.2.3/include \
        --sysconfdir=/usr/local/etc/php \
        --localstatedir=/var \
        --disable-debug \
        --with-pear \
        --with-pic \
        --disable-rpath \
        --with-bz2 \
        --with-curl \
        --with-freetype-dir=/usr \
        --with-png-dir=/usr \
        --enable-gd-native-ttf \
        --without-gdbm \
        --with-gettext \
        --with-gmp \
        --with-iconv \
        --with-jpeg-dir=/usr \
        --with-openssl \
        --with-png \
        --with-pspell \
        --with-expat-dir=/usr \
        --with-pcre-regex=/usr \
        --with-zlib \
        --enable-exif \
        --enable-ftp \
        --enable-magic-quotes \
        --enable-sockets \
        --enable-sysvsem --enable-sysvshm --enable-sysvmsg \
        --enable-track-vars \
        --enable-trans-sid \
        --enable-yp \
        --enable-wddx \
        --with-kerberos \
        --enable-ucd-snmp-hack \
        --with-unixODBC=shared,/usr \
        --enable-memory-limit \
        --enable-shmop \
        --enable-calendar \
        --enable-dbx \
        --enable-dio \
        --with-mime-magic=/usr/local/etc/httpd/magic \
        --without-sqlite \
        --with-libxml-dir=/usr \
        --with-xml \
        --with-apxs2=/usr/local/app/httpd/bin/apxs \
        --without-mysql --without-gd \
        --without-odbc --disable-dom \
        --disable-dba --without-unixODBC \
        --disable-pdo --disable-xmlreader --disable-xmlwriter

config.layoutの編集

まず、configureでどんだけいじっても*.pidファイルとログの生成ディレクトリは${localstatedir}/logs、buildディレクトリ以下(って何に使うんかね?)が${datadir}/build以下に置かれる状況が変えられないので直接ファイル書き換えで対応する。*.pid等は${localstatedir}/run/httpd、ログは${localstatedir}/log/httpd、buildはprefix(exec_prefix)下にとそれぞれ調整。

--- config.layout.orig  2007-08-02 22:53:45.000000000 +0900
+++ config.layout       2007-08-02 22:54:28.000000000 +0900
@@ -20,7 +20,7 @@
     mandir:        ${prefix}/man
     sysconfdir:    ${prefix}/conf
     datadir:       ${prefix}
-    installbuilddir: ${datadir}/build
+    installbuilddir: ${exec_prefix}/build
     errordir:      ${datadir}/error
     iconsdir:      ${datadir}/icons
     htdocsdir:     ${datadir}/htdocs
@@ -28,8 +28,8 @@
     cgidir:        ${datadir}/cgi-bin
     includedir:    ${prefix}/include
     localstatedir: ${prefix}
-    runtimedir:    ${localstatedir}/logs
-    logfiledir:    ${localstatedir}/logs
+    runtimedir:    ${localstatedir}/run/httpd
+    logfiledir:    ${localstatedir}/log/httpd
     proxycachedir: ${localstatedir}/proxy
 

configureのパラメータ指定

SRPMのspecを参考に。

./configure \
  --prefix=/usr/local/app/httpd-2.2.4 \
  --sysconfdir=/usr/local/etc/httpd \
  --datadir=/var/www \
  --localstatedir=/var \
  --with-apr=/usr/bin/apr-1-config \
  --with-apr-util=/usr/bin/apu-1-config \
  --with-mpm=prefork \
  --enable-mods-shared=all \
  --enable-pie \
  --with-pcre \
  --enable-ssl \
  --with-ssl \
  --enable-ldap \
  --with-ldap \
  --enable-distcache \
  --enable-proxy \
  --enable-cache \
  --enable-mem-cache \
  --enable-file-cache \
  --enable-disk-cache \
  --enable-authnz-ldap \
  --enable-cgid \
  --enable-authn-anon \
  --enable-authn-alias

あとは普通にmake; make install。

ログディレクトリと設定ファイルディレクトリへのシンボリックリンクを張る

インストールしたあと、/usr/local/app/httpd-2.2.4 ディレクトリからログディレクトリと設定ファイルディレクトリを参照できるようシンボリックリンクを設定する。

# cd /usr/local/app/httpd-2.2.4
# ln -s ../../../../var/log/httpd logs
# ln -s ../../etc/httpd conf

こんなとこかな。