ラベル Linux の投稿を表示しています。 すべての投稿を表示
ラベル Linux の投稿を表示しています。 すべての投稿を表示

2014/02/09

ext3ファイルシステムにはデフラグは本当に要らないのか?

またLinuxの小ネタですが、どうも巷では
ext3・4ファイルシステムはNTFSと違ってフラグメントしないのでデフラグしなくてよい
といった話が出たり消えたりするようです(季節ものの話題)。

ファイルシステムがフラグメントすると何が悪いかというと、I/Oの数(いわゆるIOPS)が増えることと、ストレージ側のキャッシュ効率が悪くなることです。普通のストレージはSCSIコマンドに乗っけたデータを受け付けるわけですが、SCSIコマンドは「一定の連続したブロック」を処理します。40KBのデータが連続していればひとつのSCSIコマンドでカバーできますが、完全にフラグメントしていると(4KBブロックだとして)10回分のコマンド処理が必要になります。

SCSIコマンドのリファレンス(Seagate社)

ストレージ側のコントローラにもSCSIコマンドを処理するためのプロセッサが乗っていて、サーバーの方からやってくるSCSIコマンドを一生懸命処理しているので、これが増えるのは望ましくないわけです。あまり数が多いとストレージ側のプロセッサが処理しきれなくて、いわゆるコントローラのCPU使用率が上がった状態になってしまいます。

ストレージ側のキャッシュもブロック位置の局所性を期待したものとなるので、フラグメントされたファイルだとヒット率も必然的に下がります。

さて、結論を言うとext3・4はごく普通のファイルシステムなので、フラグメントはします。ファイルもフラグメントするし、空き領域もフラグメントします。だからといって、たとえば複数のプロセスが並列にI/Oを出すと、それぞれが順番にブロックを取っていくので片っ端からフラグメントしてしまうのかというとそういうことはなくて、できるだけ連続した領域が割り当たるように工夫されています。

ext3では、ブロックリザベーションという仕組みで、iノードに対して一定の領域のブロックを「予約(仮押さえ)」してくれます(デフォルトで8ブロック、最大で1027ブロック)。つまり、iノードを作ってデータを書いたら、その先の部分をそのファイル用に取り置きしておいて追加のデータが来ればそこお使えるようにする感じでしょうか。ディスク容量が僅少となってなかったりフラグメントが激しくなっていないうちは、連続領域が割り当てられることが期待できます。

ちなみに、(あまり変更の必要はないかもしれないですけど)このリザベーションの量は、ファイル単位でioctl(2)で変更することができます(ただし、一度iノードがメモリから落ちてしまうと設定が消えてしまうようですが)。

EXT3_IOC_GETRSVSZ
EXT3_IOC_SETRSVSZ

ext4だと、このあたりのリザベーションの仕組みはなくなっていて、かわりにdelayed allocation(遅延ブロック割り当て)でカバーされているようですが、これはこれでまた別の問題を引き起こすからなかなか難しいですね。

2014/02/04

CentOSの素カーネルとCentOS Plus

SystemTapを掛けようとするとエラーになるので、なんでだろうと思ったら、

  • CentOSの素のカーネル(RHELとほぼ同じなのでしょう)
  • CentOS Plusカーネル(CentOSでパッチを当てたりしているようです)
という二種類があって、後者が適用されているのに、前者用のdebuginfoがインストールされていたというオチでした。

2014/01/14

AWSのRoute53でDDNS (Dynamic DNS)

AWSにはRoute53というDNSサービスがあって、外からIPをAPIで登録できるのでDynamicDNSの代わりに使えるようです。

これまではmydnsというサービスを利用させてもらっていて、そちらはそちらですごく安定していて良いサービスなのですが、新年を機会にAWSに移行してみることにしました。

