Z手帖

2007-12-23

移転のお知らせ 22:35

最近まったく更新していないのになんですが、自分でブログをいろいろカスタマイズしてみるのも面白そうかなと思い、自分の環境に移転することにしました。飽きたら戻ってくるかもしれませんが…

そんなわけで、今後の更新は以下のサイトで行っています。

http://blog.nicetrip.org/

よろしくお願いします。

katakata 2009/06/29 14:45 OpenVZの記事、参考にさせていただいております。
新しいサイト http://blog.nicetrip.org/ ですが、DBが停止しているのではないでしょうか? OpenVZ+Unionfsの記事を拝見したいのですがここ数日アクセスするとDBエラーが出力されています。
復旧を楽しみにしています。

2007-09-28

[]ミャンマーについて 18:17

9月に二週間ほどミャンマーという国に行ってきました。このブログの内容にそぐいませんが、ニュースでついに流血の事態が報じられており個人的にとても悲しいので、旅行したときに私が持った印象を簡単に箇条書きにしておきます。読み捨ててください。でも、少しでもあの国に興味を持ってくださる方がいればうれしく思います。

  • マンダレーヤンゴンイギリス植民地の面影(碁盤目状に整備された道路・ビクトリア調の建物)を残しており、その下の喧騒の様子が南インドの都市にそっくりだった。
  • ヤンゴンにはインド系が多いように感じた。歴史的な経緯があるらしい。
  • でも華僑もいっぱい。
  • 噛みタバコ文化圏。歩道の隅は真っ赤っ赤。
  • バガン遺跡に行ったが、個人的に遺跡は飽きが早い。
  • 遺跡がいまだ信仰の場になっているのは、あまり日本にない感覚だと思う。
  • ファッションの流行は(日本より当然遅れているが)どこでも一緒だなと思った。
  • インターネットは日本とアメリカへの直接の通信は遮断されていた。ただし、ドイツには制限がされていないので、プロキシ経由で実質的に何でも見れる。
  • 僧がネットしてるらしい。
  • 日本語学校が流行っているらしい(遊びに行きました)。
  • ツーリストはその国が観光地化しているとツーリストずれしていると嫌がり、ツーリストの施設がまったくないとそんなところにはそもそも行かない。
  • ミャンマーでもサッカーは大人気。サイカーのにいちゃんでもマンUやチェルシーの選手を全部知ってた。サッカーはワールドワイドなスポーツだと再確認した。
  • 村でも衛星のアンテナを持っている家が必ずあって、そこから海外の情報を仕入れているらしい。NHKやリビアなんとか放送とかも設定すれば見れた。
  • コンピュータの学校を卒業したという女の子(ニュースに出てくるシュエダゴン・パゴダの受付をしていました)はLinuxとかjavaとか知ってた!

f:id:zeemore:20070827090939j:image:smallf:id:zeemore:20070830104149j:image:smallf:id:zeemore:20070831102204j:image:smallf:id:zeemore:20070904101003j:image:small

ただ旅行しているだけだとミャンマーはとても平和に見えます(私がそうでした)。旅行人の特集を見ると、意外な影の部分がわかって面白いです。

旅行人156号ビルマ東西南北ミャンマーへの旅

2007-08-18

[][]malloc(1) 00:43

第1章から第4章まではUNIXの基礎知識、Cの基礎知識やソースの概要なので、第5章から読み進めていくことにします。

まず、straceをしているときに見かけたことがある気がするmallocとmfreeです。メモリの取得や開放のための関数です。

いきなり疑問点がひとつ。p297に「coremapとswapmapのそれぞれは、2515行で宣言されているmap型の構造体の配列である」と書かれてあるのですが、どこにその宣言がされているのか分かりませんでした。

203 :    int coremap[CMAPSIZ];
204 :    int swapmap[SMAPSIZ];

2515:    struct map
2516:    {
2517:        char *m_size;
2518:        char *m_addr;
2519:    }

intの配列が宣言されていることは分かるんですけど…とりあえず、どこかでmap構造体の配列であることが宣言されていることを前提として読み進めるとします。map構造体は、アドレスのサイズ(charポインタ)とアドレスの始点(charポインタ)を要素としているようです。要素にはアドレスの終点はないようです。サイズと始点があれば計算できるものなので、余計なデータでメモリを消費しないということでしょうか。

さて、malloc関数のソースは以下の通り。

