システムコール - みる会図書館


検索対象: UNIX MAGAZINE 2001年8月号
74件見つかりました。

1. UNIX MAGAZINE 2001年8月号

得られたホスト名は、送出する情報の一部としても利用 します。 strncpy(mywd. wd—hostname , myname , sizeof (mywd. wd—hostname) mywd. wd—hostname [sizeof (mywd. wd_hostname) 1 ] この場合にも、たんに mywd. wd_hostname フィール ドにコピーするのではなく、ホスト名を各内する領域のサ イズに注意してコピーしています。 このあとは、ネットワークの初期化コードか読きます。 socket システムコールを使い、ドメインには AF-INET を、型には SOCK-DGRAM を指定して UDP を利用す るソケットを作成します。 socket (AF—INET, SOCK_DGRAM, 0 ) ) く 0 ) { sys10g(LOG ERR, "socket : %m") ; if ((s ソケットを作成しただけではプロードキャストを利用で exit(l); syslog (LOG—ERR , & 。Ⅱ , sizeof(on)) くの { if (setsockopt (s , SOL—SOCKET, exit(l) ; " setsockopt SO-BROADCAST : %m" ) ; SO_BROADCAST, なっています。そうしないと、 bind システムコールの実 たすべての領域をいったん 0 でクリアすることが慣習と 構造体の準備にはすこし注意が必要です。ます、割り当て 次の bind システムコールの呼出しに用いる sockaddr キャストを利用できるようにしています。 ト・オプションを設定し、作成したソケットでプロード きないので、 setsockopt システムコールを使ってソケッ sp¯>s—port ; Sin. sin_port sin. sin—family = AF—INET; Sin. sin_len = sizeof (Sin) ; memset (&sin, 0 , sizeof(sin)) ; 行時にエラーが発生することがあります。 す。そのため、 bind システムコールを呼び出すときには UDP を利用する場合は sockaddr-in 構造体を指定しま かし実際には、接続形態に合わせた構造体を指定します。 は sockaddr 構造体を指定することになっています。し bind システムコールのマニュアルでは、第 2 引数に 70 この構造体の大きさも指定する必要があります。 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) くの { sys10g(LOG-ERR, "bind: %m") ; exit(l); 初期化の最後では、 run-as 関数により取得したグルー プ ID やユーザー ID を使って権限を設定しなおします。 こまでにソケットの作成やポートの割当てなど、 root 権 限を必要とする処理は終っているため、以降では root 権 限はイになるからです。 setgid(unpriv—gid) ; setgroups(l , &unpriv—gid) - / * XXX BOGUS groups [ 0 ] egid * / setuid(unpriv—uid) ; if ( ! configure(s) ) exit(l); if ( !quiet-mode) { signal (SIGALRM , onalrm ( 0 ) ; onalrm) ; さこ、 configure 関数を使って実際に接続しているネ ットワークの清報を取得します。これにより、バケットを 送出すべきアドレスを決定します。また、 quiet-mode が 真ではない、つまり自身の 1 辭長を送出する必要がある場合 には、 signal 関数を使って ALRM シグナルに対するシ グナルハンドラを登録し、 onalrm 関数を呼び出して情報 を送出します。 rwhod では、定期的におこなう情報の送出にタイマー 割込みを利用しています。タイマー割込みルーチンである onalrm では、関数を終了する前に再度タイマーを設定す るため、定期的に処理をおこなえるようになっています。 初期化カ鮗ると、情報をネットワークから受け取るため の無限ループカきます。ルーフ。のでは、ネットワー クから情報を受け取るために recvfrom システムコールを 呼び出しています。このシステムコールは、ソケット、値 を書き込むバッフア、バッフアの大きさといった write システムコールて利用する引数、 recv システムコールて利 用するフラグ引数、さらにどこからメッセージが到着した かを受け取るための領域とその大きさを引数にとります。 recvfrom(), (char *)&wd, sizeof (struct wh0d) , 0 , (struct sockaddr * ) &from, if ()c く = の { CC &len) ; UNIX MAGAZINE 2001.8

2. UNIX MAGAZINE 2001年8月号

ネットワークにはさまざまな計算機がつながれていま す。ネットワークを利用するすべての計算機かのもの であれは間題にならないことも、さまざまな言算機か混在 するために大間題となる場合があります。次のプログラム ネットワーク・バイト順序 union { main(void) int #include く stdio . h> を見てください。 unsigned 10 Ⅱ g unsigned char 1 ; c [ 4 ] ; u. c [ 0 ] u. c [ 1 ] u. c [ 2 ] u. c [ 3 ] このプログラムを実行したときに、 66051 と表示される u. 1 ) ; exit(O) ; printf ( "%lu\n" 68 0 値として 66051 をネットワークに出力したとしましよう。 きるでしようか。たとえは 66051 と表示する計算機から、 このように角物 ( の異なるマシン間で通信すると、何か起 ます ) 。 解釈されますにのようなシステムは Big Endian と呼び 0 x 2560 = 50331648 十 131072 十 256 = 50462976 と が上位の桁を表し、 3 >< 2563 十 2 >< 2562 十 1 x 2561 十 一方、 50462976 と表示されるシステムでは右側のバイト ますにのようなシステムを LittIe Endian と呼びます ) 。 = 65536 十 512 十 3 = 66051 と解釈され 2561 十 3X256 か上位の桁を表しており、 0 x 2563 十 1 x 2562 十 2 x 題です。 66051 と表示されるシステムでは、左側のバイト この 4 バイトを整数としてみるとどう解釈されるかカ墹 0 1 2 3 番に 0 、 1 、 2 、 3 を書き込んでいます。 このプログラムでは、以下のように 4 バイトの領域に順 ります。 システムもあ川ま、 50462976 と表示されるシステムもあ ネットワーク上では、値はすべてビット列としなければな らず、バイトの並びとして扱われます。つまり、 4 バイト をまとめた整数ではなく 4 つのバイトか通信され、そオ・しが 整数として解釈されるため、この値は 0 、 1 、 2 、 3 の 4 バ イトで表現されます。これを同種の計算機で読み込めは、 さきほどのフログラムでみたとおり 66051 という値か彳等 られます。一方、この値を 50462976 と表示する計算機 では、 0 、 1 、 2 、 3 の 4 バイトをこの順番で読み込むと ( 当然ながら ) 50462976 と解釈されます。つまり、デー タを送り出した計算機での値と受け取った計算機での値が 違ってしまうのです。これでは正しい通信ができません。 そこで、ネットワーク上で通信をおこなう場合には、 4 バイトの整数を送り出す際の順番か決められています。さ きほどの例でいえば、 50462976 を送出したときにネット ワーク上で 0 、 1 、 2 、 3 となるように、つまり下位の桁 から順番に送り出すことに決まっていますにれをネット ワーク・バイト順序と呼びます ) 。 これをプログラムとして実現する場合、現在のシステム がどのようなバイト順序を使っているかを知る必要があり ます。実際には、ライプラリ関数として 4 バイトの整数 をネットワーク・バイト順序に変換する hto ⅲ関数など が用意されているので、それを利用します。重要なのは、 ネットワークに送出するデータはかならすこのネットワー ク・バイト順序に統一するという点です。こう決めておけ は、解釈の異なる計算機か混在していても正しく通信でき るようになります。 UDP の利用 UNIX MAGAZINE 2001.8 ・ socket システムコールでソケットを作成する。 データ送出のために次のような処理をおこないます。 ことでデータを受信できます。一方、クライアント側では のを待っ ・ recvfrom システムコールを実行してデータが到着する ・ b ⅲ d システムコールでソケットに名前を割り当てる ・ socket システムコールでソケットを作成する のときサーバー側では、 こなうため、プログラム内で UDP を利用しています。 rwhod デーモンはプロードキャストを用いた通信をお

3. UNIX MAGAZINE 2001年8月号

連載 / BSD をハックする一② 写真 1 試作した表示器 通常のユーザー・プログラムカ阯まってしまうようなト ラブルカ起こると、表示も止まる ・ユーザープロセスがロードアベレージやメモリ空き状況 などを頻繁に調べるのは負荷か高い ・ユーサーランド・プログラムですませたのでは、、ハック する " という連載の名に反する という間題があるため、カーネル内に表示ソフトウェアを 組み込むことにしました。間題はカーネルにどのように組 み込むかです。別の言い方をすると、どのプロセスのコン テキストで動かすかということになります。カーネルのう ち、システムコールから呼び出される部分をトッフ。ハーフ と呼びます。トッフ。ハーフは現在走行中のプロセスのコン テキストで仕事をしています。プロック ( イベント待ち ) することもできます。割込み ( ハードウェア割込み ) のハ ンドラから呼び出される部分をポトムノ、一フと呼びます。 目標 ポトムハーフは現在走行中のユーサープロセスとは無関係 です。また、プロックできません ( してはいけません ) 。ト 総合的な手間を考えると、どうやらパラレルポートに接 ッブハーフ / ポトムハーフはカーネルの状態に関する概念 続する表示器がもっとも簡単なようなので、これを作成す であり、カーネル内の関数のなかには、トッフ。ハーフとポ ることにしました。その次に、 20 桁 x 2 行の LCD 表示 トムハーフの両方から呼び出されるものもあります。 器のシリアルポートへの接続に挑戦することにします。 ・割込み駆動 ( ポトムハーフ ) ロードアベレージ表示器 状態表示は定期的に更新するものなので、カーネル内の タイマー機能を用いることになると思われます。 2 桁の LED をパラレルポートに接続して何を表示する ・カーネルスレッド のがよいでしようか。手始めに、 ( 簡単そうな ) ロードア NetBSD の場合、デフォルトで swapper 、 pagedae- べレージを表示してみることにします。写真 1 か試作した rnon 、 reaper 、 ioflush 、オプションで apm() 、 usbd 表示器です。 などのプログラムカ可力いています ( いるようにみえま 仕様 す ) 。いすれも ps コマンドで表示されますが、対応す るプログラムは / sb ⅲにも /usr/libexec にもありませ 目標として設したイ」嘛について説明します。ます、機 ん。これらはカーネルスレッドであり、そのコードは 能 - E の目標は以下のようにしました。 カーネル (/netbsd) のなかにあります。 ・ 2 桁の 7 セグメント LED を使用する。 カーネルスレッドにる方式をさらに分類すると、既 ・ロードアベレージを表示する。 存のカーネルスレッドに表示機能を追加する方式と、表 ー範囲は 0.0 ~ 9.9 。 示のためだけのカーネルスレッドを追加する方式が考え PC UNIX のロードアベレージは、私がおもに使う られます。 ものでは 0 ~ 3 内外なので、小れ点以下 1 位までを ・ユーサー・プログラム 表示することにします。 ューザー・プログラムになんらかのシステムコールを実 ー表示は 1 秒ごとに更新する。 行させて、そこで処理をおこなう方式です。たとえば、 ー小れ点は 1 秒ごとに点滅する。 nfsd や nfsio ( 他の OS では biod や nfsiod という名 0 前のこともある ) がそうです。システムコールは終了せ す、ユーサー・プログラムの状態は、、システムコール実 行中 " のままとなります。通例、シグナルを送ることで システムコールは終了し、サービスを停止します。 141 UNIX MAGAZINE 2001.8

4. UNIX MAGAZINE 2001年8月号

ば変換は不要ですが、そオび丿、タ ) 場合には受け取ったデー タをホストバイト順序に変換しなけれはなりません。そこ で、この部分のコードは Big Endian のマシンでは実行さ れないように、条件コンパイルカ硬われています ( 図 2 ) 。 このコードでは ntohl 関数を使って、バケットの送出時 刻、ロードアベレージの勺値、システムの起重加骸リ、各 ューサーのアイドル時間とログイン日該リを、それぞれネッ トワーク・バイト ) 側茅からホストバイト順序に変換してい ます。 さらに、バケットには含まれていないバケットの受イ 刻を現在の日骸リとして登録したあと、このデータを書き出 します。 (void) time((time-t *)&wd. wd—recvtime) ; (void) write(whod, (char *)&wd, (c) ; if (fstat(whod, &st) く 0 Ⅱ st . st-size > cc) ftruncate(whod, (c) ; (void) close(whod) ; 最後に、書き出したデータよりもファイルのほうカ張 い、つまり以前のデータよりも小さくなっていれば、旧 い無効なデータが残っていることになります。この場合、 rwho コマンドの誤動作などが予想されるため、 ftrun- cate システムコールを使ってファイルのサイズを小さく します。 これで main 関数は終了です。 1 つのバケットを処理す る無限ループを繰り返しながら、ネットワークから送られ てくるすべてのバケットを、データベース・ディレクトリ にファイルとして書き込んでいきます。 次に、タイマー割込みにより起動され、自身の情報をネ ットワークに送出する onalrm 関数をみてみましよう。 この関数の地頁では、ます現在日該リを取得します。さら 、 10 回ごとにシステムの起重加該リを取得しなおします。 now = time (NULL) ; if (alarmcount % 10 getboottime ( 0 ) ; alarmcount 十十・ 基本的にシステムの起重丿時刻か変わることはありません が、日か狂っていたなどの理由でシステムの日か変更 されると、システムの起動刻もそれに合わせて変わりま す。このようなことか起きないともかぎらないので、 10 回ごとにシステムの起重加刻を再確認しています。なお、 alarmcount 変数は外部変数として定義されており、初期 72 値は 0 です。つまり、 onalrm 関数か最初に呼び出された ときの値は 0 であり、システムの起動刻をかならす検査 することになります。 続いて、実際の情報を準備します。ます wtmp ファイ ルを調べ、ファイルのタイムスタンプが史新されていた り、ファイルの大きさが変わっている場合にはその内容 を内部のバッフアにコピーしなおします。実際の処理は、 この内部バッフアをみながらおこなわれます。これは、フ ァイルを読むという上交的重たい作業をできるだけ避け、 メモリからの読出しですませるためです。このとき、ユー サーがシステムにログインした時刻をネットワーク・バイ ト順序に変換して一尉寺しておきます。 we—>we_utmp. out—time = htonl (utmp [i] . ut—time) ; こうすることで、毎回バイト順序の変換をおこなう必要 がなくなります。 あとは w コマンドと同様の処理になります。ロードア べレージの平上直を取得したり、端末の山辭冬更新琲刻を使 ってユーサーのアイドル時間を引・算したりします。 データの準備ができたら、それを送出する処理に移りま す。実際にはマルチキャスト通信を利用してデータをやり とりするコードか含まれていますが、 こではプロードキ ャスト通信のためのコードだけに注目します。 onalrm 関 数のバケットの送出に関する部分からマルチキャスト里 のコードを取り除くと、次のようになっています。 f0 て ()p = neighbors ; np ! = NULL; np = np¯>n—next) { np—>n—addrlen) ; np—>n—addr , (void) sendto(s , (char *)&mywd, cc, 0 , UNIX MAGAZINE 2001.8 (void) a1arm(AL—INTERVAL) ; done : するようにします。 すから、 alarm 関数を使って一定時間後にシグナルか当盟 [ にデータを送るべき時刻にシグナルが発生すればよいので する日該リを設定しなければなりません。そのためには、次 後に重要な仕事が 1 っ残っています。次にデータを送出 この処理カ鮗ると onalrm 関数もはは終了ですが、最 アドレスにデータを送出するだけです。 納されているので、 sendto システムコールを利用して各 送出すべきすべてのアドレスが neighbors リストに格

5. UNIX MAGAZINE 2001年8月号

・ bind システムコールでソケットに名前を割り当てる。 ・ sendto システムコールを使ってデータを送り出す。 いすれも最後の recvfrom や sendto を繰り返すこと で、情報を扣度もやりとりすることができます。 プロードキャストを利用するには、もうすこしおましな いが必要です。具イ勺には、プロードキャストを利用する ソケットに SO-BROADCAST ソケット・オプションを 設定します。このオプションを指定しておけば、プロード キャスト・アドレスを宛先としてデータを送出すると、自 重加勺にプロードキャストを用いた通信がおこなわれます。 「 whod のソースコード それでは rwhod のソースコードをみていきましよう。 ファイルは /usr/src/usr. sbin/rwhod/rwhod. c です。 ソースコードの先頭では、コピーライト表示やファイ ルのバージョン識別情報などに続き、各種の定義がおこな われています。このあたりは飛はして、 main 関数からみ てみましよう。 main 関数の : 頁では、ます実行している ューザーが root であることを確認しています。 if (getuid()) errx(l , "not super user'l) ; このコードでは、 getuid 関数か返す値、つまり現在の ューザーのユーサー ID が 0 以外かどうかを調べていま す。この簡単なコードによって、起動したのが r 。。 t では ない場合にフログラムを終了するようにしています。 ミッションをうまく言影すれ ファイノレシステムは : の / 、一 は、 root 以、外のユーザーの実行を許可しないファイルに することができるため、このコードは不要にも思えます。 ッションが変わ しかし、何かの都合でファイルのパー り、誰にでも実行できるようになるかもしれません。この 程度の簡単な処理でチェックできるのですから、詩ヾてお いて損はないと思います。 次に、 run-as 関数を呼び出して、プログラムを実行す る権限を設定しなおすためのユーサー ID やグループ ID を取得します。 run-as (&unpriv—uid , &unpriv—gid) ; この処理は多くのデーモン・プログラムでおこなわれま す。完璧なプログラムであ川ま心配する必要はないかもし UNIX MAGAZINE 2001.8 プログラミング・テクニック れませんが、なんらかの理由で侵入者の攻撃対象となった 昜ロ、 root の権限のまま実行していると、侵入者に root 権限をケえてしまう可帽生があります。そのため多くのデ ーモン・プログラムは、必要最小限の権限で動作するよう になっています。 ここて取得した ID を使って、のちはど実際に権限を変 更します。 引数のチェックをしたあと、 daemon 関数を使って自 分自身を制御端末から切り離し、さらにバックグラウンド で重川するようにします。 #ifndef DEBUG daemon(l , 0 ) ; このコードが ifndef て話られている点に注意してくだ ーでは、 DEBUG シンポルが定義されていない さし、。 場合にのみ daemon 関数を実行するようにしています。 DEBUG シンポルが定義されていれは、このプログラム はまだデバッグ段階ということになります。その場合にプ ログラムをバックグラウンドで実行すると、テンヾッグイ乍業 の妨げとなる可能生があるためです。 ほかにも、 HUP シグナルが送られたときにシステムの 起重加刻を読み直すための設定や、 syslog を用いたログ の出力の準備、 UDP て利用するポートの値の取得、ユー ザー情報を得るための utmp のオープンなどの初期化を おこなっています。これらの処理の途中でホスト名を取得 し、データとして利用できるようにしています ( 誌面の都 合ー E 、てオ斤り返しています。以下 1 司様 ) if (gethostname (myname , 1 ) く 0 ) { sizeof (myname) sys10g(LOG_ERR, "gethostname : %m") ; exit(l); myname は MAXHOSTNAMELEN の長さをもつ 配列です。ます、ここにホスト名を抽出します。取得した ホスト名のなかでドットかイ吏われている場合は、ドットの ない、、ホストの " 名前部分を取り出します。 if ( ()p = index(myname , * CP この処理は意外に簡単です。 index 関数を使って頁か ら文字、、 . " を検索し、みつかればそこにヌル文字を書き込 #endif みます。 69

6. UNIX MAGAZINE 2001年8月号

プログラミング・テクニックノ ntOh1 (we—>we—utmp. out—time) ; we—>we_utmp. out—time we—>we_idle ntohl(we—>we—idle) ; for (i 0 ; i く n ; i + + ) { we = Wd. wd_we ; wd. wd—boottime = ntohl (wd. wd—boottime) ; wd. wd-loadav[i] = ntohl(wd. wd—loadav[i] ) ; for (i 0 ; i く 3 ; i + + ) wd. wd—sendtime = ntOhI (wd. wd—sendtime) ; / * undo header byte swapping before writing t0 file * / struct whoent *we ; int i , n = ()c ー WHDRSIZE)/sizeof (struct whoent) ; #if ENDIAN ! = BIG_ENDIAN 図 2 ネットワーク・パイト順序とホストパイト川印の変換 十十 ; #endif if ()c く 0 & & errno ! = EINTR) syslog (LOG-WARNING , C011tinue ; recvfrom システムコールは言売み取ったメッセージのサ イズを返します。この値が 0 以下であれば、 よる言もムみが失敗したことを示します。ただしこの場合で も、タイマー割込みが発生してシステムコ reCV.• ーノレの実行が中 recvfrom ( こ UNIX MAGAZINE 2001.8 ネットワーク・バイト順序になっています。どちらも同し はありません。 sp->s-port に内されている値はすでに ん変換しなけれはならないような気がしますが、その必要 タはネットワーク・バイト順序となっているので、いった ので、それを石忍するためです。バケットに含まれるデー rwhod もやはり同しポートからデータを送出するはすな このとき、 sp->s-port と上交しています。送り手側の continue ; inet—ntoa(from. sin—addr) ) ; ntohs(from. sin—port) , , - "%d: bad source port from %s" syslog (LOG—WARNING , 号 - ! insecure_mode) 、 { if (from. sin—port ! = sp—>s—port & & ・ たかを石薩忍しています。 次に、受け取ったメッセージか正しいポートから送られ ています。 を表示する前に本当にエラーが発生したかどうかを石忍し 断されたときはとくに間題がないので、エラーメッセージ バイト順で表現されているので、変換しなくとも値か等し いかどうか調べられます。なお、値カしいかどうかは判 定できますが、値の大小は上交できません。ポート番号の 大小を上交することはないと思いますが、その場合はいっ たんホストバイト順序に変換してから上交をおこなってく ださい。 このあと、メッセージのサイズ、ノヾージョン番号、メッ セージのタイプを検査し、さらにホスト名の部分が正しい 値になっているかを調べます。これらの条件がすべて満た されていれは、データベースに用いるファイル名を作成し continue ; sys10g(LOG_WARNING, "%s : %m" ッ path) ; if (whod く 0 ) { whod = open(path , O—WRONLY ー O—CREAT , 0644 ) ; ィレクトリに作成します。 そして、このファイル名でファイルをデータベース・デ "whod. %s" , wd. wd—hostname) ; (void) snprintf(path, sizeof path, ます。 71 順序の変換です。ホストのバイト順が Big Endian であれ 次の処理は、ネットワーク・バイト順序とホストバイト 十分です。 クトリに変更しているため、ファイル名を指定するだけで 使ってカレント・ディレクトリをデータベース・ディレ rwhod デーモンの初期イに、 chdir システムコールを こではとくにディレクトリを指定していませんが、

7. UNIX MAGAZINE 2001年8月号

VMware 図 7 ネットワーク・デパイスの割当て ロ ロ。 ロ。 ロ。 したとき、モジュールは VMware に「僕のメモリ、返し て ! 」と要求します。そして、要らなくなったらふたたび 「返すね」と返却します。同様の動作がほかのイ反想 PC で もおこなわれ、結果として実メモリ容量よりも大きなメモ リをイ瓦想的に作りだします。 ところで、このモジュールはかならすしも組み込む必 要はありません。ゲスト OS にモジュールを組み込んで いない場合、未使用メモリを VMware に返さなくなり ます。つまり、組み込まない場合にシステムが受ける影響 は、、、実メモリの容量より大きなメモリを佖想的に作りだ せなくなる " ことです。 さきほど、ゲスト OS のメモリが足りなくなったとき、 モジュールが VMware にメモリの割当てを要求すると説 明しました。このとき、もし VMware のメモリプールに 余裕がなかったら、いったいどうなるのでしようか。 目を皿にしてマニュアルを読みましたが、そのような場 合の動作についての言当主はみつけられませんでした。そこ で簡単なテストをしたところ、メモリか割り当てられるま でイ反想 PC が停止する ( ! ) という現象がみられました。も ちろん、イ反想 PC カ阯まれはゲスト OS も止まります。 実メモリ容量より大きなイ反想メモリを利用できるのは、 たしかに便利です。しかし、現実に運用しているときに、 どのくらいの頻度で上記のような現象が発生するかは不明 ですし、いざというときに止まってしまっては困ります。 クリティカルな条件て利用する場合は、このモジュールを 組み込まないほうがいいかもしれません。 ネットワーク・テパイスの割当て ESX サーバーでは、ネットワーク・テンヾイスはコンソー ル OS と仮想 PC に別々に割り当てます。たとえば、複 数のネットワーク・デバイスがあるホストでは、通常は 1 つをコンソール OS に割り当て、残りをイ反想 PC に割り 当てることができます。この場合、それぞれのイ課 PC に 専用のネットワーク・デバイスを割り当てたり、あるいは 182 1 つのネットワーク・テパイスを複数のイ反想 PC で共有す ることができます ( 図 7 ) 。 このとき、コンソール OS は、 VMnix に組み込まれた デバイスドライバを通してネットワークにアクセスし、仮 想 PC は、 VMkernel に組み込まれたテンヾイスドライバ (VMkernel モジュール ) を通してネットワークにアクセ スします ( 図 5 ) 。 Workstation 版のゲスト OS は、 VMware プロセスが 発行する Linux のシステムコールを通してネットワーク にアクセスします (/dev/{vmnet(),vmnetl, . み書きしています ) 。ところが、このときにユーサー空間 とカーネル空間のあいだでデータのコピー処理が発生し、 これが VMware のネットワークを遅くする一因になって います。しかし、 ESX サーバーではこのようなコピーは イなので、かなりの生能改善か期待できます。 また、コンソール OS と VMware がテンヾイスへアクセ スするガ去はそれぞれ独立しているため、互いのデータを 覗き見ることはできません。仮想 PC どうしでも覗き見は 不可能です。ただし、それぞれのテンヾイスをダムハプに接 続していれば、ハフ経由て流れ込んできたデータを読み取 ることはできます。 SCSI アダブタと SCSI ティスク ネットワーク・テンヾイスと同様、 SCSI テンヾイスについ てもコンソール OS と仮想 PC に別々に割り当てたり、 共有することができます。 イ瓦想 PC は、 VMware に割り当てられた SCSI アタブ タカードを通じて、 SCSI ディスク上に作られたイ瓦想ディ スクファイルにアクセスします。反対に、イ瓦想 PC は自 分の仮想ディスクファイル以外のディスクやファイルに アクセスすることはできません。 コンソール OS は、 VMware に割り当てた SCSI テンヾ イスにアクセスできます。ただし、この場合は VMker- nel がコンソール OS に組み込まれている必要があります ( VMkernel 経由でアクセスしているようです ) 。コンソー ル OS が VMware 管理下の SCSI ハードディスクにア クセスするのは、 VMware 用のノヾーティションを成疋し たり、ファイルシステムをフォーマットしたり、仮想ディ スクファイルを作成したりするためです。 UNIX MAGAZINE 2001.8

8. UNIX MAGAZINE 2001年8月号

次に、 neighbors リストにすでにこのデータが登録さ れていないかどうかを石忍します。具イ勺には、インター フェイス名と宛先アドレスか共通なデータの有無を調べま す。 PORT_SA(dstaddr) sp—>s—port ; for ()p = neighbors ; np ! = NULL ; np = np->n—next) if (memcmp (sdl—>sdl—data, np—>n—name , sdl—>sdl—nlen) IPADDR_SA (np->n_addr) = = - IPADDR_SA (dstaddr) ) break; if ()p ! = NULL) continue ; 共通のデータがあれは新たに登録する必要はないため、 次のデータの処理に移ります。前の条件が成立しない、つ まりこの段階で np が NULL の場合には、 for ループを すべて回ったことになり、データがなかったことが分かり ます。この場合には、新たに neighbors リストに追加す るデータを蒲してこのリストのう頁に加えておきます。 ewhod かなり昔のことですが、拡彊阪の rwhod として ewhod というプログラムが充行しました。当時はまだパソコンで UNIX を動作させるのは難しく、現在のものとくらべて はるかに非力なワークステーションを使っていました。な かでもディスクレス・ワークステーションと呼ばれるハ ドディスクをもたないワークステーションでは、ネット ワーク経由で別の言算機のディスクにアクセスするイ督はみ になっていました。ディスクレス・ワークステーション で rwhod を動作させると、、、ネットワークから受け取っ たバケットをディスクに書き込むために、さらにネット ワーク経由でデータを送る " というもったいない処理がお こなわれていました。 この点に注目した ewhod の作者は、わざわざネット ワークを経由して送らなくても、ネットワーク上の 1 カ 所にデータを集めてそれを NFS などて記布すればよいと 考え、さらに異なるネットワークからもデータを収集でき るような言にしました。そのため、 rwhod のように情 報を送りながら集めるのではなく、情報を送り出す竹璞だ けをおこなったり、ネットワークを越えて通信するための 74 機能が追加されています。 時代は変わり、ディスクレス・ワークステーションな どはとんどみかけなくなった現在においても、異なるネッ トワークから情報を収集する目的で ewhod を利用した い人がいるようです。ところが、 こで問題か生じます。 ewhod を使うとうまく重川信しない言 t 算機があるのです。 これは、ホストバイトカ卸亨の問題です。 whod データベ ースを作成する言 t 算機と、それを利用する計算機とでホス トバイト順序が異なる場合に問題カ起こります。 whod デ ータベースは、ホストバイト順序で値か書かれています。 もちろん ewhod の場合にも、データベースの内容はホス トバイト順序て書かれています。これを異なるホストバイ ト順序の言算機か利用しようとすれは、正しく読めないの は当り前です。 これを解決するには、たとえばデータベースを作成する ewhod が、さまざまなバイト順序の計算機のために複数 のデータベース・ディレクトリを作成するなどのガ去か考 えられます。もちろん、 rwhod の仕組みを根本から考え なおすこともできるでしようが、既存の rwho や ruptime など、すべてのコマンドを明冓築するのは名案とはいえま せん。皆さんならどのように劇長しますか ? ☆ 今回は、前号でとりあげた rwho や ruptime か利用 する whod データベースを作成するためのコマンドとし て、 rwhod デーモンを紹介しました。 rwhod は、プロー ドキャストを使うために UDP を利用します。 UDP を利 用するプログラムを紹介するのは今回か初めてですが、理 解していただけたでしようか。 connect システムコールな どで接続を確立するのではなく、メッセージを書き出すた びにどこに送るかを指定し、読み込む際にもどこから送ら れたかの情報を受け取りながら重川します。 一部の人にはひどく忌み嫌われているプロードキャスト ですが、うまく使えばおもしろいこともできます。一度使 ってみてはいかがでしようか。 ( たしみ・ひさかす ) UNIX MAGAZINE 2001.8

9. UNIX MAGAZINE 2001年8月号

特集リ N ー X の基礎知識 0 そう、先日入れ替えたはかりの /bin/sh が原因でした。 / b ⅲ / s ンヾッチを当てたとき、共有ライプラリ (shared library) を使うようにコンパイルしてしまったのでした。 プート時には共有ライプラリが入っている /usr/lib がマ ウントされていないため、 /bin/sh の実行に失敗するわけ です。 UNIX にも共有ライプラリか導入され、コンパイル後 の実行プログラムのサイズが、従来のスタティック・リ ンクされた実行プログラムと上鄙交してかなり小さくなりま した。現在では、どの UNIX システムも共有ライプラリ の機能をもっていますが、 10 年はど前に SunOS 4.0 で 初めて導入されたときには、「あ、共有ライプラリ使うた ら、こんなに小さくなるんや」と感動したものでした。し かし、この作業をしたころには共有ライプラリも当り前に なっていたため、はとんど無意識に使っていたわけです。 山も丘でこそ、こういった失敗はあまりみかけなくなりま したが、以前はしはしば発生しました。 現在の UNIX のリリースでは、プート時に使われる /bin/sh などの実行ファイルについては、—static オフ ションを付けてコンパイルするように MakefiIe にも言当 されています。プート時に、共有ライプラリカ鉢リ用可能と いう前提を置いてはいけません。プート時に使われるコマ ンドの多くは、 /bin や /sbin ディレクトリに置かれてい ます。これらの実行ファイルを file コマンドで調べてみ ると、 sh: ELF 32-bit LSB executable, lntel 80386 , version 1 (SYSV) , statically linked, stripped のように表示されます ( これは NetBSD での例です ) 。 れから、共有ライプラリを使わす、静的にリンクされてい ることカ吩かります。 システムの運用に密接にかかわる重要なコマンドやファ イルを入れ替えるときは、細心の注意が必要になります。 しかし、それ以上にシステムがどのような手順て起動さ その過程でどういったコマンドが使われているかを 正し 0 早しておかねばなりません。これがきちんと頭に 入っていれは、上で述べたような失敗は防げたはすです。 この失敗とよく似たことは、環竟変数 LD-LIBRARY- PATH や / etc / ld. c 。 nf の設定を間違えたときにも発生し 56 ます。つまり、どの共有ライプラリを使うかを指定する環 境変数や設定ファイルを書き間違えると、共有ライプラリ を使うコマンドがうまく動かなくなることがしはしばあり ます。共有ライプラリはたしかに便利な機能ですが、その 設定にもとづくトラブルカ起きると、原因をみつけにくい ので注意しましよう。 システム・クラッシュ ! システム・クラッシュはよく発生するトラブルの 1 つ です。たいていはそのままリプートし、 fsck の実行に日判日 はかかるものの、システムが復旧していきます。しかし、 ときには大変なことになる場合もあります。 兄 それは、ある日突然やってきたのでした。 「あディスクか変な音、たててるで」 しばらくすると、コンソールー E にディスクエラーを示す メッセージか次々に現れ、システムがクラッシュしてし まいました。 「あーあ、やつばりディスクがあかんのかなあ」 リプートすると、 fsck で山のようなエラーが出てきま す。どうやら、完全にクラッシュしてしまったようです。 困ったなあと思いながらシステムを停止させ、再度プート させても状況に変わりはありません。挙句の果てに、ディ スクのハードウェア・エラーによってまったくアクセス できなくなってしまいました。 これは最悪の事態です。ディスクは完全におだふつで す。そこで、ディスクを取り出し、はは 1 司し容量の別のデ イスクを入れてシステムの復旧作業にとりかかりました。 こんなケースはあまりないのですが、仕方がありません。 OS を再インストールし、システムのノヾックアップとして 作っておいた CD-R をドライプに入システムを復活 させようとしました。 「バックアッフ。があるから、安じ、、安じ、」 ところが・ 「げげ、 CD-R か読まれへん ! 」 なんと、バックアッフ用の CD-R か第売めないのです。 これではバックアップではなく、たんなる虹色の円盤で UNIX 'MAGAZINE 2001.8

10. UNIX MAGAZINE 2001年8月号

C ⑦開 lmage Communication ・プリンター設定機能を必要に応じて 無効にでき、トラカレを低減。 ・メンテナンス業務を必要最小限に とどめる。 ・サーバーとプリンターの連携で、 新システムへのリクエスト 特定ネットワークからの出力のみの 大量の放置出力を減らすこと。 許可が可能。 プリンター用紙消費量を低減すること。 安定して運用できること。 結果的に TCO 削減に寄与すること。 Ridoc IO Gate のシステムは、学生の端末 からプリンターに出力指示が出された場合、 事務的な目標は TCO 削減ではあります 管理サーバーを経由することで印刷データ が、現場の目標は何より、学生の印刷コス を収集。さらに、プリンターの HD にログファ ト意識の向上。プリンター周辺に放置され イルを蓄積、管理サーバーで自動的にログ ている大量の出力用紙をなくすことです。 を収集し、ユーザーごとに集計します。ュー まずは、無駄な印刷を行わないよう学生 ザーごとに設定された印刷制限枚数を超 に呼びかけることや、一枚の用紙に複数の えたユーザーが印刷を行うと、出力を制限 ページを印刷する方法を紹介するなどの対 され、これらログデータを Web で公開。制 策を練ってはみたものの、目立つ効果は得 限ユーザーには自動的に告知されます。 られませんでした。やはり、技術的な対策 システム条件など通常必要としないプリ を施す必要性に迫られました。 ンターの操作パネルのキーを無効化し、学 新システム導入の際、リコーに注目したの 生による誤操作を減らし、そのことによるト は、印刷枚数の管理や、パネル誤操作対 ラブル対応の手間がなくなります。 IP アドレ 策など、必要だと考えていた機能がセットに スのアクセスコントロールマスク採用で他の なっていたところです。その他細かなニーズ ネットワークや端末からの印刷出力を制限。 にも即時に応える柔軟な対応性も導入の 印刷データにプロテクト情報を加えることに 決め手となりました。 よって、データの正当性をチェックし、不正 な印刷データを排除します。 新しいプリント管理システム導入の結果、 出力量は導入前に 比べ、年間約 3 割 も低減が見込ま れ、懸案のプリン ター周辺の放置印 刷物もかなり解消 されました。 新しいプリント出力管理 システムへの期待。 対応機器システム Ridoc Gate ( リドックアイオーケイト ) 教育部門用プリント管理システム ・ UNIX 、 Windows クライアント対応。 ・印刷ログテータ収集と出力制限が可能。 ・プリンターごとの出力制限機能、出力可能なプ リンターの制限機能。 ・ユーザーグループ / プリンターグループごとの出 カ制限機能。 ・操作パネルのアクセス制限、特定ネットワーク 以外からのアクセスの制限などを容易に可能。 ーズに応える豊富なオプション設定。 [ 基本バッケージ標準価格 : 1 , 000 , 000 円 ] IPSiO NX810 高速ネットワークプリンター ・ネットワーク対応のハイ / ヾフォーマンスレーザープリ ンター ・ 32 枚 / 分の高速出力を 実現。 ・コンパクトサイズながら両 面印刷、フィニッシャーなど の高生産性を実現。 [ 標準価格 : 268 , 000 円 ] IPSiO NX910 超高速ネットワークプリンター ・ 45 枚 / 分の超高速出力 を実現したレーザープリン ・・仕分け、ステープルなど の後処理を効率化する豊 富なオプションを用意。 ・両面印刷をはじめとする 高機能を実現。 [ 標準価格 : 498 , 000 円 ] 高まる学生のコスト意識。 放置は減り、 出力量も 3 割減に。 RidocIO Gate 導入効果 ・使用量を超えたユーサーの出力を 半自動的に制限。 ・詳細な出力ログを容易に収集・管理 できる。 IPSiO 00 000 A3 カラーレーサープリンター ・ 28 枚 / 分の超高速フル カラー出力を実現。 ・カラー出力のコストを従 来のモノクロプリンターなみ に低減。 ・後処理機能や多彩な給 紙システムを必要に応じて 選択可能。 ・リアル 1 , 200dpi の高画 質出力を実現。 [ 標準価格 : 588 , 000 円 ] ※表示価格は消費税別、搬入・設置料別途です , RidocIO Gate 導入図ー東海大学湘南キャンヾス Client 印刷 Server 管理 Server P. C P. C Printer 刷Ⅳ Client P. C P. C P. C 印刷 Server リコーホームページ http: ″ www.ricoh.co.jp/ 株式会社リコープリンタシステム販売推進室 神奈川県横浜市港北区新横浜 3-2-3 Tel. 045-477 ・ 1385 Printer Client ※ Windows は米国 Microsoft Co 「 po 「 ation の米国およびその他の国における登録商標です。※会社名および商品名は各社の商標または登録商標です。 Open BIocks プレゼント。 詳しくは http://www.ricoh.co.jp/lPSiO PR リュ -