DynamicDNSで、IPは動的IPなので、当然一定期間なりで内容を更新していかないといけません。
今回、更新用のクライアントはQNAP NAS上に配置してみました(Raspberry Piでも良いのですが、最近SDカード上のファイルシステムがぶっ壊れて止まっていることがあったので)。

ただ今にして思うとRaspberry Piの方が簡単だったような気もします。QNAPのipkgとperlに手こずりました。

以下、覚え書き。

まずはじめにAWS側の設定ですが、これはRoute53のウェブ画面で登録するだけで簡単です。
Hosted Zonesページで、「Create Hosted Zones」ボタンを押してゾーンを登録します。


これでゾーンができるので、Hosted Zone IDというのを控えておきます(控えなくてもいつでも見られますが)。
作成したゾーンを選択して、上の方に「Go to Record Sets」というボタンがあるので押します。


すると、以下のようにレコード画面になります。
最初は、SOAレコードとNSレコードしかないので、Create Record Setを押して、適当にAレコードを追加します。

ここまででAWS側の設定は終わりです。簡単です。

次に、QNAP側の設定。
  • パッケージの更新。
    perl、gcc、makeはipkgで更新をかけておく。最近 ipkg update するとエラーが出るようになってしまったのですが、めげずに手打ちでアップデートを掛けます。
    ちなみに、ipkgがwgetで失敗しているときは、/opt/etc/ipkg/tsx19-kmod.confの中の

    src tsx19 http://ipkg.nslu2-linux.org/feeds/optware/tsx19/cross/unstable

    の行をコメントアウトするとエラーが出なくなるかもしれません。
  • ツールを配置するディレクトリを適当に決めます。ディスク上(再起動で消えてしまわないところ)ならどこでも構いませんが、たとえば /share/MD0_DATA/route53 といったディレクトリを作って、そこに配置すれば良いと思います。
  • AWS secret。
    AWSからシークレットキーを取ってきて、/root配下、もしくは更新処理を行うツールのディレクトリに.aws-secretsという名前で配置します。

    シークレットキーは、「アカウント」の「セキュリティ証明書」からダウンロードできます。


    .aws-secretファイルの中身は以下のようにします。パーミッションを0600にすることを忘れずに。

    %awsSecretAccessKeys = (
       "my-aws-account" => {
          id => "アクセスキー",
          key => "シークレットキー",
       },
    );
  • dnscurl.pl(アップデートツール)のダウンロード。
    AWSからdnscurl.plというスクリプトをダウンロードしてきて、上のディレクトリに配置します。その際、#!/usr/bin/perlを#!/opt/bin/perlに書き換えておきます。
  • dnscurl.plを起動すると、いろんなperlモジュールが足りないと言われるので、CPANなりapt-getで更新を掛けます。Digest::HMAC_SHA1モジュールは必須です。その他、足りないものはどしどし追加していきます。
  • perlがOKになると、今度はcurlに「cacert.pemが古い」と言われて起動できません。http://curl.haxx.se/ca/cacert.pemあたりからcacert.pemをダウンロードして、これも同じディレクトリに配置しておきます。cacert.pemはコマンドラインとかでも指定できるはずなのですが、スクリプトを書き換えないとできなかったので、とりあえず環境変数にしておきます。

    % export CURL_CA_BUNDLE=cacert.pem
  • dnscurl.plの使い方は、http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DnscurlExample.htmlなどを参考にしてください。

    今回使ったのは、"Creating Resource Record Sets in Your Route 53 Hosted Zone"に出てくる方法で、レコードをxmlファイル(以下の例ではMyCreateRecordsRequest.xml)に書いておいてdnscurl.plの引数に引き渡す、というものです。

    % dnscurl.pl --keyname my-aws-account -- -H "Content-Type: text/xml; charset=UTF-8" -X POST --upload-file ./MyCreateRecordsRequest.xml https://route53.amazonaws.com/2012-12-12/hostedzone/HostedZoneID/rrset
  • dnscurl.plは指定した情報(Aレコードとか)をRoute53にアップロードしたりするような機能しかないので、Dynamic DNSとして使う際には自分のルーターについたIPアドレスを取得して、それをdnscurl.plに食わせる、というスクリプトが必要です。
    普通は、route53DynDNS.bashというのを使うようなのですが、これは内部でxpathを使っています。困ったことに、QNAPでは(見た範囲では)xpathがないようなので仕方なくpythonで自製しました。エラー処理もなんもなしの適当スクリプトですが。

    route53update.py
  • cronで、適当な間隔でアップデートを走らせます。
  • ドメインのネームサーバをアマゾンのものに変更します。ウェブの管理ページでNSレコード欄を見ると4つほどネームサーバが出てくるので、プライマリ、セカンダリ以下として設定します。これで完了です。