2528:    malloc(mp, size)
2529:    struct map *mp;
2530:    {
2531:       register int a;
2532:       resister struct map *bp;
2533:
2534:       for (bp =mp; bp->m_size; bp++){
2535:           if(bp->m_size >= size){
2536:                a = bp->m_addr;
2537:                bp->m_addr =+ size;
2538:                if ((bp->m_size =- size) == 0)
2539:                    do {
2540:                       bp++;
2541:                       (bp-1)->m_addr = bp->m_addr;
2542:                    } while((bp-1)->m_size = bp->m_size);
2543:                return(a);
2544:           }     
2545:       }
2546        return(0);
2547    }

想像よりも遥かに短いです。

2528:    malloc(mp, size)
2529:    struct map *mp;
2530:    {
...
2547:    }

さっそく見慣れない書き方がでてきました。古い文法なのかなと調べてみたところ、第2章のp271に解説されていました。なんとなく想像できるように、関数の第1引数のmpがmap構造体へのポインタであることを宣言しているということのようです。宣言されていないsizeは「デフォルトとして整数であるとみなされる」ということらしいです。

2534行からはmallocの第2引数に渡されたsizeに十分なメモリをmap構造体の配列から取り除くという処理(リソースマップの管理)をしています。

2534:       for (bp =mp; bp->m_size; bp++){

条件判定部の「 bp->m_size」は「 bp->m_size > 0」という意味らしいです。そして、ゼロサイズのエントリは最後の要素(見張りのエントリ)として存在しているようです。要するにエントリの最後まできたら、リソースマップに適当なエントリがないということで偽になって、

2546        return(0);

を返すようです。

2535:           if(bp->m_size >= size){
2536:                a = bp->m_addr;
2537:                bp->m_addr =+ size;
2538:                if ((bp->m_size =- size) == 0)
2539:                    do {
2540:                       bp++;
2541:                       (bp-1)->m_addr = bp->m_addr;
2542:                    } while((bp-1)->m_size = bp->m_size);
2543:                return(a);
2544:                }     
2545:            }

ここはそのまま読み進めるとつらいので、具体的な例を挙げながら読んでいくことにします。次のようなエントリを持ったリソースマップがあるとします。

エントリ サイズ アドレス
0          10       20
1          15       50
2           5       80

  • 例1 サイズが5のリクエストを受け取ったとき

エントリ0から検査していった場合、エントリ0のサイズ(10)は求めるサイズ(5)以上ですので、2535行目のif文は真になります。if文内ではaにエントリ0の始点のアドレス(20)を代入して(2536行目)、エントリ0の始点のアドレス(20)に求めるサイズ(5)を足します(2537行目)。さらにエントリのサイズ(10)から求めるサイズ(5)を引けば(2538行目)、以下のようになります。

エントリ サイズ アドレス
0           5       25
1          15       50
2           5       80

エントリ0のサイズが0になったときに2538行目のif文が真になってdo〜while文の処理を行いますが、ここでは偽なので2543行目で変更前のエントリ0の始点のアドレス(20)をreturnします。

  • 例2 サイズが10のリクエストを受け取ったとき

2538行目までは例1と同じです。

エントリ サイズ アドレス
0           0       30
1          15       50
2           5       80

ここでエントリ0のサイズが0になりますので、2538行目のif文が真になります。do〜while文ではリソースマップのエントリを繰り下げています。結果以下のようになります。

エントリ サイズ アドレス
0          15       50
1           5       80

ところで、2542行目のwhileの条件文は「==」で比較しているのではなく、「=」で代入しているだけなんですね。

2542:                    } while((bp-1)->m_size = bp->m_size);

どうやらbpがmap構造体へのポインタを示さなくなったときにこの条件文は偽になるようです。

[]Lions' Commentary on UNIX 00:16

最近C言語をまた少しずつ勉強しはじめてます。

インターネットの仕事をしていると、普段お世話になっているLinuxカーネルやら Apacheやらが動いている仕組みについてどうしても興味を持ってしまいます。そのソースは大概Cで書かれているのですが、私はCの理解が浅いのでなかなか手をつけることができませんでした。でもいつまでもそんなこと言ってられないので、興味ある題材で地道に勉強していこうかなと思って「Lions’ Commentary on UNIX (Ascii books)」を読んでいくことにしました。初期のシンプルなUNIXカーネルのソースの解説書です。

この本で扱っているカーネルと比較すると現在のLinuxカーネルは遥かに膨大らしいので、この本を読んだからといってLinuxカーネルをハックできるようになるわけではないと思うのですが、千里の道も一歩からということで。とりあえず今のレベルは「独習C」を一年前に一通り読んで、ポインタがよくわからないので「C言語ポインタ完全制覇 (標準プログラマーズライブラリ)」を途中まで読んでいるというところです。

2007-07-19

[]OpenVZの使い道 21:23

OpenVZのようなパーティショニングの技術はどういった場面に役に立つのだろう、とちょっと考えてみました。


