川の流れのように‥(Eiji Ota's Weblog)
- All
- application
- kernel
- life
- opensolaris
プロジェクト パルサー (Project Pulsar -- embedded solaris on PowerPC)
|
Project Pulsar -- Embedded Solaris on PowerPC
先日、Sun LabのOpen Houseがあって、SolarisをPowerPCアーキに移植する プロジェクト・パルサーをやっているTom Riddleさんのプレゼを聞く機会が ありました。
PowerPCへの移植に前々から興味があったので、早速隣のビルへと(^^:)でかけ、幾つか勝手な質問をぶつけてみました。
(注) Tom Riddleと聞いて最初に思ったのは、Harry Potterに出てくる若き日のLord Voldmortのことでした(^-^)
ちなみにTom Riddleさんは、06/01付けのメールで、OpenSolarisのPowerPC communityに、 PowerPCアーキでブート したことを連絡しています。
Q1. Solarisのソースツリーをconfiguration systemライクにしないの?
まず質問したのは、configuration systemのことでした。
Solarisの場合、SPARCの仕様やx86サポートなどからも異なったCPUアーキを サポートできるようにソースツリーが構成されています。 とはいうものの、幾千というシステムをサポートする組み込みシステムでは、 eCosのような洗練された configuration systemを導入した方がやりやすいのではないかと思って 質問してみました。
この道(?)の先駆者であるeCosと (embedded)Linuxを 例にあげ、Solarisのソースツリー構成をより組み込み向けに見直して、PowerPCを サポートする可能性はないのかと聞いてみたのですが、現状のPowerPCサポートは、 Solaris 2.6で行ったものをOpenSolarisに組み込む形で行われていて、そこまでは 考えていないという答えでした。
実は、SunはSolaris2.5.1でPowerPC (PRePプラットフォーム向け)をサポート しており、まだ Solaris 2.5.1 PowerPC Edition Installing Solaris Software といったドキュメントでその痕跡をみることができます。
Q2. 他のRTOSのインタフェースはサポートしないの?
続いて、他の組み込みRTOSへの対応、例えば uITRONインタフェース のサポートの可能性、を聞いてみたのですが、感じあまり興味なさそうでした。(^^;)
つまりは、RTOSの領域までは当面踏み込むつもりはなく、あくまで(Embedded)Solaris = SRV4 + (soft)RT拡張のままであるということ、かも知れません。
Q3. サブシステムをモジュール化してMicro Kernelにはしないの?
L4 Micro Kernelを使った取り組み -- 例えば、 L4 + Linuxや、L4 + uITRONなどが巷では実装されていること -- をあげ、 組み込み向けにSolarisをMicro Kernelアーキに対応させるつもりはないだろうか、 また、uCLinuxのようにMMUがないCPUへの 対応や組み込みには重い(だろう)SVR4のVMを考えると、カーネルサブシステムを モジュール化して(今以上に自由度を上げて)選択する仕組みが必要ではないかと質問してみました。
※ 例えば、「Open SourceなCPU」にあるSPARC V8 coreのLeonは、SPARC CPUですが、 MMUがありません。(SPARCの仕様上、MMUは自由に実装できる)
やはりというか、当然というか、そこまでaggressiveな取り組みは一切(^^:)考えて いないようでした。こういうデフォルメ的な取り組みは、オープンソースな 活動でやることなのかも知れません。
Q4. Device Driverの対応は?
最後に組み込みプラットフォームのDevice Driverの対応はどうするつもりなのかを 聞いてみたのですが、今の作業はSun LabにあるPegasosベースのマシンで行っていて、 それ以外のドライバはCommunityに任せたいという意向のようでした。
Pegasosベースのマシンといっていたのは、たぶんメールにある ODW (Open Desktop Workstation)のことではないかと思います。 (PowerPC G4 1GHzを使用したマシンということのようです)
|
ちなみにTom Riddleさんのメールにある URL に行くと、PowerPC上でブート可能なunixがダウンロードできます。(^^)
|
Technorati Tag:
OpenSolaris
Posted at 06:04午前 6 22, 2006 by eota in opensolaris | Comments[4]
Open SourceなCPU
先日、UltraSPARC-T1 (Niagara Chip)のスペックが公開されましたが、チップそのものがついに
OpenSPARC-T1と
してリリースされました。
OpenSPARC-T1 CPUをダウンロード...というと、何となく戸惑うのですが、^_^:
Verilog RTLを含むChipデザインをダウンロードできるようです。
GNU GPL(Ver2)でライセンスされるということですから、いわゆるオープンソース
そのものです。自分で製造して...という類ではないので、自作PCに使ってという
わけにはいかないと思いますけれど、CPUアーキのリサーチなどのアカデミックな分野やオープンソース・ハードウェア、たとえばopencores.orgや、オープンソースなSPARC V8 core Leonを使ったLEOX projectのような活動にいい意味での刺激を与えてくれそうで、今後の発展に期待したいです。^-^
Posted at 02:42午前 3 22, 2006 by eota in opensolaris |
プロジェクト黒点 (Project Sun SPOT)

先週、SunラボからProject Sun SPOTが発表されました。
SPOT = Small Programmable Object Technologyということらしいのですが、
太陽にちなんだ命名は生きていて、ちょっと微笑みます。^-^(Sun Spot = 黒点)
で、このSun SPOTって何?というと、どうやらARM9を使った組み込みボードキット
ということのようで、Java2 Micro Edition (Java ME)で作ったアプリをそのボードで
動作させられる組み込み環境のようです。
といっても、(Javaアプリを動作させるのは)携帯ですでにやっていることなので、
そう?という感じだったのですが、Sun SPOTの目標として、
○ Wirelessを前提。ネットワーク環境で動作する組み込みアプリ。
たとえば、ネットを通じてRe-programmingが行えるような仕組みや、ネットを通したmigration (あるSun
SPOTから、別のSun SPOTへのアプリのMigrate)
○ 使い慣れたIDE/言語での組み込みアプリの作成
○ セキュリティ。たとえば、public-key cryptographyの組み込み装置への適用等。
というのがあったようで、必然とJavaに落ち着いた...ということになっています。^-^;
目標を改めてみてみると、確かに野心的で携帯の枠を越えているのは確かのようです。
そして携帯よりも小さい組み込みデバイスを想定しているようなんですが、実際のところはやっぱり携帯でのJavaの成功が背景にあり、そのコンセプトを更に押し進めた...のかも知れませんね。^-^
動作しているJava VMにはOSの機能を持たせていてVirtual Machineを直接Bare Metalで
動作させているということで(↓)、
Powered by a small Java 2 Platform, Micro Edition (Java ME) virtual
machine
written almost entirely in Java, Project Sun SPOT provides a way to
easily,
affordably and quickly build Java-based sensor applications that run
directly
on the central processing unit (CPU) without any underlying operating
system.
このJava VMの実装に興味が引かれたのですが、どうもSquawkと呼ばれる組み込み用のVMをベースにしているようです。このSquawkには、次のような特徴があります。
○ 直接hard上で動作 (RTOSなどを必要としない)
○ Device DriverがJavaで書かれている
○ memory footprintが少ない -- Java VMで80k, ライブラリで270k。
○ 複数アプリを動作させることができる。(application isolation mechanismを使用)
また、Sun SPOTではCLDC1.0以外にセンサーやアクチュエーターをJavaアプリから操作できるようにライブラリが用意されています。
開発環境はNetbeans 5.0を使用し、USBを使ってアプリを転送するようです。
ハードはARM9で、無線、温度センサー、光センサー、3Dアクセラメーター, 8つある汎用
I/Oポートに、4MBのFlash Memory (512KのRAM)とかなりの装備になっており、
評価ボード兼学習キットの色合いを見せています。
まぁ、これなら$499も仕方ないかなぁとは思うのですが、組み込み装置として$499はちょっと高い気もしないわけではありません。^.^

組み込みはやっぱりハードの自由度が高くないと、実用上は意味がないと思うので、是非Java
VM(Squawk)をオープンソースにしてもらって、他のCPU、X86やSH, MIPS, PPCへの移植を進めてほしいものです。
またJava VM上で動作するthreadの応答速度も気になるところで、その当たりのスペックも出してほしいのですが、SquawkがReal
time Java
VMであるとは聞いていないので、リアルタイム性はないのかも知れません。そうであれば、ますますオープンソースにしてもらって、リアルタイム性の追加も
進めたいところですね。 今後に期待しています。
Posted at 06:18午前 3 13, 2006 by eota in opensolaris | Comments[10]
CoolThreads -- OpenSPARC T1登場 (CoolThreads -- OpenSPARC T1 rises)
Niagaraと呼ばれていたUltraSPARC-T1の仕様が
OpenSPARC-T1
として公開されました。
公開されたドキュメントは次の3つです。(最初の2つはprivileged editionと
hyperprivileged editionの2つが用意されています。hyperprivileged editionの方は、
Hypervisor(Virtual Machine)の仕様についても記述しているようです)
○ UltraSPARC Architecture 2005 Specification
いわゆるSPARC V9の仕様であるISA(Instruction Set Architecture)などの他、
今後のSunのSPARC CPUのベースになるSunのV9拡張の仕様(UltraSPARC Architecture
2005) -- MMU, Trap, Interrupt, CMT, Error Handlingの仕様等 -- が記述され
ています。
○ UltraSPARC T1 supplement to UltraSPARC Architecture 2005 Specification
UltraSPARC T1の、UltraSPARC Architecture 2005仕様の実装について
記述されています。
○ UltraSPARC T1 Hypervisor API Specification
sun4vと呼ばれているSolarisのUltraSPARC T1対応部分の実装とそのHypervisor APIに
ついて記述されています。
かつてない充実したドキュメントで、カーネル開発者には有り難いことです。
|
UltraSPARC-T1以降のSunのUltraSPARC上にLinuxやNetBSDなどのOSを移植したり、
新規のOSを開発するエンジニアにとって、これらのドキュメントと実際に実装を
行ったOpenSolarisのソースは、かけがえのない資料になると思います。
こういった貴重な資料を公開してくれるなんて、一昔前では考えられなかったこと ですが、本当にいい時代になりましたね。^-^ |
|
Technorati Tag: OpenSolaris
Technorati Tag: OpenSPARC
Posted at 04:41午前 2 18, 2006 by eota in opensolaris |
GNU Solaris Nexentaをインストールする (Install GNU Solaris Nexenta)
| 先日、GNU/Solaris Nexentaをお試しにインストールしてみました。
GNUのソフトがapt-getでSolarisで使える? 何!というノリで、早速インストール することにしてしまいました。(^-^;) そこで、今日はNexentaのインストールについて紹介したいと思います。 |
|
インストールは、比較的「簡単」という"感じ"ですが、手入力で情報をインプットする ためどこか間違えていないか、ちょっと不安であったのも確かです。特に、ディスクの パーティションは要注意かも知れません。僕の場合は、まんまとはまり、結局2度ほど パーティションを行うことになりました。(^.^:)
1) Install CDを用意する
Nexentaのホームページ からダウンロードします。ページの一番下にダウンロードの方法について書かれて いますが、ダウンロードする前に登録が必要になっているようです。また、LiveCDも ダウンロードできるようですが、巷のCD-Rでは納まらないサイズ(実際、書き込みが できませんでした)のようで、 VMware や QEMU で動作させることを想定しているようです。
2) ディスクをパーティッションしておく
Nexentaのインストールそのものは、それほど難しくないと思います。CDを4枚も 使う、通常の(?)OpenSolarisのインストールを考えると、CDを1枚だけ、しかも20-30分 で終わってしまうインストールは、逆に嬉しい?のですけれど、僕の場合 パーティッショニングではまって、結局やり直しとなってしまいました。
問題は、Nexentaのインストーラから起動されるfdisk(実際はSolarisのformatコマンド から起動されるfdisk)が拡張パーティッションを認識できないため、Nexentaを 拡張パーティッションの方にインストールするつもりでいると、結局インストール できなくなってしまうというものです。Solarisのfdiskをちゃんと意識していれば 事前に用意したと思うのですが、すっかり忘れていました。
僕の場合は、Windows XP/Gentoo Linux/Nexenta(+純正OpenSolaris)の3つ(4つ?)をインストールするつもりで あったので、Nexentaを拡張パーティッションの方にいれようとしてしまい、 インストール作業中にインストールできないことに気づき、結局やり直しました。
さて、パーティッションはLinuxのfdiskを使って、あらかじめNexenta用に 切っておきます。
僕の場合は、こんな感じでした。(Solarisが基本パーティション、Linuxが拡張 パーティション)
/dev/hda1 Diag
/dev/hda2 WinXP
/dev/hda3 Solaris用 << パーティッションIDを0xbfに設定。
/dev/hda4 Extended
/dev/hda5 Linux
/dev/hda6 Linux Swap
/dev/hda7 Linux (boot)
※ Solarisのパーティッションは、Linux fdiskのtコマンドを使い、 直接0xbfを設定 しておきます。
3) Install CDでブートし、インストールする
ブートするとログインプロンプトが出力されるので、rootでログインします。 パスワードはありません。 インストール手順は、基本的にNexentaのホームページに書かれているとおり (Getting Started) です。ただ、α1とα2を試したのですが、α1の場合、インストールスクリプトの名前 がドキュメントと違っているので、ちょっと戸惑うかもしれません。 (α1の場合、記述では、インストールスクリプトは、 /usr/gnusolaris/nexenta-install.shとなっていましたが、実際は /usr/gnusolaris/install-stage0.shでした。)
Solaris用のパーティッションが予め切られていれば、インストーラはそれをシステム ボリュームにしようしますので、インストーラに認識させればよいです。でも、表示の 際には、システムボリュームはSolarisの論理パス名(/dev/dsk/cXdYsZの類)で表示され ます。(たとえば、僕の場合、/dev/hda4で切ったパーティッションは、 /dev/dsk/c0d0s0として表示されました。)
Nexentaだけをインストールするのであれば、パーティッショニングは "Auto"でよいと思いますが、OpenSolarisもインストールしようと思うのであれば、 Fresh Installationで"Manual"を選ばないといけません。そうすると、OpenSolarisの Formatコマンドを呼び出し、自分で設定するようになります。
(注意) formatコマンドが起動されるときに、ディスクのジオメトリ情報(シリンダ数や ヘッダ数)が設定されてなく、自分で設定しないといけない場合がありますので、 予めディスクのジオミトリー情報を調べておいた方がいいかも知れません。
僕の場合は、Linuxをブートした時にディスクの型番をメモしておき、ディーラの サイトからジオメトリ情報を調べました。 今は昔と違ってジオメトリ情報が実際のディスクのHW実装を表すものでも何でも ありませんが、ソフトでは伝統的にこれらの情報を使用しているので、何らかの 値を入れる必要があります。できればメーカーの公表している数字がよいと思います。 そのときには、次の値を用意しておくとよいと思います。
○ Cylinder数
○ Header数
○ Sector数
○ RPM
これら以外を聞かれても、デフォルトでなんとかなります。^-^
Linuxのインストールなどに慣れていれば、あまり違和感はないと思いますが、 これが初めてという方は"Auto"を選ぶのが無難かも知れませんし、ちょっと今は Nexentaは止めておいて、OpenSolarisの方をインストールしておくという手も ありそうです。(それに、Nexentaはちょっとした幾つかの問題があります。下の4を 見て下さい。)
fdisk (format)でパーティションを切った後に、Installerはどれをrootにするか、 swapにするか等々を聞いてきますので、ここではパーティションを切るだけです。 OpenSolarisの場合は、パーティションを切る時に設定しますが、それとちょっと 違います。
Installerがroot, swapなどをどれにするか決めるのに、論理番号を知っておく 必要があるので、パーティションを切ったときに、どれをroot, swapにするか、 /dev/dsk/c0d0sXのXの数字を一応頭の中にいれておくとよいと思います。
後は流れ作業ですが、最後にgrubを書き込むか聞いてきます。既にLinuxや OpenSolarisでgrubを書き込んでいる場合や、Windows XP boot loaderでブート する場合は、止めておいた方が無難です。
また、α1の時は、rootが(hd0,0,a)に固定で設定され、たとえば/dev/hda4を システムボリュームにした場合は、rootは(hd0,3,a)でなければいけないため、 これにより結局ブートできないということがありました。(そういう場合は、grubの 画面でrootの値を変更し、ブートしてから/boot/grub/menu.lstを編集します)
4) Nexentaの問題点
Nexentaは、Linuxで実績があるGNU Debianの環境を使っているだけあって、 Xサーバの設定など、OpenSolarisよりも優れているところがありますし、 gnomeの環境も、普段、Debian Linuxを使っている人には、馴染みのあり、 かつ綺麗なもので、好感が持てました。 ただ、次の2つの問題にインストール後、直ちにぶつかりました。
○ SVR4パッケージがインストールできない
これはかなり困った問題です。今回の場合、使ったノートのNetworkドライバが BroadcomでOpenSolarisに添付されていないものだったため、ドライバがインストール できず困りました。結局、opensolaris.orgから配布されている packaging tool 使い、なんとかドライバはインストールできました。
opensolaris.orgから、 pkgutils.i386.tar.bz2 をダウンロードしてコマンドを展開するのですが、このままではpkgaddが動かず、 結局次の2つのライブラリをOpenSolarisからコピーして動作させました。
・ /usr/lib/libwanboot.{so, so.1}
・ /usr/lib/libzonecfg.{so, so.1}
ただ、元々のパッケージがないので、必要なパッケージが存在しないというワーニング が表示されます。それを無視してインストールするわけですが(というか、それしか ない(+_+:))、依存関係がある場合は動作しません。
できればスーパーセットにしてDebian packageも、OpenSolarisのSVR4 packageも 使用できるようにして欲しいものです。
○ 日本語環境がない
実は、apt-getで簡単に手に入るのだとばっかり思っていたのですが、GNU Debianの 全部のパッケージ・環境を用意しているわけではないようです。 また、Solaris10の languageCDのパッケージを上でインストールしたpkgaddでインストールしようとしても、 必要なパッケージがないためダメでした。結局のところ、日本語環境は自力でソース からコンパイルして作り上げる以外の方法はないようです。国際化、 ローカライゼイションなどまだ用意されていないDebian packageの提供が待ち望まれ るところです。
5) 感想
総じてよいできです。インストールにやや難がありますが、Linuxの出たての頃を考える と、仕方がないように思います。でも、インストール周りは、Linuxなどの ディストリビュートではよいものもたくさんあるので、短時間で相当改善されるのでは ないでしょうか? やはり頭が痛いのは、日本語環境。Debianベースのpackageを早く 充実させて欲しいです。それと、SVR4の環境は、やっぱり継承して欲しいなぁと思い ます。SVR4のパッケージを自由にインストールできるようにして貰えると、ソフト資産 を継承できるという意味でかなりよいと思うのです。 これらの問題が解決されれば すぐにでも使いたくなる気にさせるNexentaです。
Posted at 02:30午前 2 09, 2006 by eota in opensolaris |
最近の話題から(OpenSPARC)
今のいままで自分達の会社がOpenSource向けのサイトを開いていたことにも気づかずにいました。(^-^:) プロジェクトに浸りきりで、たとえば12月は、2Qの区切りということもあってマイルストーンの〆切に追われ、OpenSolarisをゆっくりチェックする余裕もなく、そのまま知らぬ存ぜぬのままきてしまったようです。
で、そのサイトなんですが、SunSource.netという、なんかまんまのサイトです。^O^
早速サイトに飛ぶと、右側にOpen Source Projectの幾つかが書かれていて、BrazilやGlassFish, Grid Engineやらの中に混じって、OpenSolaris見つかりました。^-^
でも、OpenSolarisの説明が"Unix Operating System"っていうのは、愛嬌なのでしょうね? なんか、も少し説明があっていいような気がしないわけでも....ありません。
その中でちょっと面白いのは、その下にあるOpenSPARCかも知れません。
UltraSPARC-T1
OpenSPARCでは、Open Source Hardwareとして、Niagaraというコードネームで呼ばれたUltraSPARC-T1のVerilogのソースや仕様などを公開する予定のようです。そしてUltraSPARC Architecture 2005(UltraSPARC-T1のISA(instruction set architecture))の仕様や、OSの移植情報(Linux/FreeBSDなどのSolaris以外のOSの移植向け)も提供するということですので、個人的にもちょっと楽しみにしています。
もう1つ眼にとまったのが、OpenSolarisをPowerPC上に移植したというニュース。
OpenSolarisのPowerPCへの移植は、Blastwareのサイトでやっているようなんですけれど、OpenSolarisのPowerPCコミュニティのディスカッションを覗くと、未だ実際にはブートまで行っておらず、OpenSolarisのソースをPowerPC向けに(MSBで)コンパイルした段階のようですね。今後はgrub2の対応などを行ってブートまで持っていくということですから、こっちも、ちょっと期待したいと思っています。
Technorati Tag: OpenSolaris
Technorati Tag: OpenSPARC
Posted at 04:37午前 1 19, 2006 by eota in opensolaris |
OpenSolaris事始め(その2:カーネルビルド)
OpenSolaris事始め(その2:カーネルビルド)
前回、OpenSolarisを僕のToshibaのノートにインストールしてLinuxを吹っ飛ばしてしまっったお話をしましたが、それを会社の人に話をしたら色々と反応が返ってきました。
たとえば、「Windowsの代わりにOpenSolarisをインストールしようとしたんだって? それはWindowsのたたりに決まってるだろう? Windowsっていうのはそれができるんだ。」
(どうやってできるの...って結局聞けませんでしたけれど(^^;))
また、「それはよい経験だったね。バグだったら、こいつは貴重な体験だろう?、まずは再現させてみることだ。是非もう一度トライするべきだ、そう思うだろう?」
(だから、それは僕のパーソナルユースなので...と思いましたが、言っても無駄そうでした(^.^))
人それぞれですねぇ。。。僕のLinuxなんて、そう、誰も気にしていませんでした。(^-^;)
今はディストリビューションが様々あるLinuxくんですけど、以前はYggdrasilぐらいしかなかったんですよねぇ。もちろんRed Hatの前のディストリビューションですけれど、秋葉原のガード下に輸入もののYggdrasilを売っていて、それを買いにいったものでした。(追記(09/06): そういえば、slackwareもあった気もします。でも、Yggdrasilの方が好きでした...^-^)
その当時のLinuxは、アプリケーションをインストールするには、ソースからコンパイルするのが当たり前のような感覚でしたけれど、OpenSolarisくんをいじっていると、そんな頃のLinuxくんを思い出すようで、不思議と懐かしい気分が....ということで、ついつい、今までLinuxくんでやっていたのをOpenSolarisくんで....と思うようになりました。(^v^)
それでもって今日は前回の続きで、OpenSolarisのソースビルドの話です。kernelの実装の方もちょっとやりたいんですけど、乗りかかった船、ある程度までいってしまいましょう。(^.^;)
ここでは、ReleaseNotesにあるやり方ではなくて、カーネルとドライバのビルドに絞ったやり方を紹介します。
えーと、前回は確かソースとコンパイラ一式をダウンロードしたところでしたよね。
- 1.SUNWonbld-yyyymmdd.i386.tar.bz2
- 2.opensolaris-bfu-yyyymmdd.i386.tar.bz2
- 3.opensolaris-closed-bins-yyyymmdd.i386.tar.bz2
- 4.opensolaris-src-yyyymmdd.tar.bz2
(yyyy=年, mm=月, dd=日)
- 1. アーカイブを展開する
これらを適当なディレクトリの下に展開してもらうのが第一歩です。一応ここでは、
/opensolarisの下に展開する...ということにしましょう。
bz2でtarが圧縮されているファイルは、次のようにbzip2とtarをパイプでつないでも いいですし、
- # bzip2 -dc xxxxx.bz2 | tar xvf -
gtarが入っていれば、直接実行してもかまいません。gtarはSUNWgtarをインストール すればおとされます。フルでインストールしていれば、gtarはあるはずです。
- # gtar -xvfj xxxxx.bz2
SUNWonbld-yyyymmdd.i386.tar.bz2の方は、SVR4パッケージ形式なので、改めて pkgaddする必要があります。
- # pkgadd -d onbld SUNWonbld
pkgaddしたら、onbldはもう要らないので消してしまいましょう。
- # \rm -rf onbld
- 2. パスを設定する
展開が終わったら、/opt/onbld/binと/opt/SUNWspro/binをPATH環境変数に加えます。
/opt/SUNWspro/binはコンパイラをインストールするとできるディレクトリです。
(コンパイラは、http://opensolaris.org/os/community/tools/sun_studio_tools/からダウンロードします)
{t}cshであれば、.cshrcに
- set path = (/opt/onbld/bin /opt/SUNWspro/bin ... (残り))
{ba}shであれば、.profileに
- PATH=/opt/onbld/bin:/opt/SUNWspro/bin:(残り); export PATH
などとやるわけですね。(皆さんご承知だとは思うのでくどかったですね(^-^;))
※/usr/ucbはPATHから削るか一番最後に指定するようにという注意があります。
- 3. opensolaris.shを準備する
opensolaris.shを今展開してできたusr/src/tools/envからもってきます。
- # cp usr/src/tools/env/opensolaris.sh .
必須なのは、GATE,CODEMGR_WSです。STAFFERやVERSIONは必要に応じて設定します。(STAFFERは、ビルドが終わったら(またはアボートしたら)メールするo送付先で、VERSIONは作ったカーネルでブートしたときにuname -vすると出てくる名前です)
上の例の場合は、こんな感じになるかな。
- GATE=opensolaris; export GATE
- CODEMGR_WS="/$GATE"; export CODEMGR_WS
- STAFFER=<自分のアカウント>; export STAFFER
さて、ここまでは、ReleaseNotesに載っているのですが、以降はちょっと異なります。(^0^)
- 4. ソースのタグを用意する
ソースを読むのに必要なのは、まずはタグファイルでしょうか?
cscopeとctagsはやっぱり何はともあれ作ってしまいたいもの。
ところが、何もせずにタグファイルを作ろうとすると次のように怒られてしまいます。何が足りないのでしょうか?
- # bldenv -d opensolaris.sh
- # cd /opensolaris/usr/src/uts
- # make cscope.out
/opensolaris/usr/src/tools/proto/opt/onbld/bin/xref -x cscope.out
sh: /opensolaris/usr/src/tools/proto/opt/onbld/bin/xref: not found
*** Error code 1
make: Fatal error: Command failed for target `cscope.out'
Current working directory /opensolaris/usr/src/uts
どうやら、xrefというツールがないらしいですね。まずこれを"作る"必要があります。 それには、
- # cd /opensolaris/usr/src/tools
- # make
としてやるだけです。これが終われば、必要なツールができていますので、改めて
- # cd /opensolaris/usr/src/uts
- # make cscope.out
としてやりましょう。
ctagsは、同じディレクトリで、
- # make tags
としてやるだけです。簡単ですね。
※ makeの代わりにdmakeとすると4つ(デフォルト)のmakeを起動します。
- 5. カーネルとドライバのビルド
さていよいよ待ちにまった?カーネルとドライバのビルドです。^-^
全ソースをビルドするには、次のようにnightlyコマンドを起動してやればいいのですが、何せコマンド、ライブラリーまでビルドするので時間がかかります。
(追記 (09/09))
nightlyの使用例が抜けていました。(^^)
# nightly ./opensolaris.sh & (nightlyの起動)
# tail -f log/nightly.log (logの表示)
Defaultのnightlyは、clobber (make clobber)ビルドですが、-iオプションを使うことで回避が可能です。
# nightly -i ./opensolaris.sh & (-iオプション付き)
また、上のログファイルはnightly終了後にlog/log.(mm=月, dd=日)に移されます。実行中は上のように
logの下に直接置かれます。
(追記終わり)
そこまでやる必要はないので、ここでは時間を節約したカーネルとドライバのみのビルドについて説明したいと思います。
その前に、AMD64向けでなければ、32bitカーネルとドライバだけ必要ですから、64bitのビルドははしょることにしましょう。デフォルトでは、64bitと32bitの双方をビルドしていしまいます。
そのために、Makefileを2ついじることにします。
- # cd usr/src
- # vi Makefile.master
i386_BUILD64=
↓ (次のように変更)
i386_BUILD64= $(POUND_SIGN)
- # cd usr/src/uts
- # vi Makefile.uts
$(NOT_RELEASE_BUILD)DEF_BUILDS64 = debug64
↓ (次のように変更)
$(NOT_RELEASE_BUILD)DEF_BUILDS64 =
LINT64_BUILDS = debug64
↓ (次のように変更)
LINT64_BUILDS =
OBJS_DIR_DBG64 = debug64
↓ (次のように変更)
OBJS_DIR_DBG64 =
次にヘッダーファイルをprotoツリーにコピーさせます。
- # cd usr/src/uts
- # dmake -e install_h
これでビルドの準備は終了です。カーネルとドライバをビルドするには、
- # cd usr/src/uts
- # dmake -e
- # dmake install
としてやれば、カーネルと全ドライバをビルドしてくれます。
- 6. 作成したカーネルとドライバをシステムにインストールする
無事にカーネルとドライバがビルドできたら、これをシステムにインストールします。
それには、やっぱりbfuコマンドを使うのがよいでしょう。でもそのためには、bfuで 使用するアーカイブを作成する必要があります。それには、makebfuコマンドを使って やります。
(追記(09/07))
makebfuコマンドを起動するには、/opt/onbld/bin/i386にPATHが通っている ことが必要です。そうしないと、
/opt/onbld/bin/mkbfu[5]: cpiotranslate: not found
と怒られてしまいます。次のように起動前にパスを通してくださいね。
# setenv PATH /opt/onbld/bin/i386:$PATH ({t}csh)
# PATH=/opt/onbld/bin/i386:$PATH; export PATH ({k}sh)
また、makebfuの第一引数には、xxxxx/proto/root_i386とprotoディレクトリの下の root_i386まで指定する必要があります。
当初はタイポがあり、protoまでしか記述されていませんでした。ご注意ください。
(追記終わり)
- # cd /opensolaris
# makebfu -b /opensolaris/proto /opensolaris/opensolaris.sh
- # makebfu -b /opensolaris/proto/root_i386 /opensolaris/opensolaris.sh
すると、コマンドやライブラリがないので次のように怒られますが、無視してしまい ましょう。(^.^;)
Copying /opensolaris/proto/root_i386 to /tmp/bfu101682...
Copying /opensolaris/proto/root_i386 to /tmp/bfu101682...
Making compressed archives from /tmp/bfu101682 in /opensolaris/archives/i386/nightly.
Creating generic kernel archive: 33920 blocks
Creating generic lib archive: 10 blocks
Creating generic root archive: 100 blocks
Failed to create generic sbin archive: 10 blocks
find: illegal option -- d
find: [-H | -L] path-list predicate-list
Creating generic usr archive: 2640 blocks
Creating i86pc boot archive: 660 blocks
Creating i86pc root archive: 2500 blocks
Creating i86pc usr archive: 10 blocks
Creating conflict resolution archive: 590 blocks
アーカイブはarchiveディレクトリの下に置かれるはずです。一応、確かめておき ましょうね。
% find archives/i386/
archives/i386/
archives/i386/nightly
archives/i386/nightly/conflict_resolution.gz
archives/i386/nightly/generic.root.gz
archives/i386/nightly/generic.usr.gz
archives/i386/nightly/generic.lib.gz
archives/i386/nightly/i86pc.usr.gz
archives/i386/nightly/generic.sbin.gz
archives/i386/nightly/i86pc.boot.gz
archives/i386/nightly/generic.kernel.gz
archives/i386/nightly/i86pc.root.gz
後はこのアーカイブをbfuでインストールするだけ....なんですが、ここでちょっと 待った。
ソースは最新版(08/18日版)ですよね? Solaris Expressはその版のもの ですか? それが異なると、不整合がおきて立ち上がりませんね。(--;)
そこで、ダウンロードしたbfuアーカイブをまずシステムに適用しておきます。
最新のもの(8/18日版)であれば、archives-20050818というディレクトリに置かれて いるはずです。これをまずbfuでシステムに適用しましょう。
archives-20050818/i386/
archives-20050818/i386/conflict_resolution.gz
archives-20050818/i386/generic.usr
archives-20050818/i386/generic.root
archives-20050818/i386/generic.lib
archives-20050818/i386/generic.sbin
archives-20050818/i386/i86pc.root
archives-20050818/i386/i86pc.usr
archives-20050818/i386/generic.kernel
archives-20050818/i386/i86pc.boot
archives-20050818/BINARYLICENSE.BFU-ARCHIVES.txt
archives-20050818/README.BFU-ARCHIVES.i386
archives-20050818/THIRDPARTYLICENSE.BFU-ARCHIVES
- # bfu /opensolaris/archives-20050818/i386
注意としては、bfuの引数は絶対パスであること。
そして、bfuする前に、 bldenv -d /opensolaris/opensolaris.shを実行していることでしょうか?
bfuが終わったら、念のためacrを実行します。そしてリブートです。
- # acr
No conflicts to resolve. - # reboot
※ このacrコマンドは、僕はopensolarisがリリースされるまで知りませんでした。
こんな便利なコマンドがあったとは...と絶句したのですが(それまでは、マニュアルでconflictを解決していたので)、このコマンドはNevadaリリース(opensolarisのベース)で誕生したコマンドのようです。以前のSolaris10, Solaris9などでは存在していなかったニューフェースでした。^-^
さて、無事リブートが終わったら(配布されているアーカイブなので、問題はないはず)、先ほど作ったカーネルとドライバをインストールします。
- # bldenv -d /opensolaris/opensolaris.sh
- # bfu /opensolaris/archives/i386/nightly
- # acr
そしてリブートです。ソースに何か変なことをしていなければ、すんなりと立ち上がるはずです。(^^)
- # reboot
※ 万が一ブートしなかったら、grubメニューでfail safeを選び、配布されているアーカイブをもう一度適用しましょう。基本的には、
- 1. fail safeで立ち上げる
- 2. ルートをmountする
- 3. swapを追加する ← 仮想メモリが足りなくなると困るから...
- 4. bfuをマウントしたディレクトリに適用する (
-Rオプションで指定します-Rオプションはbootadmの方でした。ルートディレクトリは第二引数に指定します(^-^;)) - 5. rebootする
(追記(09/08))
上(↑)でさらって書いてしまっていますが、老婆心からもう少し詳細な手順を書いておくことにします。
- 1. grubのメニューでfail safeを選ぶ
- 2. パーティッションをマウントする
fail safeで立ち上げると、次のようなメッセージが出力され応答を促されます。
Searching for installed OS...
/dev/dsk/c0d0s0 -- Solaris11 nv_17 x86
Do you wish to automatically uupdate boot archives? [y,n,?]n
目的はシステムの復旧なので、ここでは"n"と応えておきましょう。
ここで表示されるパーティッションの論理パス名を使ってマウントします。ここの例だと、
/dev/dsk/c0d0s0がシステムボリュームなので、
# mount /dev/dsk/c0d0s0 /mnt
とします。
- 3. swapを追加します
# swap -a /dev/dsk/c0d0s1などとします。swap -lでちゃんとスワップが追加されているか確認できます。
# swap -l (確認)
- 4. bldenvを実行します (bfuを実行するため)
# /mnt/opt/onbld/bin/bldenv -d /mnt/xxxxx/opensolaris.sh
(全て、マウントしたシステムボリュームにあることに注意してください)
- 5. PATHを通します
# PATH=/mnt/opt/onbld/bin:$PATH; export PATH - 6. FASTFS, BFULD環境変数を設定します
# FASTFS=/mnt/opt/onbld/bin/i386/fastfs; export FASTFS
# BFULD=/mnt/opt/onbld/bin/i386/bfuld; export BFULD
- 7. bfuを配布されたbfuアーカイブに適用します
# bfu /mnt/xxxxx/archives-20050818/i386 /mnt
ワーニングが色々とでますが、非常事態のオペレーションなので目をつぶりましょう...(^-^)
バックアップを取っておくことをお奨めします。
何かあった時に上書きされてしまうファイルの例としては、/boot/grub/menu.lst, /etc/hosts, /etc/passwd,
/etc/shadow, /etc/default/login, /etc/system, /etc/vfstabなどがあります。
ブートに必要なもので変更されているものは、システムボリュームのどこかに保存しておくといいと思います。
また、fail safeが動作しない場合(って本当に想定外ですが...-_-)、インストールCD (CD1)で立ち上げて、
ここで説明した手順を行うこともできます。
まず必要ないと思う手順ですが、もしもの時に必要かも知れません。開発作業中は、想定しないことが
まま起こるものです(こういう時は、開発者は持てる力を出して復旧するのですが....結構大変っ ていうのが実感です...特に時間がない状況だと... ^.^;)
そんなこともあり、こういう手順を知っておいて 損はしないと思います。ただ、力業であることはご承知おき下さい。^-^
(追記終わり)
画像(↓)は、gvimとcscopeを使ってソースを見ているところです。これでOpenSolarisをハックするのに必要な環境ができあがったことになりますね。(^^)
Technorati Tag:
OpenSolaris
Technorati Tag:
Kernel Build
Technorati Tag:
Solaris
Posted at 05:51午前 9 06, 2005 by eota in opensolaris | Comments[0]
OpenSolaris事始め(その1)
OpenSolaris事始め(その1)
普段愛用しているToshibaのノート。そこにはLinuxが入っています。
(正確には、入っていました…です。どうしてかは、読んで頂けると分かるはず…T-T)
そしてついに、そこのWindows XPをOpenSolarisに置き換える決意を...。
(^-^;).oO(実は今更かも…) (注:Windows XPは、プレインストールされていたもの。LinuxでWifi/USBドライバーのコンフィグに成功してからは、最近はあまり使わなくなっていた)
今日はその顛末をご報告します。。。
- *事始め1. Solaris Expressをダウンロード Solaris Express community releaseを次の(↓)のところから、ダウンロードして CDに焼き付けます。
- *事始め2. Buildツールと/OpenSolarisのソースをダウンロード http://www.opensolaris.org/os/downloads
- ○ SUNWonbld-yyyymmdd.i386.tar.bz2
- ○ opensolaris-bfu-yyyymmdd.i386.tar.bz2
- ○ opensolaris-closed-bins-yyyymmdd.i386.tar.bz2
- ○ opensolaris-src-yyyymmdd.tar.bz2
- *事始め3. Installの準備をします 大事なデータがあれば、事前にバックアップをとっておく事をお奨めします。
- *事始め4. Installの開始 CDROMを入れてブートし、Installの開始します。
- *事始め5. 最後に言語CDをインストールする 言語CD(optionのCD)を使って日本語環境をインストールします。
http://www.opensolaris.org/os/downloads
(今回の一言)
☆ インストール --- なんでCDを4枚も使わなきゃいけないのぉ?
Solaris Expressをダウンロードしてインストールから始めます。
でも、CDROMを4枚分ダウンしてCDに焼き付けるのは流石に辛い。(;-;)
ちなみに、言語CDを入れると5枚になります。
同じサイト(↑)から、ビルドに必要なツールとOpenSolarisのソースをダウンロード します。
OpenSolarisのカーネルビルドをしない時は、別に必要ではありません。
X86向けには、次のようなツール、ソースをダウンロードすることになります。
(gccを使わない場合 - gccは現時点(2005/August)だと、ちょっとまだ不安定かも)
(yyyy=年, mm=月, dd=日)
(そのわけは… → 今回の一言)
(今回の一言)
☆ さようなら、Linux君。君の事は忘れないよ…。(T^T)
Windows XPのパーティッション、P1にインストールするつもりがCDROM一枚目が 終了した時点で念のため確認したら、P3のLinux君のファイルシステムが壊れて いました。(T-T).oO (い、痛すぎる…)
なぜこのようになったのか、未だ分かりません。えぇ、全然分からないんです。。。
もしかすると、P2にあったLinux Swap (0x82)が昔のSolarisのPartition IDと同じ なので、それが影響したかも知れません。
でも、そんなことはどうでもいーんです、もう。
(← 仕事を考えると、実は全然良くない…が、再現させるにはリスクがあまりに 大きすぎる…(--;)) 長年のデータ、そして作ったプログラムが消えてしまった…今はそれだけを受け止め、 ただ涙したいだけ(T-T)(uuuuuu..)
☆ P1のところにOpenSolarisを入れるのにはこの後も四苦八苦。
よくは分かりませんが、P1にWindows XPなどが入っていてそれに上書きしたい場合、 LinuxのfdiskなどでそのパーティションIDを0xbf(Solaris2 Partition ID)に変更して おくとよいのかも知れません。僕は結局その方法でインストールを完了しました。(--;)
(注:Linuxのパーティッション全部が上書きされたわけではなくて、ファイルシステムが大規模に破壊されfsck時に相当量のファイルがlost+foundにつながれてしまったためデータを紛失。とはいうものの、fsck後はマウントが可能だった。自力ブートはちと無理ぽかったもののCDの助けでfdiskを起動...)
上(↑)にもありますが、 パーティションの構成がちょっと面倒かも知れません。新規にパーティッションを 切る場合や、OpenSolarisだけを使う場合はそう面倒でもありません。(^^)
一枚目はすぐ終ってシステムがリブートして来ます。その後で追加のCDを聞いてくる ので、そのままCDを交換していきます。これを繰り返して、4枚インストールします。(ちょっと退屈かも…)
(今回の一言)
Debianのようにミニマムをインストールした後、ネットで必要なパッケージだけを 追加する方がありがたい気がする。SVR4パッケージ形式にラッパーをかますことで実現でき そうな気がしないわけではないけれど…。
でも、誰がOpenSolarisのビルド毎にパッケージを用意してネットで配布するのかという問題などが残りそうですね。。。(^-^;)
日本語環境といっても、ATOKや一部フォントなどcopyrightが違うものは配布されていないので、Solarisの日本語環境とは違います。やっぱ、こういう違いは結構でかいかも? (^.^;)
(今回の一言)
僕は身近にあったSolarisのCDから日本語環境を追加してしまいました。といっても、 これは日本語Solarisがあればの話…。本来は、scimなどのIMをちゃんと用意したいところですよね。
この辺りはオープンソースで用意していかないとどうしようもないところかも知れません。OpenSolarisの今後の国際化対応に期待 したいところですね。
取り合えず、無事インストール完了した姿(↓)です。(^-^)
Technorati Tag:
OpenSolaris
Technorati Tag:
Solaris
Posted at 02:41午前 8 22, 2005 by eota in opensolaris | Comments[0]
leakにも強いSol10のmdb:あぁぁなんて便利なのぉの巻
皆さん、こんにちは。 週末は如何でしたか? すっかり間が空いてしまい、ちょっとご無沙汰って感じです。(^-^).oO (Gobusata Desu!) 障害調査やらI/Oメモリやらで、カラカラと走り回っていたんですけれど、それに加え、 娘の通う日本語補習校のボランティアにはまってしまいました。はは。。。^.^; ボランティアで、 Webアプリを作っているんですけど、普段の開発とは畑違いの世界。でも、Webアプリに 興味があったので(流行ものに弱い)、ちょっと深入りしてしまったらはまってしまいました。^0^ MySQL + PHP + Javascriptなんで、完全にインタープリターの世界。 すぐ結果がみれる‥デバックもサクサク快感シリーズ。 あぁぁこのサクサク感がいいぃって浸ってしまい、ついつい夜更かしを繰り返し、ついには 家でも会社でも、昼でも夜でもプログラムを作っている有様。。。妙に若い頃を思い出してしまいました。 たまには違うプログラミングも楽しいって分かったこの頃です。(^_^) ちょっと脱線してしまいましたけど、今日も助っ人mdb君のお話です。 やっぱりプログラミングではデバックもサクサク快感を味わいたいモノ。 Solaris君にはmdbがついているさっていうことで、普通なら頭を抱えてしまいがちな、 メモリリークをmdbでささぁ、さくさくっていうところをご紹介です。 メモリリークというトラブルは、何にもないと**とてつもなく、そして限りなく**大変。 (はぁぁ‥考えただけでも、重くなってしまうぐらい‥) トラブルの状況も、マシンがだんだんと重くなって‥まるで足に1つ1つ重石を繋がれている ように、徐々に先に進まなくなってきて‥そして、もうズリズリと最後は這っているかのような‥ こういうトラブルに見舞われたら、あぁあなたのマシンにもメモリリーク居るかも? メモリリークは原因を探るのは難しいくせに、ワークアランドは簡単明快。そうです、マシンを リブートしちゃうんです。そうすると、それまで溜めに溜めた重石を全部捨て去るように、 いきなりサクサクに戻りますよね。でも、また数日して徐々に重くなっていく感じが復活。(--;) 仕方無しに、定期的にリブートするようにするかぁぁっていう体験はありませんか? そうです、それがメモリリークくんなんです。困ったものですねぇ。 さて、この困り者のメモリリークくん、調査しようとなると、まずはパニックではないので、 メッセージも何もありません。遅くなったら強制的にクラッシュダンプを取るのが第一歩です。 でも、そこからが地道な作業の始まり‥カーネル内のメモリの使用状況をみて、どの子が重りを つけられ、アップアップしているか探し、やたら巨大化して肥満状態になった子をみつけたら、 その子がどこでやたらメモリを食べているかを探す‥っていうのが、今まででした‥。^^; でも何も情報がないのでは、砂漠に埋もれた指輪を探すようなもの。壮大な砂漠を目前に途方に くれてしまいますね。(T-T) でもSolarisの場合は、嬉しい機能が幾つかあって、壮大な砂漠を抜ける道を教えてくれるので 本当に助かるなぁ。"-" メモリリークで当たりをつけるには、メモリにロギング機能がないと話になりません - この子が 重そうだって分かっても、何も情報がないのでは、結局は巨大なジャングルのようなソースコードを 走り回るようなもの。たっぷり汗をかくわりには、結局迷子になりかねませんよね。^.^ Solarisは、カーネルメモリのアロケートにslab allocator (object-caching kernel memory allocator) を使用しています。Jeff Bonwickさんが作成したものですが、大変 有名なもので、数々のOSに影響を与えているカーネルメモリ・アロケーターです。最近ではLinux/BSDも 似たような実装を行っています。興味がある人は、次のUsenixの論文に目を通されてもよいし、巷で 売られているカーネル本にも簡単な解説があったりします。(でも、ちょっと難しいので‥心してね^-^) Jeff Bonwickさんの(最初の)論文。 The Slab Allocator: An Object-Caching Kernel Memory Allocator (1994) カーネル本には、例えば、Uresh VahaliaさんのUnix Internals: The New Frontiers. (Prentice Hall, 1996)が有名かも知れません。 まぁ、slab allocatorの実装の詳細はそちらに譲るとして、slab allocatorには、 object-cachingによる性能改善以外に強力なログ機能があって、このログ機能が、メモリ破壊や メモリリークに一役かっているんですよぉ。このログ機構のお陰で、メモリ破壊の調査がやたら楽。 涙ポロポロものなんですけど、mdbのマニュアルとかを見て貰うと、何となく分かって貰えるかも? さて、メモリリークくんには、そのものズバリの"findleaks"というコマンドがmdbには用意されていて、 こいつを使ってやれば、あっという間のリークくん(←なんじゃらほい?)になるんですよ。 では、ちょっと見てやりましょうね。(前置きながかった?かしら‥) さぁ、トラブルが発生、あなたはクラッシュダンプを取りました。トラブッた人の話では、 どうやらメモリリークの様子。 でも大丈夫。findleaksで一発! さぁいきますよぉ。
> ::findleaks
CACHE LEAKED BUFCTL CALLER
000003000006f688 1 00000300088fada8 cpr_isset+0x14
000003000006f688 1 0000030008d72da8 cpr_write_header+0x64
000003000006f688 1 0000030008143570 devi_attach+0xcc
000003000006f688 1 000003013875e280 devi_attach+0xcc
000003000006f688 1 000003004461d938 devi_attach+0xcc
000003000006f688 1 000003000a819738 devi_attach+0xcc
000003000006f688 1 00000300210add68 devi_attach+0xcc
000003000006f688 1 00000300022b67c8 devi_attach+0xcc
000003000006f688 1 00000300095cbdf0 devi_attach+0xcc
000003000006f688 1 000003000994c038 devi_attach+0xcc
0000030001453688 1 0000030008f0d4f8 dv_mknod+0x28
000003000006f688 1 000003000acd6e88 dv_mknod+0x44
0000030000073408 1 0000030009217c08 dv_shadow_node+0x4c8
000003000006f688 1 0000030050a3b4d0 frrequest+0xafc
000003000006f688 1 000003000964a268 ibt_query_qp+0x108
0000030000077188 1 00000300009fb6b0 kobj_export_ksyms+0x11c
000003000007a008 1 00000300009f6868 kobj_export_ksyms+0x11c
0000030000077b88 1 00000300009eb5a8 kobj_export_ksyms+0x11c
000003000006f688 1 0000030000cc5b88 kobj_zalloc+8
000003000006f688 3 00000300087d6938 kobj_zalloc+8
000003000006f908 1 00000300091f1180 nv_mem_zalloc+0x10
000003000006f908 1 0000030008084338 nv_mem_zalloc+0x10
0000030000072008 1 0000030001f61cc0 nv_priv_alloc+0x10
0000030000072008 1 0000030001f5f630 nv_priv_alloc+0x10
000003000006f688 1 00000300087d4d58 pcmcia_get_io_regs+0x26c
000003000006f688 1 0000030008d73a20 rmc_comm_send_pend_req+0xa4
000003000006f688 3 0000030003176208 sppptun_open+0x2e0
000003000108cc88 1 000003000920c9d0 vn_alloc+0xc
=-----------------------------------------------------------------=
Total 32 buffers, 8936 bytes
どうですか? 誰が何回リークしたのか、一発でしょう?
じゃ、その関数のどこでメモリがアロケートされたものか、見るにはどうすればいいでしょう?
それには、BUFCTLで表示されているアドレスを、これまたズバリ"bufctl"コマンドに指定して
やります。例えば‥、
> 00000300088fada8::bufctl -v
ADDR BUFADDR TIMESTAMP THREAD
CACHE LASTLOG CONTENTS
300088fada8 300093c2d68 4f6d0aee3671 2a100cf1cc0
3000006f688 3000049b980 300007ae9a0
kmem_cache_alloc+0x90
kmem_zalloc+0x28
cpr_isset+0x14
i_cpr_save_cpu_info+4
i_cpr_mp_setup+0x2c
devi_attach+0xcc
attach_node+0xdc
i_ndi_config_node+0x148
i_ddi_attachchild+0x64
devi_attach_node+0x5c
devi_attach_children+0x90
config_immediate_children+0xa8
devi_config_common+0xa4
mt_config_thread+0x68
これで、メモリが解放されなかったのは、cpr_isset+0x14番地で獲得されたものだって分かりますね。
やたら簡単過ぎますっ。(-vを忘れないでね!)
findleaksはSol10で強化されているのですが、例えば-dフラグをつけてやると、bufctlを使用する
必要がありませんよ。手が抜けて、嬉しい限り!
> ::findleaks -d
findleaks: using cached results (-f will force a full run)
CACHE LEAKED BUFCTL CALLER
000003000006f688 1 00000300088fada8 cpr_isset+0x14
000003000006f688 1 0000030008d72da8 cpr_write_header+0x64
000003000006f688 1 0000030008143570 devi_attach+0xcc
000003000006f688 1 000003013875e280 devi_attach+0xcc
000003000006f688 1 000003004461d938 devi_attach+0xcc
000003000006f688 1 000003000a819738 devi_attach+0xcc
000003000006f688 1 00000300210add68 devi_attach+0xcc
000003000006f688 1 00000300022b67c8 devi_attach+0xcc
000003000006f688 1 00000300095cbdf0 devi_attach+0xcc
000003000006f688 1 000003000994c038 devi_attach+0xcc
0000030001453688 1 0000030008f0d4f8 dv_mknod+0x28
000003000006f688 1 000003000acd6e88 dv_mknod+0x44
0000030000073408 1 0000030009217c08 dv_shadow_node+0x4c8
000003000006f688 1 0000030050a3b4d0 frrequest+0xafc
000003000006f688 1 000003000964a268 ibt_query_qp+0x108
0000030000077188 1 00000300009fb6b0 kobj_export_ksyms+0x11c
000003000007a008 1 00000300009f6868 kobj_export_ksyms+0x11c
0000030000077b88 1 00000300009eb5a8 kobj_export_ksyms+0x11c
000003000006f688 1 0000030000cc5b88 kobj_zalloc+8
000003000006f688 3 00000300087d6938 kobj_zalloc+8
000003000006f908 1 00000300091f1180 nv_mem_zalloc+0x10
000003000006f908 1 0000030008084338 nv_mem_zalloc+0x10
0000030000072008 1 0000030001f61cc0 nv_priv_alloc+0x10
0000030000072008 1 0000030001f5f630 nv_priv_alloc+0x10
000003000006f688 1 00000300087d4d58 pcmcia_get_io_regs+0x26c
000003000006f688 1 0000030008d73a20 rmc_comm_send_pend_req+0xa4
000003000006f688 3 0000030003176208 sppptun_open+0x2e0
000003000108cc88 1 000003000920c9d0 vn_alloc+0xc
=-----------------------------------------------------------------=
Total 32 buffers, 8936 bytes
kmem_alloc_16 leak: 1 buffer, 16 bytes
ADDR BUFADDR TIMESTAMP THREAD
CACHE LASTLOG CONTENTS
300088fada8 300093c2d68 4f6d0aee3671 2a100cf1cc0
3000006f688 3000049b980 300007ae9a0
kmem_cache_alloc+0x90
kmem_zalloc+0x28
cpr_isset+0x14
i_cpr_save_cpu_info+4
i_cpr_mp_setup+0x2c
devi_attach+0xcc
attach_node+0xdc
i_ndi_config_node+0x148
i_ddi_attachchild+0x64
devi_attach_node+0x5c
devi_attach_children+0x90
config_immediate_children+0xa8
devi_config_common+0xa4
mt_config_thread+0x68
(たくさん表示が続くのでカット...^-^;)
でもちょっと困ることが‥。先もお話しましたけれど、これらの情報はslab allocatorのロギング機能
で取得されたものを表示しているんです。でも、ロギングはデバックカーネルで有効。。。。
それじゃ、困りますねぇー。デバックカーネルじゃないと、findleaksは強化されたものの、
それじゃぁ限定的な情報しか表示してくれませんよねぇ。例えば、
> ::findleaks
CACHE LEAKED BUFFER CALLER
0000030000072308 2 000006000091f0a0 ?
0000030000073508 2 00000300003ac300 ?
0000030000076908 1 00000300000e5b40 ?
0000030000077508 1 00000300000ecac0 ?
0000030000077808 1 00000300000e7000 ?
=-----------------------------------------------------------------=
Total 7 buffers, 8096 bytes
うーん、これじゃ、誰なのか分からない‥。(==;)
ロギングは性能に影響を与えるので、通常はoffなんですよねぇ。それにデバックカーネルは製品には
使われませんし。=.=;
そういう場合には、lightweighなデバックフラグを使うのも手かも知れませんよ。
/etc/systemファイルに、次の行を加えてリブートしてやるんです。
set kmem_flags = 0x00000100
すると、次のようにデバックカーネルでなくても、どの子がリークしてしまったか分かるようになりますよ。
> ::findleaks
CACHE LEAKED BUFFER CALLER
0000030000726c08 1 0000060000a25e40 cpu_init_private+0x54
0000030000073508 2 0000060000874580 init_cpu_info+0xcc
0000030000072308 2 00000600009f5a10 init_cpu_info+0x100
0000030000077508 1 00000300001460c0 kobj_export_ksyms+0x11c
=-----------------------------------------------------------------=
Total 6 buffers, 2888 bytes
このフラグ、富士通がPrimePowerをサポートするのに必要として、導入された軽量なデバックフラグです。
メモリリークだけでなく、メモリ破壊にも大変有効なので、気にならない方は、Onにしておくのを
お奨めしちゃいます。
(富士通のPrimePowerではデフォルトでOnになっている‥はず ^_^)
メモリリークとかメモリ破壊は、本当に大変な障害なんですけど、こういうツールで今は
相当に楽になっていますよね! 嬉しいなって思う機能の一つかな。^-^
それでは。
Posted at 05:53午後 6 13, 2005 by eota in opensolaris | Comments[0]
mdbの強力な助っ人CTF (でも、誰もみてくれない可哀想なやつ)‥の話
Solaris10の新機能ではありませんけれど、今日はSolaris9で導入されたmdbのCTF (Compact ANSI-C Type Format)についてお話したいと思います。 日頃お世話になっているツールですものね。クラフトマンは、ツールを大事にするものですもの。(^-^) 率直に言って、このCTFは、カーネルのデバックには相当な強力な味方になっていて、 一度これにはまると、CTF無しでデバックしたくなくなるほど、便利です。 またデバック時間もかなり節約してくれる、やりくり上手。開発者には必須のアイテムって言っても 良いくらいなんですね。でも、これが黒子、縁の下の力持ちなんですね。 そんな、日頃から陰で支えてくれているのに、陽の当たるところには出ない、CTFについて ちょっと紹介してあげたいって今回は思いました。^_^ oO (Yoroshiku!) CTF以前は、デバック情報を残すためにはコンパイラ・オプションで-gを指定するなどしなくて はなりませんでした。その結果、コンパイルされたカーネルは肥大化してしまい、 32bitの890Kバイト程のunixカーネルが、7Mバイト強まで膨れ上がってしまう有様で、 とても製品版のカーネルに使える状態ではありませんでした。 こんな大きいカーネルではロードにも時間がかかるし、格納媒体も増えてしまいますよね。 (でも、DVDだったら一枚で収まるのかな?) それに、CTF以前のデバックでは、adbのマクロや自分で作成したmdbのコマンドなどを使用して データ構造をクラッシュダンプから出力してやらなくてはならず、ソースが変更されたり、 別のバージョンのカーネルが使用されたりしてデータ構造に変更があったりすると、 表示された結果が妥当なものかすら分からないことがありました。 開発者としては、こっちも相当大きいですよね。adbのマクロやmdbのコマンドを その都度作成していくのは、大変手間暇がかかって、うんざりすることもままありました。 (今だから言える! えへへへへ‥) 結果、各開発者は各々お手製のコマンド、ライブラリを持つことになるんですけれど‥。 (まぁ、自然な流れとして‥) こういう問題を解決するため、C言語のシンボル情報、静的変数、大域変数の情報、リターン値、 引数情報などを効率良くカーネルに残すことを目的に、CTFが作られたわけです。 偉い、さすがっ! って一応エールを送りませう。これを開発したのは、Mike Shaprioさんと Matt Simmonsさんですね。Mikeさんは、元々mdbの開発者です。 そして、MattさんはSolaris10でkmdbを開発しています。(パチパチ "-") CTFの情報に加えて、不要な情報の削除、重複情報の削除、圧縮などを施した結果、 平均して1-2%の増加でデバック情報をカーネルに含ませることができました。 これなら、いつもカーネルに含ませることができますね。(うん、グットだぁ) CTF情報はコンパイル時に作成され、ELFセクションに一度格納された後、 リンカーでロードされる時に、各々のモジュールの持つ情報はマージされて、メモリーにロードされます。 パニックが発生した場合に、自動的にこれらの情報がクラッシュダンプに入るので、 デバック時には動作中のカーネルそのものの情報が得られます。 この仕組みにより、ソース変更や、カーネル・バージョンを気にせずデバックが可能になりました。 そして、Solaris9からmdbはこのCTF情報を使用しており、次のコマンドが導入されています。 ・sizeコマンド ・offsetofコマンド ・printコマンド それでは、ちょっとこれらのコマンドを使うとどういうことになるか、見てみましょうね。(うんうん) まず、psコマンドで、パニック発生時に動いていたプロセスをリストアップさせて、 この中のautomoutdのプロセス構造体を表示させてあげましょう。
> ::ps
S PID PPID PGID SID UID FLAGS ADDR NAME
R 0 0 0 0 0 0x00000001 0000000001842d30 sched
R 3 0 0 0 0 0x00020001 0000030005089b90 fsflush
R 2 0 0 0 0 0x00020001 000003000508a778 pageout
R 1 0 0 0 0 0x42004000 000003000508b360 init
R 101898 1 101898 101898 0 0x42000000 0000030019763398 automountd
R 101881 1 101881 101881 0 0x42000000 000003000f2197f8 nscd
:
automountdのプロセス構造体のアドレスは0x30019763398ですから、
このアドレスをprintコマンドに指定させてあげるだけで、プロセス構造体の中身を見ることができます。
> 0000030019763398::print proc_t
{
p_exec = 0x3001280bd00
p_as = 0x300070617a8
p_lockp = 0x300063f2a00
p_crlock = {
_opaque = [ 0 ]
}
p_cred = 0x300127cf350
p_swapcnt = 0
p_stat = '\002'
p_wcode = '\0'
p_pidflag = 0
p_wdata = 0
p_ppid = 0x1
p_link = 0
p_parent = 0x3000508b360
p_child = 0
p_sibling = 0x3000f2197f8
:
また、プロセス構造体のサイズが知りたい時は、sizeofコマンドを使用して、
> ::sizeof proc_t sizeof (proc_t) = 0xbd0とやってやります。 例えば、プロセス構造体の中にあるas構造体のオフセットが知りたければ、offsetコマンドを使用して、
> ::offsetof proc_t p_as offsetof (proc_t, p_as) = 8とやってやります。 これらのコマンドは、皆クラッシュダンプに格納されているCTF情報を参照してデータ構造(上の例だとプロセス構造体)を把握しているわけですね。実に便利っ! このprintコマンドは、多彩なオプションを実はもっていて、非常に便利。このprintコマンドだけでもかなりデバックがサクサク進む‥。ありがたや、ありがたや。
> ::help print NAME print - print the contents of a data structure SYNOPSIS [ addr ] ::print [-aCdhiLptx] [-c lim] [-l lim] [type] [member|offset ...] DESCRIPTION -a show address of object -c limit limit the length of character arrays -C unlimit the length of character arrays -d output values in decimal -h print holes in structures -l limit limit the length of standard arrays -L unlimit the length of standard arrays -n don't print pointers as symbol offsets -p interpret address as a physical memory address -t show type of object -i interpret address as data of the given type -x output values in hexadecimal type may be omitted if the C type of addr can be inferred. Members may be specified with standard C syntax using the array indexing operator "[index]", structure member operator ".", or structure pointer operator "->". Offsets must use the $[ expression ] syntax ATTRIBUTES Target: kvm Module: mdb Interface Stability: Evolving例えば、-taオプションを指定してやると、先の例は次のようになります。
> 0000030019763398::print -ta proc_t
{
30019763398 struct vnode *p_exec = 0x3001280bd00
300197633a0 struct as *p_as = 0x300070617a8
300197633a8 struct plock *p_lockp = 0x300063f2a00
300197633b0 kmutex_t p_crlock = {
300197633b0 void *[1] _opaque = [ 0 ]
}
300197633b8 struct cred *p_cred = 0x300127cf350
300197633c0 int p_swapcnt = 0
300197633c4 char p_stat = '\002'
300197633c5 char p_wcode = '\0'
300197633c6 ushort_t p_pidflag = 0
300197633c8 int p_wdata = 0
300197633cc pid_t p_ppid = 0x1
300197633d0 struct proc *p_link = 0
300197633d8 struct proc *p_parent = 0x3000508b360
300197633e0 struct proc *p_child = 0
300197633e8 struct proc *p_sibling = 0x3000f2197f8
300197633f0 struct proc *p_psibling = 0
:
このprintコマンドだけを見ても、CTFが如何に便利か分かりますよね。
でも、普段は誰からも意識されない存在。ちょっと可哀想。^^;
皆さん、mdbを使った時に、是非CTF君のことをちょっと思い出してあげて下さいね。(^-^)v
それではよい週末を。
Posted at 01:04午後 6 03, 2005 by eota in opensolaris | Comments[0]
SPARC Memory Model - 涙のハング物語 (またかいっ)
今週悩ませたのは、(またまた?)ハングの問題でした。 でも、今回のハングは、よりシステムプログラムっぽく、いてての問題でした。(++;) そんな僕の涙物語。。。。 眠ったきり、誰にも起こされないThreadがシステムに居たんですけれど、よりによってその子がロックを抱えたまま眠ってしまったんですね。 そのため、そのロックを待っている人たちがずらりと列を作るかのように並んでしまって、システムがにっちもさっちも行かなくなってしまいました。 ちょうと、おトイレの中で眠ってしまって、おトイレを待っている人たちがずらりと並んで、仕事どころではないっという状態でしょうか(って、例えがいいのか微妙ですが。。。。) そもそも、「ロックを抱えたまま眠って」っていうのがあり得ないって感じなんですが、デバイスノードを管理しているルーチンで、こういうことがあり得るものがあるんですね。 今回とは違う例ですけれど、例えば、mutexロックを掴んだthreadがsemaphoreでI/O完了を待っているのに、ちっとも完了しない‥そうこうしているうちに、そのロックを待っている人たちがずらりと並んで‥恐ろしい状況になってしまっている、、というのも似たような(?)感じですね。 # 振り向けばそこに‥たくさんの人たちがぁ‥って怖いですよね、どうでもいいですけれど。(-.-;) 今回のは、どうやらSPARCのメモリモデルと関係しているようでした。 これはちょっと難しい話なので、例をあげましょう。 支払いに小切手を送ったのに、届いていないと電話を貰う。「そんな馬鹿な、今日には届いているはず。ちゃんと郵便ボックスを見てよ?」と言っても、「配達の時間は過ぎている。さっき見たばかり。何も入っていなかった」って言われちゃう。 そんなぁぁぁと思っていると、また電話があって「アパートの人が間違えて入っていたよと君の封筒を持ってきたよ。ごめんね」。 ちっ、人騒がせなやつだ。。 こういうことと似たようなことが起こり得るのが、SPARCのload/store命令です。 上の例を次のように読み替えてみましょう。
小切手を貰う人 = メモリのデータをloadする 小切手を送る人 = メモリにデータをstoreする 郵便を送り、配達時間に届く = プログラムオーダー 隣の人が間違えて持っていった後、実際に郵便が届く = メモリーオーダーそうなると、上の例は次のような現象が起きたことになりますね。(って、ちょっと無理矢理かしら?) メモリにフラグ(データ)をstoreし、その番地からデータをloadしているのに、フラグが見えない。プログラムでは、storeが先でloadが後になっているので、フラグが見えるはず??? ちょっと後で、もう一度念のため見てみると、あれぇフラグが見えている。どうなっているのぉ??? こんな不可思議なことが起きてしまったりするんですねぇ。(*_*;) これは、実はプログラムで書かれているとおりに、loadやstore命令が実行されないことから起きます。えっ? コンパイラやアッセンブラの問題じゃないのぉって? そういう問題もあるかも知れないけど、ここでのプログラムっていうのは、機械語を想定してて、どちらかというとアッセンブラで書かれたプログラムっていう感じに近いですね。 例えば、次のプログラムをCPU1とCPU2で実行し、観測ポイントでそれぞれの結果を確認した時に、CPU1ではレジスタ%r1に1が入っているにもかかわらず、CPU2ではレジスタ%r2には、1が入っていない‥「えぇぇぇぇ、なんだってぇぇぇっ」ということが起きます。(へぇぇぇぇって感じでもあるけど ^-^)
CPU1 CPU2
store #1, [A] store #1, [B]
load [B], %r1 load [A], %r2 {{{{{ 観測ポイントでデータを確認
各CPUではstore→load命令の順に実行するようにプログラムでは指示しているわけなので、それぞれの値は1であるはずですよね?
CPU1ではそのとおりに実行したように見えますが、CPU2はload命令を先に実行してstore命令を実行したみたい。感じ、load命令を先に実行してしまったものですから、CPU1のstore命令がまだ完了していなかったって状況。
ここで、プログラムが指示しているstore→load命令の順をプログラムオーダーといいます。そして、実際にCPUが実行した順番、CPU1ではstore→load命令の順、CPU2では逆のload→store命令の順をメモリオーダーといいます。
つまり、SPARCプロセッサーは、プログラムで指示した順(プログラムオーダー)にメモリにアクセス(メモリーオーダー)するとは限らない‥ということなんですね。(な、なんだとぉぉぉぉ!)
ちょっと頭が痛いです。。。。(かなり頭が痛い???)
実際には、SPARC V9では次の3つのメモリモデルを決めています。
TSO: Total Store Order {{{{{ Load/Store同士の命令の順は守ってくれるモード
PSO: Partial Store Order {{{{{ Loadの命令の順は守ってくれるモード
RMO: Relaxed Memory Order {{{{{ Load/Storeもどっちの順も守らないモード
メモリモデルがRMOに指定されると、もうプロセッサーのお行儀はひどいものですね。LoadもStoreもしったことかぁっていう感じです。
当然性能は、期待とおり荒くれの順で、RMO > PSO > TSOの順に速くなります。
アウトローの方が行儀は悪いが、やたら速いっていう感じでしょうか? なんとなくイメージと合いますね。^-^
Solaris Operationg Systemは、UltraSPARCをTSOで使用しています。
RMOで走らせたいけど、制御できなくなってしまう‥という状況でしようか。
まだまだUltraSPARCを乗りこなせているとはいえませんねぇ。。。^-^; (やばぁぁぁぁ)
TSOでもloadとstore間で実行の順序を保証しないときがあるので、上の例のような状況が起き得るのです。こういう状況でハングが起きると、もぉ頭が痛いどころではありませんね。(しくしく状況 (;-;))
ちなみに、loadとstore間の実行順序を指定してやりたいときは、membar命令を使ってやります。
上の例ですと、次のようにmembar #StoreLoadを指定してやれば、実行順序はプログラムオーダーのとおりとなります。
CPU1 CPU2
store #1, [A] store #1, [B]
membar #StoreLoad membar #StoreLoad {{{{{ 実際には、この命令が要る
load [B], %r1 load [A], %r2
このmembarを忘れたりすると、いててててぇ状況になってしまったりするんですね。
このmembarについては、/usr/include/sys/atomic.hにコメントが書いてありますので、
近くにSunのシステムがあれば(で、Solarisがインストールしてあれば)見てみて下さいね。
(membar_enter(), membar_exit(), membar_producer(), membar_consumer()のところです)
# OpenSolarisがリリースされれば、堂々とソースを載せられるんですけど。もうしばらくの辛抱ですね。
今日はちょっとイテテの話題でした。仕事柄、こういう痛いトラブルにぶつかることもある‥そんな涙のお話(というより、愚痴かい?)でした。
さて、週末はゆっくり休むことにしましょ。
それでは皆さん、良い週末を
Posted at 06:46午後 5 27, 2005 by eota in opensolaris | Comments[0]
ある失敗談 - Solaris10のdevfsの仕業? それとも‥
先日、テストのお話をしましたよね。今日はその時の失敗談。 実は先日のテスト中、システムでパニックが発生しました。(!) 障害修正のテスト中に、パニックでシステムダウンなんて、「ゲゲッ」っていう状態ですよね。 全く洒落になりませんもの。(^0^) テストでは、お手製のデバイスドライバー(pseudoなやつ)を作って、Solaris DDI関数の動きを調べていたんです。コマンドで調べたい装置のデバイスノードと、そのデバイスの持つregプロパティの番号を指定してやると、お手製ドライバーを通して、Solaris DDI関数の返す値が分かる‥そんな“作り”の予定でした。ところが‥。 カーネルを置き換え、いざテストを開始するとパニック発生です! 「さーっ」と血の気が引いていきます。。。 (いやぁぁぁぁ (T-T) ← こんな気持ち) 落ち込む気分をカフェの一杯のコーヒーで持ち直し(あぁぁ、なぜサンなのにJava coffeeではないのだろうかとか思いつつ)、気を取り直して、クラッシュダンプを調べてみると、ddi_ctlops()の0×20番地で%g1レジスタが0であったためにパニックしたことが分かりました。 ddi_ctlops+0×20: ldx [%g1 + 0×40], %g1 なぜ値が0なのぉ?と更に調べてみると、このドライバーはロードされているものの、まだアタッチされていないために値が0となっていたことが分かりました。 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ ここでアタッチだのロードだの書いてしまったので、ちょっと簡単に解説です。 Solaris Operationg Systemでは、ドライバーは幾つかの状態遷移を経て、(無事)使用できるようになります。 ドライバーを使うには、まずカーネルからアクセスできないといけませんよね。 それには、まず動的にロード(load)してやる必要があります。そうすると、カーネルにモジュールとして登録され、カーネル空間としてアクセス可能になるわけです。 ですが、この段階ではまだドライバーとして機能してません。機能するためには、ドライバーが装置にアタッチ(attach)されないといけません。ドライバーがある装置にアタッチされると、インスタンス番号が割り当てられます。 そしてデバイスドライバーが装置を駆動し‥ハードウェアが使えるようになって‥めでたし、めでたしと、まぁこんな感じに進むわけです。 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ テストの時はドライバーはカーネル空間からみえているものの、実際には装置をまだコントロールしていない、そんな状態だったってことになるんですね。 まぁともかく原因は分かりました。少なくとも僕の修正のせいじゃないな‥。良かったっ! (^-^)v oO (Happiness) そう思うと、ちょっと余裕が生まれてきますよね。 今回も、ちょっとした(余計な?)疑問が頭の中を駆けめぐります。。。 例えば、ddi_ctlops+0×20番地で、なぜ%g1のチェックを入れないんだろう? %g1が0の時だってあるんじゃないのぉ‥Solarisのバカやろぉーとか‥。(^-^; Solaris10にはdevfsというものがあって、装置を使いたいってオープンしにいくと、devfsが勝手にロードしてアタッチしてくれます。余計な‥と思う人もいるでしょうけど、Dynamic ReconfigurationやらPCI Hot Plugなどをサポートするサーバーでは、システム稼働中にPCIカードを引っこ抜いて交換したりするわけですから、そういう場合には、動的にデバイスノードを変更してくれるdevfsの方が都合が良いときもあったりするわけです。 すると、今度は、devfsは僕のドライバーは面倒みてくれないのか‥devfsのバカやろぉーとか(またかいっ)、なるわけでして。(^-^; 更に落ち込む気分をカフェの2杯目のコーヒーで持ち直しつつ考えてみると、そういえば、僕のドライバーでは、調べる装置をオープンしているわけではないなと気づいてしまいました。オープンしているのは、僕のドライバーで、そこから調べる装置の情報を直接取得にいって‥。あぁ、その時に装置をオープンしていないのであれば、アタッチされている保証はないわけだ‥。すると、devfsが悪いわけじゃないなぁ。。。と。 そうなんです。Solaris10では、動的にattach/detachが実行され*やすい*ので、デバイスノードにアクセスしている最中は、holdしておくことが必要なんですね。じゃぁ、どうするのっ? というところで、今度はLayered Driver I/Fに気づきました。Solaris10には、Layered Driver Interface (LDI) というのがあって、ドライバーから*別の*ドライバーをオープンして使うことができるんですね。(うん、ちょっと便利‥かも?) 「そうか、これだぁ、これが必要だったのかぁぁ」 と、気づくわけです。 で、更に落ち込む気分をカフェの3杯目のコーヒーで持ち直しつつ考えてみると、、、 「でも、関係ないじゃんっ?(笑)」 と、ようやく気づくわけです。だって、Solaris DDI関数のテストが目的ですモノね! (^-^) そして、 「このままでは、俺はカフェイン中毒になってしまうではないかっ!」 ということにも‥。 (‥コーヒー飲み過ぎ‥) こんなことをしつつ、僕のサンでの一日がまた過ぎてゆくわけです‥。
Posted at 05:53午後 5 24, 2005 by eota in opensolaris | Comments[0]
mdbでサクサクとカーネルをデバック - mdb (modular debugger)
先日、AMD64のマシンでのハング障害について調べなくてはならなかったのですが、mdbの強力な機能のお陰であまり時間もかからず、助かりました。(^-^)V oO (Yokatta---)
そこで今日はmdbの話をちょっとさせて下さいね。
ハング障害っていうのは、案外と困りもの。だって、パニックだったら、"ここで値が壊れていたのでパニック"っていうのは、大抵は分かるでしょ? (まぁ、どうして値が壊れたの?っていう辺りが実は難しかったりするんですけど、それはちょっとおいて‥)でも、ハングの場合は、どこで(そして、なんで)ハングしてるのぉ?というところから出発しなければいけないんですものね。手間暇がかかるわけです。(~.~;)
でも、mdbには強力な機能があって、どこでハングしているかが簡単に分かります。今日はその方法について、説明しますね。(こういうのは、経験から来るモノですので、貴重な情報ですよぉ。)
ハングした場合は、幾つかケースがあるのですけど、今回はひたすらCPUが走り続ける、端から見ていても暑そうな、そんなケースについて説明しましょう。
(*) タスクがループしているひたすら汗をかいている場合 --- CPUが同じ箇所を永遠に実行し続けてしまう場合です。終了するはずもないので、ハングに見えてしまいますよね。
調査は大抵強制ダンプを採取して行うのですが、この場合はダンプを採取した時に各々のCPUが何を実行していたかをチェックすれば分かります。mdbでは、cpuinfoというコマンドがあって、ダンプが採取された時に各々のCPUで実行されているThreadについて情報を出力してくれます。
まず、ダンプをmdbで見るには、ダンプの番号、0から始まる数字を指定してあげるだけで、unixとvmcoreの双方のデータを読み込みます。例えば、ダンプがunix.0, vmcore.0だとしますよね。そしたら、0という数字を引数で指定してあげるだけです。
% mdb 0 ------- これで、unix.0, vmcore.0を読み込む。
そうすると、色々なメッセージがでてきますが、取りあえずは無視です。(^-^)
mdb: warning: dump is from SunOS 5.10 s10_74l1; dcmds and macros may
not match kernel implementation
Loading modules: [ unix krtld genunix dtrace specfs ufs sd isp sgsbbc
ip sctp wrsm random fcp fctl nca nfs sppp ptm logindmux md wrsmd cpc
fcip ]
そして、この不等号(>)のところでコマンドを打ちましょう。この不等号(>)はコマンドプロンプトなんですね。
コマンドは、コロンを2つつけて書くことになっています。例えば、::dcmdsみたいに。
今回の場合は、cpuinfoを実行することですから、::cpuinfoと打てばいいんですね。で、この時のポイントは、-vオプションをつけてやることです。そうすると、各CPUでの「その時の」threadの状況を出力してくれます。
::cpuinfo -v実はループしていたのは、割り込みレベル4で入っていた、ソフトウェア割り込みだったんですが、threadのスタックは、findstackコマンドで簡単に見れますので、すぐに原因までたどり着くことができました。
ID ADDR FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD PROC
1 00001835ac8 1b 1 0 109 no no t-0 2a10007fcc0 sched
| | |
RUNNING --+ | +-- PIL THREAD
READY | 10 2a10007fcc0
EXISTS | - 2a10001fcc0 (idle)
ENABLE |
+-- PRI THREAD PROC
60 2a10165fcc0 sched
ID ADDR FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD PROC
3 30000f22000 1d 1 0 -1 no no t-7 2a100255cc0 (idle)
| |
RUNNING --+ +-- PRI THREAD PROC
QUIESCED 60 2a100137cc0 sched
EXISTS
ENABLE
今回の場合は、次のような状態でした。
ID ADDR FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD PROC
0 fffffffffbc22960 1f 3 0 109 no no t-5898
fffffe80000b3c80 sched
| | |
RUNNING --+ | +-- PIL THREAD
READY | 10 fffffe80000b3c80 clock interrupt
QUIESCED | 4 fffffe80000b9c80 software interrupt
EXISTS | - fffffe8000005c80 (idle)
ENABLE |
+-- PRI THREAD PROC
99 fffffe80000e9c80 sched
60 fffffe80008b2c80 sched
60 fffffe800017fc80 sched
スタックを調べるには、見てみたいthreadアドレスに::findstackを指定してやるだけです。今回の場合は、怪しいthreadはfffffe80000b9c80ですから、これに::findstackを指定してやります。
fffffe80000b9c80::findstack今回はループしていても、クロック割り込み(レベル10の割り込みthread)が入ってきていましたので、スタックに残っている最後の関数は_resume_from_idle()でしたが、ハングはその前のwait_till_seen()で起きていました。(この関数が、ソフトウェア割り込みで呼び出されることを考慮しておらず、そのために発生したということがこの後すぐに分かりました。)
stack pointer for thread fffffe80000b9c80: fffffe80000b9860
[ fffffe80000b9860 _resume_from_idle+0xde() ]
fffffe80000b9980 wait_till_seen+0x67()
fffffe80000b99e0 remove_av+0xab()
fffffe80000b9a10 rem_avintr+0x52()
fffffe80000b9a40 pci_disable_intr+0x6e()
fffffe80000b9b00 pci_intr_ops+0x467()
fffffe80000b9b40 i_ddi_intr_ops+0xb1()
fffffe80000b9b80 i_ddi_intr_ops+0xb1()
fffffe80000b9b90 i_ddi_handle_intr_ops+9()
fffffe80000b9bc0 ddi_intr_disable+0x52()
fffffe80000b9bf0 bge_reset+0xc7()
fffffe80000b9c10 bge_restart+0x1c()
fffffe80000b9c40 bge_chip_factotum+0xd8()
以前は、mdbのようなデバッカーがなく、adbといったBSD Unixの時代からあるデバッカーを使用していたために、原因判明まで結構な時間がかかったものです。今はmdbがあるから、相当楽になったと思います。^-^
mdbでどのようなコマンドが使えるかは、::dcmdsを実行すると分かります。たくさん出てくるのでびっくりするかも知れませんね。出力された関数のもそっと詳細な情報を知りたいときは、::helpコマンドを使います。
例えば、findstackについてもっと知りたいっていう場合は、::help findstackって叩いてあげます。
::help findstackSolaris Operating Systemのいいところは、こういう強力なデバッカーが標準でついてくるところですね。
NAME
findstack - find kernel thread stack
SYNOPSIS
addr ::findstack [-v]
ATTRIBUTES
Target: kvm
Module: genunix
Interface Stability: Unstable
もちろん、OpenSolaris上でもほとんどすべてのソースが付いてきますので、DTraceやmdbの恩恵を得ることができます。こういう点が、LinuxやNetBSD, FreeBSDに比べて良いところかも知れませんね。開発時のデバックがOpenSolaris上では相当楽になるんじゃないかなって今から期待したいです。(^-^)
それでは良い週末を!
Posted at 03:08午後 5 20, 2005 by eota in