2013/12/23

QNAPでdnsmasq

dnsmasqのインストールですが、ipkgで
# ipkg install dnsmasq
Installing dnsmasq (2.62-1) to root...
Downloading http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable/dnsmasq_2.62-1_arm.ipk
Configuring dnsmasq

To complete the installation, you should check /opt/etc/dnsmasq.conf,
and then run /opt/etc/init.d/S56dnsmasq to start dnsmasq.
Successfully terminated.
あとは、/opt/etc/dnsmasq.confをいじって、/opt/etc/init.d/S56dnsmasqを実行してやれば起動されます。S56dnsmasqは、autorun.shから起動するようにしておきます。

設定ファイルも簡単で、ちゃちゃっと作れます。
今回はこんなふうに設定ファイルを作って、MAC/IPを対応付けるようにしてみました。
# 実行時のユーザ、グループを指定。
user=admin
group=administrators

# ドメインを指定。
domain=example.org,192.168.1.0/24
# DHCP設定。IPアドレス範囲とリース時間。とりあえず12時間(デフォルト)に。
dhcp-range=192.168.1.xx,192.168.1.yy,255.255.255.0,12h
# DHCPで引き渡す情報(今回は、デフォルトルートとDNSサーバ)
dhcp-option=option:router,192.168.1.zz
dhcp-option=option:dns-server,192.168.1.ww
# 以下、ホストの数だけ、MAC/ホスト名/割り当てるIPを並べる。
dhcp-host=XX:XX:XX:XX:XX:XX,hostname,192.168.1.mm,infinite
                        :
user、groupは、変えておかないとnobodyで実行しようとして警告が出ます。

これだといちいちMACアドレスを調べて、その数だけdhcp-host行を書かないといけないので、面倒といえば面倒です(色んなモノがはっきり固定されるのでわかりやすくて良いのですが)。
dnsmasqには、クライアントから申告される名前ベースで(MAC無関係に、あるいはIPアドレスもフローティングにして)管理することもできるようなので、そのほうが楽なのかもしれません。

2013/12/21

QNAPでDHCP

家庭内LANにはいくつかマシンがいて(Windows、Raspberry Pi、ノートPCなどなど)、いままではブロードバンドルータからDHCPで割り当てたアドレスをじかに叩いていたのですが、さすがにダサいし、たまにIPが変わってしまってあれっとなることもあったので、名前引きできるようにすることにしました。

ブロードバンドルータにはIPを割り当てるだけの簡単なDHCPしかなくてDNSもないので、QNAPにやってもらうことにします。

QNAPのDHCPは、ウェブ画面のネットワーク→TCP/IPタブから、編集ボタンを押すと設定できます。


ダイアログが表示されるので、適当に入力して「適用」ボタンを押すと動きます。



ただ、この状態の/etc/dhcpd.confは、
max-lease-time 86400;
default-lease-time 86400;
ddns-update-style ad-hoc;
allow booting;
allow bootp;
class "pxeclients" {
        match if substring(option vendor-class-identifier,0,9)="PXEClient";
        next-server 0.0.0.0;
        filename "pxelinux.0";
}
subnet 192.168.1.0 netmask 255.255.255.0 {
        range 192.168.1.xx 192.168.1.yy;
        option routers 192.168.1.1;
        option domain-name  "xxx";
        option netbios-name-servers 0.0.0.0;
        option domain-name-servers aa.bb.cc.dd;
}
host myclient {
        hardware ethernet XX:XX:XX:XX:XX:XX;
        deny booting;
}
となっています。