まず、HSP各社がサービスしているようなホスティングサービスが思い浮かびます。VEのroot権限を直で渡してVPS・VDSと呼ばれるサービスをするのもよし、その上にいろいろアプリケーションをのせて共用ホスティングとして提供するのもよし。ただこれは安直すぎるので、他に使える場面を考えてみます。


OpenVZの高機能なリソース制限機能を使うなら、アプリケーションサーバをVE内に閉じ込める、というのは結構いい案だと思います。設定が適切ならVE内でいくら暴れてもHNはへっちゃらなので、高負荷でサーバが重すぎてsshログインしても何もできずにリブート、ということがなくなるかもしれません。1台のサーバで複数サービスを提供しているなら、1アプリケーションごとVE内に閉じ込めてしまえば、特定のアプリケーションの暴走のあおりを他のサービスがうけることはありません。こちらのサイトでも同じことを指摘してらっしゃいます。


あと、ライブマイグレーション機能がHAに役立たないのかなあ、とも思います。

もちろんサーバの突然死はロードバランサに任せておくしかないとして、ハード交換やハードの更新の場面ではVZカーネルインストールしているサーバでライブマイグレーションすれば、サーバに入っていたデータもしっかり移行できます。まあ、しっかり構築済みのサーバと入れ替えればいいことですし、ロードバランサにぶら下げているノードに大事なデータをおいておくこともあまりないかもしれませんが、オプションとして持っておけばちょっと役立つこともあるかと思います。


高い収容率を考えると、社内の検証用サーバや研修用に役立ちます。これが一番手軽な利用方法ですかね。OSの仮想化なので、カーネルファイルシステムの検証などコアなことはできませんが、Webアプリケーションの開発とかアプリケーションの動作確認とかには十分使えます。VEの再構築も一瞬で終わります。

2007-07-04

[][]Puppetを導入してみました 11:09

仕事でサーバの初期構築や運用方法を見直す機会があったので、Puppetというシステム自動管理ツールを導入してみました。

これまでのシステム管理というと、初期構築時はサービス・サーバごとに構築用スクリプトを作成し、運用時に設定ファイルの変更があればexpectの使い捨てスクリプトで全サーバに設定を反映させていました。

この方法では初期構築スクリプトがサービスごとにばらばらで担当者が代わったときに解読が困難だったり、設定ファイルの変更を初期構築に反映していなかったりと、メンテナンスに難がありました。


Puppetを一ヶ月使用してみた感想を以下に箇条書きにしてみます。マニュアルを精読してないので、勘違いがたくさんありそうですが…

  • tagが便利
  • puppetrunが便利。
  • puppetdを特定のIPにbindできない?(0.0.0.0でListenしてしまう)
  • Componentsにエイリアスが使えないような気がする。
  • Componetnsに依存関係を持たせられないような気がする。
  • Rubyで書かれていることをよく耳にするけど、フレームワークを直接いじることがなければあまり関係ない。定義ファイル(Resource)はPuppet文法で記述する。facterを使うときはRubyで記述する。
  • Resourceのpackageを使ってrpmインストールするとき依存関係がめんどくさい。いらないパッケージをアンインストールするときもめんどくさい。
  • Resourceのpackageでproviderにyumを指定してアンインストールするときに依存関係にあるパッケージをアンインストールしてくれない。(おそらく意図しないパッケージをアンインストールしないためにこう実装されているのだと思うが初期構築するときにめんどくさいので、結局execに頼ってしまう)
  • 確かにひとつひとつのResourceは簡潔にかけるが、定義ファイルの依存関係が複雑化していってしまう。ドキュメントは必要そう。

つらつらと不満点も書きましたが、タグ機能は非常に便利なので活用しています。

タグは主に初期構築用のsetupと運用用maintenanceの2種類を用意して、運用上変更が生じそうなResourceにはこれら2種類のタグをつけています。実際に変更することになったら、maintenanceのタグを使ってpuppetrunします。このResourceにはsetupタグもついていますので、初期構築にも反映されます。これで「設定変更を初期構築スクリプトに反映してなかったので、今運用しているサーバとは設定が異なるサーバができちゃったよ!」ということはなくなると思います。


Puppetについての情報は以下のサイトにまとまっています。

http://gihyo.jp/admin/serial/01/puppet/0001

http://trac.mizzy.org/puppet

匿名希望匿名希望 2007/09/12 16:24 >puppetdを特定のIPにbindできない

puppet.confに bindaddress を書けばいいのではないかと...?

zeemorezeemore 2007/09/28 17:37 ご指摘ありがとうございます。ちゃんとマニュアルを読んでませんでした…