今回、fixed-addressを指定してMACでIPを固定したいのですが、ウェブ画面上にはインターフェースがないようなので、dhcpd.confを直に書き換えないといけません。

しかし、書き換えただけではだめです。何故かと言うと起動スクリプト/etc/init.d/dhcpd.shでrestart/startする際に、内部で/usr/sbin/create_dhcpd_confというバイナリが動いて、dhcpd.confをQNAPのオリジナルで上書きしてしまうというクソ仕様となっているからです。

いろいろ調べると、ダミーのパッケージ(QPKG)をこしらえて、そのOS起動時の実行スクリプト(autorun.sh)で置換をすればよい、という情報が出てくるのですが、これがまた動きません。厳密に言うとautorun.shは動くのですが、最後にdhcpdにHUPシグナルを送信したところでdhcpdが消滅して居なくなってしまいます。

しかたがないので、/etc/init.d/dhcpd.shを書き換えて対応。
@@ -13,6 +13,10 @@
        /bin/kill -HUP `/bin/pidof dhcpd`
        # Start daemons
        /usr/sbin/create_dhcpd_conf > /dev/null
+
+       echo "fixup dhcpd.conf... "
+       /share/administ/fixup-dhcpd-conf
        echo -n "Starting dhcpd: "
        if [ `/sbin/getcfg "DHCP Server" "Enable" -u -d "FALSE"` = FALSE ]
dhcpd.confをコピーするスクリプト。
#!/bin/sh
# copy dhcpd.conf
cp /etc/dhcpd.conf /etc/dhcpd.conf.qnaporg
cp /share/mydoc/dhcpd.conf /etc/dhcpd.conf
新しいdhcpd.confには、QNAPの生成するオリジナルのファイルに以下を追記してIPとMACを固定するようにしました(特定MACアドレスに指定IPが払い出されるようになります)。
host rasp {
        hardware ethernet xx:xx:xx:xx:xx:xx;
        fixed-address 192.168.xx.xx;
        option host-name "rasp";
}
さて、次はdnsmasqでDNSを立てようと思ったところで、dnsmaqにはDHCPが内蔵されていることが判明…。

dnsmasqに続く。


2013/12/11

BIOSのアップデートでVMWare+Linuxのハングが直った

自宅では、Windows7+VMWarePlayer+各種Linuxという環境で作業しています。

厳密には「していた」が正しいのです。マザーボード交換とマウスのBlueTooth化以来、何故だかわからないのですが、VMWare上でLinuxがブートしなくなっていました。

症状はちょっとおもしろくて、

  1. Linuxゲストが軒並み(CentOS/Ubuntu)ブートしない。正確には、USBの認識の後あたりでハングして、そのままになる。
  2. ホスト(Windows7)をリブートすると、一時的に直って起動できるようになる。
    しかし、ホストをスリープ・起床させると、それを契機としてゲスト上の一切のI/Oがハングし始める(ように見える)。ゲストを強制的にリブートすると、1の状態に落ち込む。
  3. たまたま事象発生前(スリープ前)から動かし続けていて、かつディスクを触らないようなものは動き続けることができる(topコマンドとかだけ動き続けていて、シュールな感じになります)、そうでないものは即座にふんづまる。
    どうも、プログラムテキストのロードもできなくなってしまうようで、dmesgコマンドですらハングしてしまいます。
  4. ホスト側はなんの支障もなく動き続けている。イベントビューワにも異常なイベントなし。
  5. クラッシュダンプは取れない(sysrq-triggerにcを入れた途端にハング。そりゃディスクが詰まってりゃそうなるわけですが)
という状態でした。

しようがないので、最近は作業用にLinuxホストがほしい時にはAWSでマイクロインスタンスを上げる、という「なんちゃってクラウドデスクトップ」でしのいでいたのですが、ふと、BIOSのアップデートが出ていることがわかったので当ててみたところ、綺麗さっぱり症状が消えました(ように見えます)。
当てたタイミングでBIOS設定が一度クリアされたので、そのためかもしれませんが。


ちなみに、マザーボードはGigaByteのGA-H77-DS3Hです。
GigaByteのサイトからダウンロードして、BIOSバージョンは、F7→F9に上げました。
変更内容は「1. Improve System Stability.」だそうです。これじゃOSSのチェンジログ以下だよ。

UEFIがらみでもなんかバグっていたし、風のうわさにきく「AMI BIOSはボロ^H^Hなかなか一筋縄ではいかない」というのは本当なのだなあ、やっぱりBIOSはPhoenixがいいなあと、微妙にAMIをdisってみるテスト。

2013/11/30

最近のLinuxカーネルではパーティションにTEST UNIT READYが発行できなくなっていた

久しぶりのLinux小ネタ。

タイトルのとおりなのですが、sg_tursコマンドとかでデバイス全体(/dev/sdaとか)ではなく、パーティション(/dev/sda1とか)を指定してTEST UNIT READYを発行しようとすると、最近のカーネルだとエラーになってしまうことに気づきました(CentOS5とかだとできたはず)。

まあ、TEST UNIT READYといったSCSIコマンドはもともとディスクに対して発行するものだし、それで良いのだと思いますが、ディスクの状態監視とかで、あれっと思う人はいるかもしれませんね。

2013/01/06

Raspberry Piで、コンソール(/dev/console)のブランクを停止する方法

Raspberry Piがハングした時に画面がblankしていると何も見えなくて解析もできずに悲しいので、パニックメッセージやバックトレースが見られるように、コンソールのblankを止める方法 (もちろん、Xは動かしていない場合の話です)

TERM=linux setterm -blank 0 > /dev/tty0

2012/11/04

ラズベリーパイ(RaspberryPi)その後

ラズベリーパイ(RaspberryPi)ですが、結局、何週間待っても来ないのでキャンセル。Paypal経由でちゃんと返金されましたが、なんだかなー。

2012/07/20

ラズベリーパイ(RaspberryPi)

最近流行りのラズベリーパイ(RaspberryPi)を購入してみました。

といっても、食べるパイではなくて、電子工作方面のガジェットです。
Linuxが動くという触れ込みの名刺サイズのARMベースのマイコン基板。


スペックをWebページから引用すると、こんなかんじです。

Broadcom BCM2835 (ARM1176JZFS processor(700MHz), FPU、 Videocore 4 GPU搭載)
GPUは Open GL ES 2.0対応、hardware-accelerated OpenVG、1080p30 H.264 high-profile デコード
GPU is capable of 1Gpixel/s, 1.5Gtexel/s or 24GFLOPs with texture filtering and DMA infrastructure
256MB RAM
SDカードからブート
10/100 BaseT イーサネットソケット

こんなので256MBもRAMが乗っているのだから驚きです。

ただ、大人気で、発表後すぐにRSオンラインに登録したのですが、先月末にやっと申し込みができるようになりました。しかも、いま登録して来るのは11weeks後です。

2011/11/19

syncookiesとListenバックログとパケットロスト

たまにはLinuxネタを。

Listenバックログは、伝統的なUNIXの実装だと、SYN_RCVDとESTABLISHEDの両方のソケット数を数えますが、LinuxのそれはESTABLISHEDな状態の数だけを数えるようになっています(manを見よ)。

これは何でかというと、いわゆるSYN Flooding攻撃への対応として、Linuxはsyncookieを実装したことの副作用なのだと思います。syncookieを実装していると、SYNに対してSYN_ACK(COOKIE)を返すコストがほぼゼロ(メモリコストとしては)になるので、来たSYNにすべてSYN+ACKを返すことが可能です。
したがって、SYN_RCVDの数は数えても意味がなくなったので、それはListenバックログの数としてカウントしないようにした、ということのようです(厳密に言うと、tcp_max_syn_backlog個までは SYN_RCVD で受けて普通のSYN+ACKを返し、それを超えた分についてはsyncookieを返すという挙動になりますが)。

syncookieの利点は、基本的に来たものは攻撃パケットだろうが正当な(legitimateな)パケットだろうがすべて食って返事が出来る、ということにあるのだと思われます。
すなわち、伝統的な実装の場合、攻撃パケットと正当なパケットは平等にキューから溢れますが、syncookieだと「とりあえず全員に応答してみて、handshake-completing-ACK (最後のACK)を返して来たものだけ処理をする」ということができるので、正当なコネクション要求を落としにくくなる、というメリットがあるということですね。

なお、syncookieはRFC4987で議論されていて、やり過ぎだとかTCPオプション使えないじゃないかとか、syncacheの方が良いとか毀誉褒貶?があるようですが、実装された以上は、まあ仕方がありません。



さて、前述のように「Listenバックログの数がESTABLISHEDの数だ」ということになっているので、ESTABLISHEDな受付待ちセッション数に上限を掛けなければならない都合上、Linuxはhandshake-completing-ACKを(能動的に)落とすことがあります。これは上の話からも明らかで、Listenバックログを超えてESTABLISHEDなセッションが生まれそうになったら、そのタイミングでACKを落とさざるを得ないからです。逆に伝統的な実装であれば、SYN+ACKを返した暁には、必ずhandshake-completing-ACKを受けることができます。

(余談ですが、LinuxはSYNも静かに、すなわちnetstatや/procに何らかの主張をすることなく落とすことがあって、ちょっと嫌ですね)

ここで問題になるのは、handshake-completing-ACKを落とすと、「クライアント側がESTABLISHEDなのに、サーバ側はSYN_RCVDのまま」といったことがあり得て、特に、クライアント側がread-sideになる場合は、(自分でkeep aliveなりselectなりでタイマーを掛けていない限り)無限に待ってしまうことがあり得ます。

さらに微妙なケースで、SYN+ACK再送とFIN再送のタイミングによっては、サーバ側も(read-sideの場合は、そして普通はサーバがread-sideになります)ESTABLISHEDのままになってしまうことがあり得ます。

一般論として、カーネルがパケットをいつ落とそうが知ったことではないわけですが、Linuxの場合、それが比較的、能動的な形で起きるので、そこはちょっとびっくりします。



何にせよ、
  • タイマは掛けよう。
  • tcp_abort_on_overflowやtcp_synack_retriesとかを使うのも良い考えかもしれない。
  • syncookieの有無にかかわらず、Listenバックログは適切に設定すべし。
といったことに注意が必要ですね、というお話でした。

とってんぱらりのぷう。

2010/06/16

Ubuntu 10.04LTSで、ウィンドウマネージャがe16からgnomeに切り替わらない。

Ubuntu 10.04LTSで、ウィンドウマネージャがe16のままGnomeに切り替わらない(ログイン画面でGnomeを選んでも、ログインするとe16になってしまう)という問題に当たりました。

どっかに状態が書いてあるんだろと思いつつも検索すると、このバグがヒット。


指示通り、~/.gconf/desktop/gnome/session/required_components/l%gconf.xmlをいじって、

<stringvalue>e16</stringvalue>
<stringvalue>metacity</stringvalue>に

書き換えたら直りました。

2010/06/09

Ubuntu 10.04LTS & VMWare 1.10

VMWare上のUbuntu環境を8.04LTSから10.04LTSへ移行。
いくつか(2~3)パッケージアップデートに失敗しつつも、無事アップデート自体は終了(失敗したものも、後で dpkg 等でフォローできました)。

一点だけ大きな問題がありました。それは

日本語フォントで句読点(。、)が、行の中央に表示されてしまう

というものです。

googleで出てくる情報としては、これがあるのですがハズレ。後は言語サポートをいじったりしても駄目だったのですが、最終的に、日本語Remixというのを入れたら何故か直りました。

あとはVMWareサーバ自体を1.08から1.10へアップデート。こちらは全く問題なしですが、そろそろ2.xやESXiに乗り換えないとまずそう。

2009/12/10

Zii EggのGPLソース

ZiiEggのフォーラムで、いろんな人が「早く出せ~、出せ~。ストールマンにチクるぞ~」と催促していた、GPL部分のソースコードがリリースされてます。

2009/02/24

VMWare ゲスト上のLinux(ubuntu)デバッグ

ここしばらく、VMWareゲスト上の ubuntu(Ubuntu 8.04.2)がストールしてしまうという現象に頻繁に遭遇しています。

ゲストの再起動とかも出来なくなって、Windowsのタスクマネージャから見るとvmware-vmx.exeがCPU100%になっていることが判るので、雰囲気的にはVMWareのバグのようです。

しかし、ひょっとしてゲストOSの問題かも、ということで念のため解析しておくことにしました。この手のストールの場合、まずはsysrqで情報を取る(取れるかどうか確認する)のですが、シリアルコンソール+Named Pipe Proxy経由という構成だと、どうもBreak信号がうまく飛んでくれないようです。Magic Sysrqは、シリアルコンソールからだと「Break信号+コマンド文字」になります。

仕方なく、じゃあNMIで止めてみるかと思ったのですが、VMWareからはNMIを入れることも出来ないようです。こちらも諦めて駄目モトでnmi-watchdogを有効にしてみたところ、NMIそのものはきちんと入っているようです。ついでに、kdumpも入れて様子を見ることにしました。

# cat /boot/grub/menu.list
:
kernel /boot/vmlinuz-2.6.24-22-generic root=.... ro nmi_watchdog=1 crashkernel=64M@16M
:

# cat /proc/interrupts
:
16: 45 0 IO-APIC-fasteoi uhci_hcd:usb1, Ensoniq AudioPCI
17: 45 1 IO-APIC-fasteoi ioc0
18: 110 514 IO-APIC-fasteoi eth0
NMI: 235702 235650 Non-maskable interrupts
LOC: 0 235513 Local timer interrupts
RES: 2804 3013 Rescheduling interrupts
さて無事に釣れるでしょうか...。

ちなみに、kdumpは2ndカーネルが上がりませんでした。ATAの認識が出来ずにエラーになってしまいます。まあ、そこまでくれば何か起きたんだということは判るので、とりあえずそのままにしています。

2009/02/20

アプリケーションのバックトレース (execinfo)

ちょっと必要があって、実行中のアプリケーションプログラムから、特定の走行箇所でのバックトレースを取る方法が必要になって調べましたので、備忘録。

カーネル内であれば、show_stack()を呼び出すことで走行時のスタックトレースを簡単に得ることが出来ますが、アプリケーションプログラムでもexecinfoを使うと同様のことが出来ます。

具体的には、
  1. backtrace()関数でスタック情報を取得します。
    スタック情報はvoidのポインタへの配列として用意します。この配列の大きさが、取得できるスタックの深さ(ネスト)の最大値を規定することになります。backtrace()関数の戻り値が実際に取得したスタックの深さになります。
    void *trace[100];
    nr = backtrace(trace, 100);
  2. backtrace_symbol()関数で、取得したスタック情報をシンボル化します。
    char **ents;
    ents = backtrace_symbols(trace, nr);
  3. 取得したスタック情報を表示
      for(i=0; i<nr; i++) {
    printf("#%d : [%s]\n", i, ents[i]);
    }
  4. 後始末(シンボル配列の開放)
    backtrace_symbols()関数はchar *の配列を返却しますが、この配列はbacktrace_symbols()関数が内部的にmalloc(3)で確保したものなので、最後にfreeしてあげる必要があります。
以下にサンプルコードと実行例を乗せておきます。


#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>

#define MAXFRAME 64
void show_stack(void)
{
int i, nr;
void *trace[MAXFRAME];
char **ents;

nr = backtrace(trace, MAXFRAME);

if (nr>=MAXFRAME) {
printf("Stack too deep, some entries are stripped off\n");
}

ents = backtrace_symbols(trace, nr);
if (ents == NULL) {
perror("backtrace_symbols");
exit(1);
}

for(i=0; i<nr; i++) {
printf("#%d : [%s]\n", i, ents[i]);
}

free(ents);
}

void b(void)
{
show_stack();
}

void a(void)
{
b();
}

main()
{
a();
}

実行例です。正しくスタック情報が取れていることが判ります。
# cc execinfo.c -o execinfo
# ./execinfo
#0 : [./execinfo(show_stack+0x1f) [0x8048743]]
#1 : [./execinfo(b+0xb) [0x80487dd]]
#2 : [./execinfo(a+0xb) [0x80487ea]]
#3 : [./execinfo(main+0x16) [0x8048802]]
#4 : [/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7e6b450]]
#5 : [./execinfo [0x80486c1]]

なお、エクスポートしていないシンボルは当然ながら表示されないので、確実に表示したい場合には ld に -rdynamic オプションを付与しなければなりません。

2008/11/30

Ubuntu on VMWareのCentOS5への移行

仕事で使わざるを得ないこともあるしということで、Linux環境をUbuntuからCent5に移行しようとしたら/homeがXFSだったことに気づいて愕然。

しょうがないので仮想化環境上にCent5をクリアインストールして、ディスクコンテンツごと引っ越すことにしましたが、こういうときに仮想化はやはり便利ですね。

2008/06/14

Ubuntuのアップグレード(Edgy to Feisty to Gusty)

  • ここ一月ほど、Ubuntuマシンの apt-get update が「そんなアップデート先はしらん」状態になっていたので、おかしいなあと思っていたら、使っているバージョン(Edgy)がとっくの昔にサポート終了になっていたことに気づきました。
# っていうか、配布ディレクトリぐらいは残しておいてくれんかのう。

仕方なく、バージョンアップ(6.10->7.04)を行ったので備忘録まで。
  • アップグレード自体はupdate-managerというGUIコマンドでボタン一発で出来る。

  • しかし、今回のケースでは「edgy自身アップデートができないので、update-managerが異常終了(念のためedgy自身を最新にしようとしてアボート)。現行の環境をまず現行バージョン内での最新にアップデートしてからすべてを始める、という処理はスキップできそうにない(アップグレードの設計上、当然といえば当然だが)。

    仕方なく、手動アップグレードの道へ(/etc/apt/sources.listのedgyをsedでfeistyに置換して、apt-get update/dist-upgrade)

  • ちょこちょこエラーは出るものの、システムの総更新と思えばびっくりするほどスムース。設定ファイルなどもちゃんと「どうする?」と聞いてくれるので安心です。

  • アップデート後、再起動するが特に問題なし。
    いくつかのデーモン・サービスについては、設定ファイルの構文等に変更があってインストール後に微調整が必要でした(apache、ntp/ntpdate、dovecot、postfixなど)。

    作業量としては誤差の範囲ですが、dovecotは設定ファイルが似て異なるように変わっていて少しだけトライアルアンドエラーが必要でした(my_location = /var/spool/mail/%uとか。mbox:とかINBOX=とかがついているとうまくpop3では拾えないようでした)。
その後、ほぼ同じ手順でFeistyからGustyへアップデートしました。