2015年10月19日月曜日

移行しました

Github pagesに移行してみました。
https://kjmkznr.github.io/

2014年12月7日日曜日

Apacheモジュールのアップデート時にrestartは必要か

Apacheのモジュールをアップデートしたときに通常は再起動を行っていますが、そもそも再起動が必要なのか、gracefulだけで大丈夫だったりしないかということを調べてみました。

Apacheのモジュールロードのタイミング

モジュールをロードするコードはこのあたりだろうか。

https://github.com/apache/httpd/blob/2.4.10/modules/core/mod_so.c
https://github.com/apache/httpd/blob/2.4.10/modules/core/mod_so.c

Apache からは APR の apr_dso_load() を使っているみたいなので、APRの方を覗いてみる。
https://github.com/apache/apr/blob/1.5.1/dso/unix/dso.c

複数のOSをサポートするために #ifdef が多用されててちょっと見にくいが、Linux環境であれば dlopen() が使用されるようだ。

さて、dlopen() が使用されるということが分かったので、呼び出し元に戻る。
最初に提示したコードは load_module() の中に記述されている。
これはどこからコールされているのかというと、同じ mod_so.c の中にある。



AP_INIT_TAKE2は引数を二つもつディレクティブで、
RSRC_CONFは, の外に記述するという意味のようです。
最後の EXEC_ON_READ は名前からも推測できますが、設定が読み込まれたときに実行されます。
実行するのは二つ目の引数である load_module() です。

設定が読み込まれたときに実行されると言うことは、graceful でも大丈夫な気がします。

モジュールをアップデートしてみる

graceful でも大丈夫そうということが分かったので、実際に試してみます。
mod_hello という簡単なモジュールを作ってみます。
上記のGistの mod_hello は Hello という設定がコンフィグに出てくると、第一引数の文字列をエラーログに出力するだけのものです。
インストールは apxs で行います。
$ apxs -c mod_hello.c
$ sudo apxs -i -a -n hello mod_hello.la 
httpd.conf に設定を追加します。
+LoadModule hello_module modules/mod_hello.so
+Hello world
Apache を起動します。
$ sudo apache2ctl start
 * Starting apache2 ...
[Sun Dec 07 16:11:41.528152 2014] [:notice] [pid 24998] Hello world
エラーログに "Hello world" と表示されました。
続いて、モジュールを書き換えてみます。

mod_hello.c の21行目を "Hello %s" から "Hell %s" にしてみます。
再度、モジュールをコンパイル・インストールし、graceful してみます。
$ apxs -c mod_hello.c
$ sudo apxs -i -a -n hello mod_hello.la
$ sudo apache2ctl graceful
 * Gracefully restarting apache2 ...
[Sun Dec 07 16:30:57.456100 2014] [:notice] [pid 25436] Hell world
変わりました。

結論

  • モジュールをアップデートするときは graceful で十分

参考文献

追記(2015/02/01)

mod_proxy では設定が反映されなかったりすることもあるそうで、graceful だと不十分な場合もあるようです。
共有メモリを使うようなモジュールだと古い設定がそのまま使われるとかありそうなので、モジュールの中身次第では注意が必要そうです。

2014年12月6日土曜日

Gentoo で FIDO U2F Security Keyを使う


Yubicoのオンラインストアで FIDO U2F Security Key を買ってみました。
他にもFIDO U2Fに対応しているものとしては、高機能なヤツとか小さいヤツとかあり、OpenPGPに対応していると書かれているのでちょっと惹かれましたが、入門としては一番安いヤツでいいかなと思い、これを選びました。

U2Fの使い方については「Googleの二段階認証にセキュリティキーを使う」が分かりやすいですが、Linux環境で動作させる手段は記述がありませんでしたので追加で調べました。

1. 事前準備

まず、と言ってもこれ一つだけですが、ChromiumからSecurity Keyにアクセスできるようにしなければなりません。
YubicoのSecurity Keyは hiddev で提供されます。
これへアクセス出来るように udev ルールを記述する必要があります。

https://github.com/Yubico/libu2f-host/blob/master/70-u2f.rules

udev ルールは上記のGithubに上がっています。
systemd を使用している環境であれば、これで動くらしいです。

私は Gentoo で OpenRC を使用しているので上記のルールでは動作しませんでした。


上記のようにパーミッションとグループについて設定するようにしました。
Security Keyを利用するユーザは plugdev に入っている前提です。

このルールを /etc/udev/rules.d/ に放り込めば準備完了です。

2. 使用する

Google の認証に使用してみます。

https://security.google.com/settings/security/securitykey/add

Security Keys を追加するページにChromiumでアクセスし、案内に従って操作するだけです。
問題なければ、最終的に完了ボタンが押せるようになります。
udev のルールに不備がある場合は、「次にセキュリティキーを挿入してタップしてください」というメッセージが出続けると思います。


せっかくなので Gentoo Advent Calendar 2014 の6日目に登録しました。

2014年11月9日日曜日

ISUCON4 本戦に参加してきました

先日 ISUCON4 の予選参加の件をメモしてましたが、技術的なことについてメモしてませんでした。すみません。
でも、どんなことやったかあまり覚えてないので予選の方は書かないかもしれません。

無事予選を突破することが出来、本戦に参加する資格を得ましたので、本日参戦してきました。
予選と同じメンバーで、Oops!というチーム名で参加してました。

もちろん目標は賞金狙いだったのですが、結果から言うと惨敗でした。
他のチームに負けたと言うより、運営に負けたという感じがしています。
1位2位とそれ以下という感じで、スタートラインに立てなかったようです。


最終スコア

最終的な公式スコアはそのうち isucon.net の方で公開されると思いますが、競技時間内に提出できたスコアは、最終 8,461 で最大が8,548でした。

めも

  • 07:30 起床。第一関門の起床コンテストの壁突破。
  • 08:00 出発。
  • 09:00 渋谷着。予選の時と同じくヒカリエ近くのかつやでカツ丼を食べる。
  • 09:30 ヒカリエ到着。
  • 10:00 開場。カフェスペース奥のちょっと長めの机をゲット。
  • 10:30 諸々準備が終わり、競技開始まで待ちぼうけ。
  • 10:50 サーバのIPアドレス、パスワードが書かれた封筒を貰う。
  • 11:00 競技説明。
  • 11:19 
    • 初期スコア計測。
    • 予選はPHPを選択したが、本戦では Go を選択。
    • この時点で 8,059 。
    • ただし、ローカル環境でのベンチで、公式のスコアとは違う。
    • iperf でノード間の帯域を調べてみたら 33Gbps とか出ていたので、ネットワークは余裕っしょという感じになる
  • 11:20 - 12:30 
    • 何回かベンチを走らせ、ログを集計したりした。
    • プログラムを眺めて修正すべき箇所のあたりをつけた
  • 12:30 - 13:20
    • 何をやってたんだか不明。
  • 13:20
    • 公式のスコアを計測。
    • 7,665
  • 13:20 - 15:40
    • nginx の設定とかを秘伝のたれに差し替え。
      • この辺は @2matzzz がやったはず
    • その間に動画の配信を nginx からにするようにプログラム書き換えた。
      • 元々は動画自体がRedisに突っ込まれていた
      • アップされた動画の SHA1 を求めて、Redisにハッシュを登録
      • 動画自体はファイルに書込。書き込んだファイルは nginx で公開。
      • 広告の JSON 内の URL を書き換えて、動画のURLを変更。
        • /assets/xxxx.mp4 みたいなURLにした。
    • ローカル環境スコアが20,391
  • 15:40 - 16:10
    • 3台のマシンでファイルを共有できるように NFS を構成してくれたので、そっちに動画を描き込むように修正。
    • その他 nginx を調整。
    • 動画ファイルの共有のためにRedisに登録された動画を ngx_redis を使い取り出せないかとやってみたけど、効果がなかったため止めた。
    • ローカル環境スコアが23,613
  • 17:00
    • 公式スコアを計測
    • 6,779
    • スコアが下がってしまい焦る。
  • 17:00 - 18:30
    • 今まで1台のみでベンチマークしていたが、ノードB,Cの2台構成で試したところ、レポートのあたりでFAILED
    • ログをノード間で共有してなかった
    • Redisに突っ込んだりしてみたけど、最終的にNFSに書き込むようにした。
    • スコアは2台でも変わらなかった
  • 18:30 - 18:50
    • やってることはストップして、環境の整理
    • 再起動とかを行う。
    • ログの出力を止めたりし、最終の公式スコアを測定。
  • 18:50
    • finish.txt とかを確認
    • 終了モード。

反省点

  • クライアントからのリクエストはちゃんと調べましょう。
    • 普通の環境だとブラウザにキャッシュさせるとかは普通にやるけれど、ISUCONではそのあたりをまったく考慮していなかった。
    • 過去のISUCONの問題で予習していくうちに、ISUCONの枠に囚われてしまった感がある。
  • ローカルのベンチマーク環境とリモートのベンチマーク環境の違いをよく考えよう
    • なぜリモートのベンチマークだとスコアが下がるのかをよく考えていなかった
  • 落ち着こう
    • 一つのこと(今回はGo言語のプログラムの修正)に集中しすぎた
    • チームメンバーとのコミュニケーションをもっととれば良かった
  • Gentooとかコンパイルオプションとかそういうことの前にやることはたくさんある。
    • Gentooを使うのは最終手段とすべき。
松鵜先生のチームに勝てたのは嬉しかったが五十歩百歩という感じであまり喜べないですね。

最後に、楽しいイベントを開催してくれた運営の皆様ありがとうございました。
きっとまた来年も参加させていただきます。

2014年10月11日土曜日

共有ライブラリのアップデート時にプロセスの再起動はいつ必要か

共有ライブラリのアップデート時、対象のライブラリが起動中のプロセスから利用されているかを見て、プロセスの再起動を行うかどうかの判断をしている。

例えばこんなのとかですね。
$ sudo grep libssl.so.1.0.1e /proc/*/maps | cut -d/ -f3 | sort -u | xargs -r -- ps uf
プロセスを再起動すれば、更新されたライブラリが使用されるという認識で居るのだけれど、実際にそうなのか調べたことがなかった。
ライブラリをアップデートしたときに、どのタイミングで差し変わるか気になったので調べてみた。

共有ライブラリのサンプル


プロセス再起動時

まずは、普通に再起動を行ってみる。
$ ./test
Hell World
PID is 16856
Press Any Key To Exit...
別のターミナルで maps を参照してみる。
$ grep libexample /proc/16856/maps
7fee12576000-7fee12577000 r-xp 00000000 00:0f 14844378                   /usr/local/lib64/libexample.so
7fee12577000-7fee12776000 ---p 00001000 00:0f 14844378                   /usr/local/lib64/libexample.so
7fee12776000-7fee12777000 r--p 00000000 00:0f 14844378                   /usr/local/lib64/libexample.so
7fee12777000-7fee12778000 rw-p 00001000 00:0f 14844378                   /usr/local/lib64/libexample.so
libexample.soを更新してみます。
$ ./test
Hello World
PID is 17109
Press Any Key To Exit...
$ grep libexample /proc/17109/maps
7f33b9223000-7f33b9224000 r-xp 00000000 00:0f 14844450                   /usr/local/lib64/libexample.so
7f33b9224000-7f33b9423000 ---p 00001000 00:0f 14844450                   /usr/local/lib64/libexample.so
7f33b9423000-7f33b9424000 r--p 00000000 00:0f 14844450                   /usr/local/lib64/libexample.so
7f33b9424000-7f33b9425000 rw-p 00001000 00:0f 14844450                   /usr/local/lib64/libexample.so
まあ、普通に更新されますね。

他のプロセスがライブラリをロードした状態で、更新する

プロセスAで libexample.so を使用した状態で、libexample.so を更新し、プロセスBを起動する。 そのときプロセスBは、古いライブラリと新しいライブラリのどちらを使用することになるのか。
プロセスA
$ ./test 
Hell World
PID is 17248
Press Any Key To Exit...
プロセスAは起動させたままで、ライブラリを更新する。
$ vim libexample.c
$ make
$ sudo make install
プロセスBを起動する。
$ ./test 
Hello World
PID is 17343
Press Any Key To Exit...
このとき maps は以下のようになる。
$ grep libexample /proc/*/maps 2> /dev/null
/proc/17248/maps:7f707a138000-7f707a139000 r-xp 00000000 00:0f 14844464                   /usr/local/lib64/libexample.so (deleted)
/proc/17248/maps:7f707a139000-7f707a338000 ---p 00001000 00:0f 14844464                   /usr/local/lib64/libexample.so (deleted)
/proc/17248/maps:7f707a338000-7f707a339000 r--p 00000000 00:0f 14844464                   /usr/local/lib64/libexample.so (deleted)
/proc/17248/maps:7f707a339000-7f707a33a000 rw-p 00001000 00:0f 14844464                   /usr/local/lib64/libexample.so (deleted)
/proc/17343/maps:7f9413f52000-7f9413f53000 r-xp 00000000 00:0f 14844475                   /usr/local/lib64/libexample.so
/proc/17343/maps:7f9413f53000-7f9414152000 ---p 00001000 00:0f 14844475                   /usr/local/lib64/libexample.so
/proc/17343/maps:7f9414152000-7f9414153000 r--p 00000000 00:0f 14844475                   /usr/local/lib64/libexample.so
/proc/17343/maps:7f9414153000-7f9414154000 rw-p 00001000 00:0f 14844475                   /usr/local/lib64/libexample.so
libexample.so が置き換わってるので古いのを利用しているプロセスは (deleted) がつく。

fork時

fork した子プロセスでライブラリの関数を利用するプログラムを用意します。 1秒ごとに子プロセスを生成して、その間にライブラリを更新します。
$ ./test-fork
[Parent] PID is 18271
[Parent] Hell World
[Child] Hell World
[Child] PID is 18272
[Child] Hell World
[Child] PID is 18273
[Child] Hell World
[Child] PID is 18274

プログラムは起動したまま、ここでライブラリを差し替え。
$ vim libexample.c
$ make
$ sudo make install
プログラムの出力を見てみると、
[Child] Hell World
[Child] PID is 18276
[Child] Hell World
[Child] PID is 18277
[Child] Hell World
[Child] PID is 18279
[Child] Hell World
[Child] PID is 18280
変わらず "Hell" のままですね。
細かな動作までは調べてないので推測ですが、fork() の場合は動的にリンクされたあとのメモリ空間をコピーするためではないかと思います。

まとめ

  • 共有ライブラリをアップデートしたときはプロセスの再起動が必要
  • 子プロセスの再起動だけでは不足
  • 同じ共有ライブラリを他のプロセスで利用していたとしても、新しく起動したプロセスでは更新後の共有ライブラリが利用される

備考

今回は試してないですが、Dynamic Loadingというライブラリを動的にロードする方式がありこの場合どのような動作になるのかが気になります。
恐らく dlopen/dlclose で開き直せば新しいライブラリがロードされるのではないかと思いますが..
Dynamic Loading は恐らく Apache のモジュールのロードで利用されてるはずです。
nginx ではビルド時に組み込むはずなので、Dynamic Loading ではないはず。

2014年9月28日日曜日

ISUCON4 オンライン予選に参加してきた

ISUCON4のオンライン予選をLINEカフェにお邪魔させて頂きながらやってました。
細かくメモってないから、覚えてる範囲で日記にしておく。

メンバーは専門学校時代の同級生とその同僚で3人。
言語はPHPを選択しました。


  • 08:50 渋谷到着。普段出勤するより早い。
  • 09:00 近くのかつやでカツ丼ミニを食す。
  • 09:20 ヒカリエ11Fに着。ローソンで昼飯飲み物を購入。
  • 09:30 LINEカフェに突入。
  • 10:00 予選開始。bitbucket のリポジトリにコードなどをつっこむ。
  • 10:50 PHP などの初期設定など、もろもろ雑作業を終えて最初のベンチマーク(スコア: 1,646)
  • 11:18 スコア 3,297
  • 11:49 スコア 3,252
  • 12:36 スコア 2,460
  • 13:36 スコア 2,507
  • 13:51 スコア 24,397
  • 14:25 スコア 28,160
  • 14:42 スコア 28,785
  • 15:10 スコア 39,377 この時点で5位。このスコア以降はプログラムを大幅に書き換えようとして制限時間内に終わらず。

最終的に暫定10位以内に入ることは出来なかった。無念。
ami 提出のため、楽天カフェに移動し反省会。
再起動したら 46,274 までスコアが上がった。無念。

今回の反省点。

  • プログラムの大幅な書き換えと平行して、そのままのコードでチューニングしていく人がいるべきだった。
  • SQL力が足りなく、コード内のSQLが何をやっているのかを把握し切れていなかった
この2点が大きいと思った。

技術的な点はそのうちひっそりと追記します。

2014年7月18日金曜日

今まで行ったねこカフェめも 2014年7月版

今までに行ったことがある猫カフェのメモ。

ねこのみせ

URL: http://www.nya-n.jp/
場所: 町田

まずはここ。
関東で一番古くから営業しているお店。
家から一番近いところなので、よくいく。
お店はそれほど広いわけではないけれど、マンガがたくさん置いてある。

初めて行ったのは Twitter によると

行った日メモ

  • 2009年08月17日

ねこっ茶

URL: http://necoccha.com/
場所: 横浜

普通の家みたいなところでした。
和室と洋室があり。

以前の職場が横浜だったのですが、このお店とは駅を挟んで逆側だったので結局一度しか行かず。
駅からもちょっと歩いたところにある。
ねこはもちろん可愛かった。


行った日メモ
  • 2010年06月09日











行った日メモ
  • 2011年04月27日


















Cat Magic

URL: なし
場所: 新宿3丁目

残念ながら閉店してしまったようです。
閉店したからなのか Twitter アカウントがいつのまにか、猫カフェのことじゃなく出会い系のことばかりつぶやくようになっていたので、あまり良い印象はない。

猫は人なつっこかったです。


行った日メモ
  • 2011年05月30日



















ハビ猫

URL: http://hapineko.com/
場所: 渋谷

渋谷のそれなりに良い場所にあるが、自分が行ったときはカップルが一組いた程度だった。
ここは入店時に荷物を預けなければならなず、めんどくさかった。
ロッカーにして欲しいところ。


行った日メモ
  • 2013年08月13日

Cat Cafe Nyanny

URL: http://www.猫カフェ.tokyo.jp/
場所: 秋葉原

秋葉原にあるもう一店。
そんなに広くはないが、2フロアあり1フロアは和室らしい。
自分が行ったときは和室のフロアには足を運ばなかった。

秋葉原に行ったときはここか Jalala で休憩したい。





















2014年7月7日月曜日

Gentoo勉強会 2014年7月に参加してきた

6月に引き続き、7月5日に開催された勉強会に参加してきました。
実はGentoo勉強会のことをすっかり忘れていて、前日に松鵜さんに言われて思い出して参加申し込みをしたのでした。
あと、www.gentoo.gr.jp に掲載しているニュースも当日に Pull Req をするという感じで、次回はちゃんと事前にニュースを載せたいなと思ってます。忘れてたらすいません。

場所はいつもと同じく Miracle Linux さんの会議室。


今回の参加者はメモによると合計11名。

以下メモ。

自己紹介

特にメモはない。
+Takuto Matsuu さんが Gentoo ステッカーを配ってくれました。




最近の Gentoo 事情(@aliceinwire)

EAPI 6のことをいくつか。




Dockerでテストする(@naota344)

  • (プレゼントは関係ないけど)新しいマシンにしたらしい
    • ついでに systemd 使ってみたらちょー起動速いとのこと
  • ebuild 書いた後、ちゃんとテストしてますか?
    • repoman は ebuild の静的なチェック。
    • 書式とか DEPEND とか。
    • あとは実際に build してみるくらい。
  • CFLAGS に -frecord-gcc-switches を入れると、バイナリに CFLAGS の内容が記録されて portage が後で正しく適用されているかチェックしてくれるらしい
  • ld.gold を使えば under-linking が防げる
    • under-linking というのは A -> libB -> libC という依存状態の時に A -> libC がリンクされていない状態。
    • A から見ると libC はあってもなくても良いように見えるけど、libB が依存してるので、削除すると A も動かなくなる。
  • ここから本題の Docker.
  • Docker とはなにか
    • 昨日の Docker meeting に行って下さい。
  • https://github.com/naota/dockergentoo を clone して使ってね
  • 資料はコレらしい。

 emerge できない時、どうする?(https://twitter.com/grauwoelfchen)



一度休憩

きのことたけのこや抹茶わらび餅、おまんじゅうなど。
持ってきて下さった方、ありがとうございます。
ちなみに、たけのこ派です。

metro(@kjm)

自分の発表です。
どなたかの発表が入っていたのですが、キャンセルされていたので入れてしまいました。

自分でも理解し切れていないことが多く、うまく説明できませんでした。
半分くらい Funtoo の話題になってしまった気がします。
Funtoo は drobbins 氏がホスティングサービスを提供していて(今は休止中かも?)、契約すると drobbins 氏のサポートが付いてくると言う特典があります。

一応資料はこちらにアップしております。


Gentoo Linux LDAP Authentication(@mazgi)


  • Gentoo Linux で LDAP Authentication 環境を構築
  • 主に Gentoo Wiki を参考にしたとのこと
  • 実際に構築した環境のでもを見せてくれました
  • 最近は SSSD というものを使うのが普通らしい
    • System Security Service Daemon
    • ある程度認証情報をキャッシュしてくれるらしい

 TravisでGentooのRepomanコマンド(@aliceinwire)




という感じで今回はおしまい。
懇親会にも参加したけど、イイ感じの写真が撮れなかった。
さくら水産で撮影だと素人には難しすぎるようです。


2014年6月11日水曜日

Gentoo勉強会#3 に参加してきた

2014年06月07日(土)に Miracle Linux さまの一室をお借りして開催していた Gentoo 勉強会#3 に参加してきた。

午前中に会社のビルが電気点検のため停電になっており、一部のサーバが Kernel の設定ミスにより正常に起動しなかった。その対応を行った関係で40分ほど遅刻してしまった
タイミングが悪く、入り口で10分ほど待ちぼうけになってしまった。

今回は2回目の勉強会より多い合計15名の参加者でした。
前回はちょっとGWの終わりで時期が悪かったね。

プレゼンメモ

今回も簡単に箇条書きで。

自己紹介

  • 残念ながら遅刻により不明

最近の Gentoo 事情(@aliceinwire)

  • 残念ながら遅刻により不明

Gentooステッカーの進捗について(@matsuu)

  • 前回の勉強会で、今回までに作ってくると言っていた
  • 色々調べたら、イタリアのサイトでステッカーが売っていた
  • 2種類買った
  • 6月7日の午前中に自宅に配達に来た
    • しかし、午前中は墨田セキュリティという勉強会に行っていた
    • 今日持ってきたのは、不在票だけ
  • ステッカーはここで買った
  • Gentoo以外にもいろんなステッカーが売ってる
  • ターミナルで注文もできるよ!
その後ちゃんと届いたようです。

grub2 + EFI + btrfs使い始めた話とか(@mazgi)

  • EFI+btrfsの前に、前回発表した RaspberryPi でデジタルサイネージ的なものを作ってエクスポに持ってった話を少々。
  • 今日の発表は Qiita にメモっている
  • LVM + Filesystem を今まで使っているが、ボリュームを追加したりしたときのフラグメンテーションが気になる
    • 実際にパフォーマンスの劣化が起きるかは調べてない
  • SystemRescueCD は EFI をサポートしてる
    • tmux も入ってるし便利
    • SystemRescueCD の EFIブートの画面(grub2)と BIOS ブートの画面(syslinux) を比べると、今のところ BIOS ブートの画面の方が派手。
  • btrfs の上で swap-file が作れなくてはまった
    • (青田先生)何かのAPIをbtrfsがサポートしてないからかもしれない
    • (青田先生)CoWを切ったら、動くかも?
  • /var/log を別のサブボリュームにしているのは、gzip圧縮にしたいから
    • 他のサブボリュームは lzo
    • gzip にすることでlogrotate時の compress を不要にしたい
  • 必要な Kernel config
    • CONFIG_EFI, CONFIG_EFI_PARTITION, CONFIG_EFI_VARS を y にしておく必要在り
    • (青田先生)CONFIG_EFI_VARS が m だとうまく起動できないことがあるらしいので y にしておいた方がいい
    • (青田先生)CONFIG_EFI_STUB
      • EFIから直接 Linux Kernel をロードできるようにするもの
      • grubが不要になる
      • 複数の kernel を入れ替えるのがちょっと面倒
      • リファレンス的存在
  • (青田先生)最新の kernel じゃないと btrfs の auto-defrag と snapshot は相性が悪い


Radxa Rock(@naobsd)

  • Gentooネタじゃないけど
  • [reksa] と読むらしい
  • http://radxa.com/
  • 透明なケース付き
    • 結構壊れやすいので注意
    • 割れちゃったら、問い合わせると対応してくれるかもしれない
  • インターフェイスが豊富
  • SPDIFケーブルも売っているが、写真がどう見ても光なケーブルじゃないから買わない方がいい
  • 中国の会社
  • Tom Cubieという方が開発している
    • 以前 CubieBoard というものを開発してた人らしい
  • Wifi/Bluetoothもついてるけど、技適通ってないので注意

はじめて ebuild Patch(@aliceinwire)

  • ebuild でパッチを当てる方法
  • filesディレクトリにパッチを置いて epatch コマンドであてる
  • EAPI=2 から src_prepare() で epatch を使うことになった
  • patch は plain/text だけじゃなく xz などの圧縮形式もサポートしてる
  • ARCHごとにパッチのファイル名を生成できる
    • ??_${ARCH}_foo.${EPATCH_SUFFIX}
  • epatch は eutils.eclass に含まれている
  • epatch_user はユーザ独自のパッチを当てられる構文
    • /etc/portage/patches/category/package/*.patch
    • ebuild 内で epatch_user が実行されていたら、使える
    • 実行されてなかったら、パッチを置いても使われない
    • eclass によっては中で使われてるかも

ハッカソンタイム

  • 各自てきとーに。
  • 翻訳とか
  • 青田先生の質問コーナーとか
  • Gentoo初心者のインストールバトルとか
  • 松鵜先生のebuild作成1on1とか

こういう勉強会では Macbook の割合が非常に高くなることが多いが、今回は 50% くらいのような気がする。
他は ThinkPad だったり、その他メーカーだったりしたようだ。


DSC_4309

ULA と Src/Dest NPT を使ってみた

IPv6 では IPv4 と違い使用できるアドレスが潤沢にあるため、LAN 内でもグローバル IPv6 アドレスを使用するのが一般的です。

ただ、グローバルアドレスを付与すると接続している上位の ISP が変わったりすると、LAN 内の機器も新しいグローバルアドレスに変更しなければなりません。
また、複数の ISP に接続していたりするマルチホームな環境の場合、複数のグローバルアドレスを機器に付与するため、ソースアドレスの選択の問題が発生したりします。

そこで ULA(Unique Local Address) を LAN 内の機器に付与し、ルータ等でグローバルアドレスに変換すればアドレスが変わったときに楽にならないかなと、以前から使用したいと思ってたので、試してみました。

アドレスの変換には NPTv6(RFC6296: IPv6-to-IPv6 Network Prefix Translation) を使用します。
変換先のアドレスはプレフィックスが変わったことによりチェックサムが変わらないように計算されたアドレスに変換されます。
これによりトランスレーターの計算負荷を減少させているそうです。

IPv4 の NAT と同様にエンドポイントのアドレスが変わるので、例えば SIP や FTP などは別途対応が必要になりますが、この辺はまだ調べてません。



NPTv6の設定

Linux では Kernel に実装されています。
次のコンフィグを有効化しておきます。
CONFIG_IP6_NF_TARGET_NPT=m
ユーザランドでは netfilter で設定できます。

まずは ULA -> グローバルアドレスの変換。
変換元 fd34:fe56:7891:2f3a::/64
変換先 2001:0db8:abcd:1234::/64


$ ip6tables -t mangle -A POSTROUTING -s fd34:fe56:7891:2f3a::/64 -j SNPT --src-pfx fd34:fe56:7891:2f3a::/64 --dst-pfx 2001:db8:abcd:1234::/64

続いてグローバル -> ULA の変換
$ ip6tables -t mangle -A PREROUTING -d 2001:db8:abcd:1234::/64 -i eth1 -j DNPT --src-pfx 2001:db8:abcd:1234::/64 --dst-pfx fd34:fe56:7891:2f3a::/64
net.ipv6.conf.all.forwarding が有効になっていれば、この箱を通過するパケットのアドレスが自動変換されます。

ちなみに、iptables-1.4.21 の ip6tables-save はルールの保存部分に問題があり、正しいルールが出力されませんのでご注意下さい。

... -j DNPT--src-pfx 2001:db8:abcd:1234::/64 ...
こんなルールが出力されてしまいます..
一応バグ報告を出してみましたが、未だ受理されてないようです。
nftables の方に開発リソースを振ってるのかもしれません。使ってるユーザが少ないというのもありそうですが。

感想

宅内のネットワークで1ヶ月ほど使ってますが、FTPも利用しませんし今のところ不便はないです。
ただ、IPv4のネットワークと同じく、内部ネットワークがプライベートアドレスになってしまうため、サーバ等を NPT の内側に置いてしまっていると、外から見えるアドレスと中から見えるアドレスが異なってしまうのが面倒です。
IPv6の利点であるグローバルアドレスをたくさん使えるメリットがなくなってしまうのは、勿体ない。
しかし、DMZを置くとなると、また最初の問題に戻ってしまうという...

2014年5月16日金曜日

Gentoo勉強会#2に参加した

2014年5月11日(日)に行われた Gentoo 勉強会#2 に参加してきた。

ちゃんとメモってなかったけど、覚えていることをつらつらと書いてみる。

最初に主催の @aliceinwire さんから開会の挨拶。
その後、各自自己紹介。
参加人数は9人のはずが10人くらいいたような気がするがちゃんと数えてなかったので、実際の参加人数は分からない。

続いて有志のプレゼン。
最初は @grauwoelfchen さんの「ELOG と Ebuild Phase Hook について」の予定だったが、ここでトラブル発生。
Gentoo on MacBook(Air?)でプロジェクターを正しく認識できなかったみたい。
xrandr でプロジェクタが出てこなかったというつぶやきが聞こえた。

一旦飛ばして @mazgi さんの「ギョーム系GentooLinux 会社で使えるGentoo Linux on RPiの話をします!」でした。

ギョーム系GentooLinux 会社で使えるGentoo Linux on RPiの話をします!

はじめに Raspberry Pi をプロジェクタにつないで、GentooLinuxのブート画面が撮された。
しばらく待つと、スムーズに動画が再生された。
RaspberryPiの動画再生支援機能を利用し 720p の動画が CPU 使用率 20% くらいで再生できるらしい。
動画再生には omxplayer を使っていて /etc/local.d/xxx.start に直接シェルスクリプトを書いて自動的に再生が始まるようになってるようだ。

omxplayer は Overlay を探せば ebuild が見つかるが、古いヤツしかないらしく今回は直接コンパイルしたとのこと。

RaspberryPiの環境は AMD64 な母艦と distcc を使用しビルドしたとのこと。
コンパイル自体は distcc のおかげでそこそこ速いが、それ以外の、例えば依存性の解決などが激遅でつらかったとのこと。

あと gettext で謎の現象が起きていて解決できてなかった。
gettext --help
は問題ないが
gettext --version
だとセグフォるという。
会場でも、有用な情報は出なかった。


ELOG と Ebuild Phase Hook について

一旦アジェンダを戻って @grauwoelfchen さんの発表。
発表資料はこちら。 
結局プロジェクタを認識できずに資料を別のPCに移して発表されていた。
残念ながらデモは見れなかった。

@grauwoelfchen さんは dvorak 使いらしい。すばらしい。
StumpWM という Common Lisp な WindowManager を使っていながら vim 使いとのこと。

ELOG 機能を利用して emerge 完了時に WM へ通知を飛ばす方法を発表されていた。
採用はしなかったが似た機能として Ebuild Phase Hook についても調査されたそうです。
一部ドキュメントにも載っていないイベントが飛んでくるとか。(発表資料の20pを参照)

プレゼンのテンプレートはこれを使っているらしい。
LaTeX と言う点を除けばイイ感じ。

ちなみに @grauwoelfchen さんのブログでも Gentoo 勉強会#2についてまとめられてるので参照されたし。
grauwoelfchen.at/graffiti/gentoo-users-study-meet-up-no-2

Overlay

続いて @aliceinwire さんの発表。
シンプルなタイトルだが Portage Overlay についての発表でした。
知らなかったのだが本家の Overlay リポジトリは Bugzilla に申請すれば使えるらしい。


このあたりを参考のこと。


  • layman -L でリポジトリの一覧を見れるよ
  • @aliceinwire さんのリポジトリは a から始まるので上の方に表示されてイイネ
  • /etc/portage/package.mask に次のように書くことでOverlay丸ごとマスクできる
     */*::overlay  
    • package.unmask で欲しいものだけ unmask するのが便利
  • layman にリポジトリを登録したければ Bugzilla に書けばいいよ
  • emerge --regen を実行すると依存性のチェックがちょっと速くなるらしい

覚えているのはこれくらい。

ハッカソン?

続いてハッカソンぽいもの。ハッカソンというよりはもくもく会に近かったのかもしれない。
主に本家Wikiの翻訳について行われていた。
もっと初心者の参加者の声を拾える方法があるといいかもしれない。
  • Overlay を翻訳しようとするが、翻訳バーが表示されない
  • @matsuu さんが他のページを参考に翻訳バーを表示させようとしたが、ダメだった。
  • @matsuu さんのトークページに勝手に入れちゃダメだよというコメントが。
  • IRCで確認したら許可制とのこと。品質がいいモノのみ翻訳できるようにしているとのこと。@matsuu さんのツイート
  • 翻訳するにはアカウントに翻訳権限を付けて貰う必要がある
    • 特別ページを編集して依頼するのだが、数分程度で許可されたのでバッチ処理かと思った
    • 実際には IRC に通知が届いて a3li 氏が対応していたようだ。
自分はひっそりと GentooJP Wiki を github に移行するスクリプトを書いていた。
ぜんぜん進まなかったけど。

その他・懇親会

会場で話したのか懇親会で話したのかちゃんと覚えてないことなど。
ちなみに、本会場は Miracle Linux さんでした。
懇親会は安くて安心のさくら水産。
  • @matsuu さんは次回までにステッカーを作成する
    • .ai ファイルが開けない。
    • @mazgi さんが作れるかも
  • Tシャツもいいんじゃないかという話も出たが @naota344 さんが持ってるんじゃね?という話に。
    • そもそも、OSCで販売は NG らしい
  • 次回のOSCっていつ? 
    • Tokyo/Fall は例年10月くらいじゃないか
  • ZFS on Linux でフリーズするのに困ってる
  • btrfs はプチフリっぽいのがたまにあるけど、数年使ってて壊れたことはないよ
  • Quad Core な ARM ボードが $99
    • Gentoo いれるのや distcc にちょうどいいんじゃないか
    • http://radxa.com/
  • 懇親会中に2名ほど障害対応
  • GentooJP 用に VPS サーバ貸せるかもという情報
    • 借りるだけ借りて使わないのは勿体ないので、用途も合わせて募集しないとね
    • 現在びぎネットさんにお借りしているマシンは Xen なので、カーネルアップデート出来なくて Gentoo 的につらい。
    • 新しくサーバを借りつつ、そっちによせるのはありかもしれない
    • あと管理してくれる人も募集中だよ
  • ChromeOS は Gentoo ベースではあるけど Google 謹製の GRP (バイナリパッケージ)しかインストールできないよ
  • ChromeBook って ARM マシンだから RaspberryPi の母艦にちょうどいいんじゃないか
  • CoreOSは勝手にアップデートして再起動するからコワイ
    • 流行のいみゅーたぶるな環境だと問題ないんじゃないか
  • バックアップの話
    • 最近は duplicity がオススメ
    • rsnapshot は、世代間がハードリンクなのでどれか一つ書き換えちゃうと他の世代も書き換わるからコワイ
    • pdumpfs って最近名前聞かないね
    • bacula はOSSで一番えんたーぷらいずな機能を持ってるんじゃないかな

そういえば、せっかく一眼レフカメラを買ったのに、撮るのをすっかり忘れてた。

※ 写真は勉強会とはまったく関係ありません

2013年12月7日土曜日

ElasticSearch と Kibana で画像共有サイトのシェアを調べてみる

 Twitterを眺めてたら ElasticSearchKibana というものが流行ってるらしいので、たまたま気になっていた画像共有サイトのシェアを調べてみた。

Install ElasticSearch

まずは、ElasticSearchをインストールする。
Gentoo Linux の場合は以下のコマンドで一発。

$ sudo emerge -av  app-misc/elasticsearch

設定ファイルのサンプルが /etc/elasticsearch/ にインストールされているので、それをベースに設定する。
今回はデフォルトのまま使用した。

$ sudo cp /etc/elasticsearch/elasticsearch.yml.sample /etc/elasticsearch/elasticsearch.yml
$ sudo cp /etc/elasticsearch/logging.yml.sample /etc/elasticsearch/logging.yml

あとはサービスを起動する。

$ sudo /etc/init.d/elasticsearch start

この起動スクリプトは複数のインスタンスが起動できるようになっているようで、例えば hogehoge.yml という設定を作り /etc/init.d/elasticsearch.hogehoge という名前の起動スクリプトを作ればいいらしい。
デフォルトでは elasticsearch.yml が利用される。


Install Kibana

Kibana 自体は HTML と JavaScript で構成されているものなので、ダウンロードしてきて展開するだけである。

$ tar zxvf kibana-3.0.0milestone4.tar.gz
$ cd kibana-3.0.0milestone4
$ python3 -mhttp.server

一時的に動かすだけであれば、これで十分。

Install Twitter River

 ElasticSearch に Public streamssample をどうやって入れればいいのか調べてみたところ、 Twitter River というプラグインを使えばいいことが分かった。

$ sudo /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-river-twitter/1.4.0 
-> Installing elasticsearch/elasticsearch-river-twitter/1.4.0...
 Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-river-twitter/elasticsearch-river-twitter-1.4.0.zip...
 Downloading ....................................................................DONE
 Installed elasticsearch/elasticsearch-river-twitter/1.4.0 into /usr/share/elasticsearch/plugins/river-twitter


使い方については README を見れば判ると思う。
今回は sample を利用するので type は省略する。

$ curl -XPUT localhost:9200/_river/tweets/_meta -d '
  {
      "type" : "twitter",
      "twitter" : {
          "oauth" : {
              "consumer_key" : "**** CONSUMER KEY ****",
              "consumer_secret" : "**** CONSUMER SECRET ****",
              "access_token" : "**** ACCESS TOKEN ****",
              "access_token_secret" : "**** ACCESS SECRET TOKEN ****"
          },
          "ignore_retweet" : true
      },
      "index" : {
        "index": "tweets",
        "type": "tweet",
        "bulk_size": 100
      }
  }
  '
  {"ok":true,"_index":"_river","_type":"tweets","_id":"_meta","_version":1}

これで tweets と言う名前の index が作成され、自動的に Twitter Stream に接続してツイートを収集してくれる。
ツイートがある程度溜まるまでちょっと待ってから Kibana にアクセスしてみる。

前述の通りに Kibana をインストールしている場合は http://localhost:8000/ で表示できます。
ホーム画面の一番下に Blank Dashboard というリンクがあるのでクリックしてみます。


右下に Add Row というボタンがあるのでクリックします。


Create Row ボタンを押します。


Add Panel というボタンを押してパネルを追加します。
Panel Type は Histogram でやってみます。
Sizeは12にすると横幅がマックスになります。

Time Field はデフォルトでは @timestamp になっていて、レコードが追加された日時になるようです。
ただ、Twitter River ではそのようなフィールドはないので Tweets のフィールドである created_at に変更しておきます。


また、右上に Configure Dashboard ボタンで Dashboard の設定を変えられるのですが、そこの Timepicker の設定も created_at に変更しておきます。



そうすると、このようなグラフが表示されます。
簡単ですね。

Customize Twitter River

 さて、これでシェアを調べられると思ったのですが、Twitter Riverプラグインでは Entities の urls フィールドしか取得していないようで、media フィールド内にある pic.twitter.com の情報は取得できませんでした。
 Twitter River には raw という Tweets オブジェクトをまるまる保存するオプションがあります。これを使用すればいいだろうと思って試してみました。

$ curl -XDELETE localhost:9200/_river/tweets/
$ curl -XPUT localhost:9200/_river/tweets/_meta -d '
  {
      "type" : "twitter",
      "twitter" : {
          "oauth" : {
              "consumer_key" : "**** CONSUMER KEY ****",
              "consumer_secret" : "**** CONSUMER SECRET ****",
              "access_token" : "**** ACCESS TOKEN ****",
              "access_token_secret" : "**** ACCESS SECRET TOKEN ****"
          },
          "ignore_retweet" : true,
          "raw": true
      },
      "index" : {
        "index": "tweets",
        "type": "tweet",
        "bulk_size": 100
      }
  }
  '
  {"ok":true,"_index":"_river","_type":"tweets","_id":"_meta","_version":1}

これを試してみたところ created_at が文字列型になってしまいタイムスタンプとしての利用ができませんでした。
試しに Index の型を変更してみようとしたところエラーが出て変更できませんでした。

$ curl -XPUT localhost:9200/tweets/tweet/_mapping -d '
  {
    "tweet" : {
      "properties" : {
        "created_at" : {"type" : "date", "format": "EE MMM d HH:mm:ss Z yyyy" }
        }
      }
    }
  }' | jq .
  {
    "error":"MergeMappingException[Merge failed with failures {[mapper [created_at] of different type, current_type [string], merged_type [date]]}]",
    "status":400
  }

どうも型の変更はできないようです。
Twitter Riverプラグインはオープンソースなのでフォークして、Media内のURLのインデックスを作成するように修正してみました。

https://github.com/kjmkznr/elasticsearch-river-twitter/tree/add-media-entities

$ git clone https://github.com/kjmkznr/elasticsearch-river-twitter.git
$ cd elasticsearch-river-twitter
$ git checkout add-media-entities
$ mvn package

これで target/releases/elasticsearch-river-twitter-1.5.0-SNAPSHOT.zip というファイル名でプラグインがビルドされます。

これを ElasticSearch にインストールします。

  $ sudo /usr/share/elasticsearch/bin/plugin -remove river-twitter
  -> Removing river-twitter 
  Removed river-twitter
  $ sudo /usr/share/elasticsearch/bin/plugin -u file:/path/to/elasticsearch-river-twitter-1.5.0-SNAPSHOT.zip -i river-twitter
  -> Installing river-twitter...
  Trying file:/path/to/elasticsearch-river-twitter-1.5.0-SNAPSHOT.zip...
  Downloading ....DONE
  Installed river-twitter into /usr/share/elasticsearch/plugins/river-twitter
  $ /usr/share/elasticsearch/bin/plugin -l
  Installed plugins:
      - river-twitter

あとはまた収集されるのを待ち Kibana でグラフを表示させます。



このグラフは2013/12/03 18:25 - 2013/12/07 18:25 のものです。
前述のプラグインをさらに修正して lang フィールドが ja のものを対象としています。

1位pic.twitter.com150,804 件
2位twitpic.com3,661 件
3位p.twipple.jp1,112 件
4位instagram.com689 件
5位photozou.jp118 件
6位flickr.com/flic.kr22 件
7位movapic.com1 件


調査対象は自分が思いついたサイトです。
95% は pic.twitter.com が使われているようで、思ったよりシェアが大きくびっくりしました。
公式クライアント・Webを使っている人が増えているようですね。

画像共有とはちょっと違いますが、vine.co を含むツイートを調べてみたところ、2,800件もありました。
結構普及しているんですね。

参考文献

* CactiのデータをElasticSearch+Kibanaでまとめてみてみよう

2013年10月6日日曜日

続 Amazon EC2 の Micro インスタンスで使用可能な CPU リソースを調べる

2011年に投稿した「Amazon EC2 の Micro インスタンスで使用可能な CPU リソースを調べる」は現在内容が正しくないので測定し直しました。

測定方法は以前と同じく、単純なループするだけのプログラムを実行し cgroups の cpuacct.stat を読むだけです。

環境

  • Amazon Linux 2013.09
  • ap-northeast-1c
  • t1.micro

ループプログラム

void main(){ while(1){} }

今回は cpu.rt_period_us と cpu.rt_runtime_us で CPU リソースの制限は行わずに、Amazon Linux のデフォルトの状態で測定しました。



以前は何も手を加えていない状態だと、すぐに CPU リソースが枯渇してしまい非常に扱いにくいものでしたが、今現在は最初からキャップが設定されているようです。

マイクロインスタンスは、非常に低コストなインスタンスオプションで、小規模な CPU リソースを提供します。マイクロインスタンスは、追加サイクルが利用可能であるときは、CPU 処理能力を短期バーストとして増大させることができます。このタイプが適しているのは、周期的に追加コンピューティングサイクルを必要とする低スループットのアプリケーションやウェブサイトです。持続的な CPU 性能を必要とするアプリケーションには適していません。
(引用元: http://aws.amazon.com/jp/ec2/instance-types/ )
ただ、上記AWSの説明にある「CPU 処理能力を短期バースト」というのがなくなっているのではという気もしてきます。

もっと長い時間計測すると短期バーストできることがあるのかもしれません。



2013年7月21日日曜日

BitTradeOne の赤外線リモコンKitを Linux から使ってみた

帰宅したときに部屋が暑すぎるのが嫌だったのでリモートからエアコンの電源を操作できたらいいなあ、という理由で USB 接続の赤外線リモコンを購入してみた。

購入したものはコレ。

  USB接続 赤外線リモコンキット

半田付けするのはめんどうだったので、完成品を購入。
フリスクのケースにあうように作られているらしい。

届いてから色々と調べてみて Linux では hiddev ファイルに書き込めばいいらしいということがわかったのですが、スレッドの msg#1.2.1 と同じようなことになり使うことができなかった。

このリモコンキットはファームウェアのソースコードやWindowsのアプリのソースコードなどが公開されているので、それを参考にしつつプログラムを作ってみた。


app-misc/lirc とかのドライバとして作るのがほんとはいいのかも。

Linuxで操作するための手段としては

  • hiddev インターフェイスを使う
  • libhid を使う
  • libusb を使う

などがあるが、HIDのインターフェイスのことがよくわからず、Broken pipeばかりで解決できなかったので libusb を使うことにした。

このリモコンキットには4つのInterfaceDescriptorがありますが、使用するのは interfaceNumber 3 のみです。



lsusbの結果
今回使う部分だけ抜粋すると下記の部分です。
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               8
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               8
デバイスからデータを貰ってくるときは EP Address 0x84 を libusb_interrupt_transfer() に渡してあげれば良さそうです。
逆にデバイスに書き込む際は EP Address 0x04 を渡せばいいようです。

続いてリモコンキットの制御コードの部分。

これは〔ファームウェアソースコード(Ver2.1.0〕の中を参考にします。
アーカイブの中の main.c がファームウェアのソースコードのようです。
ProcessIO() の中に switch 文があり、そこに制御コードが書かれています。

制御コード説明
0x56Get Firmware version
0x80EEPROMにデータを設定(サイズ61)
0x81EEPROMにデータを設定(サイズ10)
0x82EEPROMからデータ読み出し(サイズ61)
0x83EEPROMからデータ読み出し(サイズ10)
0x40Echo back
0x41Echo back
0x50赤外線受信データを送信(デバイス->Host)
0x51赤外線受信待ちモード設定(1=受信待ち,  0=解除)
0x52赤外線受信データを送信 拡張版(デバイス->Host, 65 octets)
0x53赤外線受信待ちモード設定 拡張版(1=受信待ち,  0=解除)
0x60赤外線出力データを受信する(7 Octets)
0x61赤外線出力データを受信する 拡張版(65 Octets)


赤外線をリモコンキットで受信する場合は
  0x53 0x01 0xFF 0xFF ....
というパケットを EPAddress 0x04 に投げます。
パケットサイズは 64 Bytes なので余った部分は 0xFF で埋めます。
これで受信待ちモードになったので、続いてデバイスからデータを読み出す制御コードを送りつけます。
 0x52 0xFF 0xFF 0xFF ....
このパケットを繰り返しデバイスに送っておきつつ EPAddress 0x84 を読み込めば赤外線を受信したときにコードを取れます。


リモコンキットから赤外線を送信する場合は
 0x61
の後に続けて送りたいコードをつけて EPAddress 0x04 に投げつければ送信されます。




久々にブログ書いたけど、文章まとめるの難しい..

2011年11月23日水曜日

Linux で UQ WiMAX に接続する (不成功)

ThinkPad X220 に内蔵されている Intel WiMAX/WiFi Link 6250 は WiMAX に接続することができる.
普段は EMOBILE を使っているので使う機会はないのだが,ちょうど EMOBILE の契約の2年縛りが切れるタイミングなので使えないかどうか試してみた.

結論を先に書くと,WiMAX への接続は出来たが認証情報の書き込みとやらに成功しなかったため,インターネットへの接続は出来ていない.
Windows 上で先に認証情報を書き込んでおけばもしかしたら,いけたのかもしれない.

1. Kernel の設定


以下の項目をモジュールにしておきます.
CONFIG_WIMAX=m
CONFIG_WIMAX_I2400M=m
CONFIG_WIMAX_I2400M_USB=m
CONFIG_WIMAX_I2400M_SDIO=m

2. ファームウェアのインストール


Gentoo/Funtoo では sys-kernel/linux-firmware というパッケージに含まれている.
$ sudo emerge -av sys-kernel/linux-firmware


3. コマンドラインツールのインストール


Gentoo/Funtoo では net-wireless/wimax というパッケージに含まれている.
$ sudo emerge -av net-wireless/wimax

以上で事前準備はおしまい.

4. UQ WiMAX に接続してみる



無線LAN と併用はできないようなので,wlan0 の出力を落としておきます.

$ sudo iwconfig wlan0 tx off

つぎに wimaxd を起動し WiMAX を有効化します.
$ sudo eselect rc start wimaxd
$ wimaxcu ron

使用できる WiMAX ネットワークを検索します.
$ wimaxcu scan

Network found.
NSP : UQ WiMAX
        ID          : 20
        Signal      : Good
        RSSI        : -73 dBm
        CINR        : 15 dB
        Network Type: Home Network
        Activated

電波状態の良いところだと UQ WiMAX のネットワークが見えるはずです.
室内だと場所によって見つからなかったりします.
ID 20 というのが UQ WiMAX のネットワークIDなので,それに接続します.
$ wimaxcu connect network 20

接続できたら,DHCP で IPアドレスが取得できます.
$ sudo dhcpcd wmx0

これでブラウザで適当なサイトを開くと,UQ WiMAX 認証画面にリダイレクトされます.(シークレットウインドウとかで開くのがベストなんだろうなぁ)
自分は未契約だったので 1 Day pass に契約しました.
契約後,認証情報を書き込みで待たされますが,いつまで経っても終わりません.
ここが出来れば Linux で WiMAX 接続は出来ると思いますが,恐らくこの処理が Linux で出来るようになることはないんじゃないでしょうか.
自分は諦めて 1 Day Pass を捨てました.


参考文献

Intel WiMAX адаптер ロシア語だけど,コマンドだけ参考にした.

2011年11月19日土曜日

UEFIブート可能な SystemRescueCD (LiveUSB)を作る

先日 ThinkPad X220 を購入しました.新しいマシンは速くていいですね.
電池の保ちも良い感じです.

ThinkPad X220 に Funtoo Linux を入れる際に気づいたんですが,最近のマシンは UEFI も搭載しているようで通常の BIOS ブートの他に EFI ブートも選べるようになっていました.
せっかくなので UEFI Only で行ってみることにしてみました.

私は Gentoo や Funtoo をインストールする際に SystemRescue CD を使っています.
比較的頻繁に更新されているのと,ベースが Gentoo なので Kernel も新しいし各種ツールも入っていてとても便利です.

しかしながら,そのままでは EFI には対応していないようなので,使う方法をまとめてみました.

1. USBメモリの準備
まずは,USBメモリの準備をします.
UEFIでは BIOS パーティションではなく GPT を使用します.

パーティションを構成するツールとしては parted と gdisk があります.
今回は gdisk を使いました.

# emerge sys-apps/gptfdisk

さっそく gdisk でパーティションを作成します.
使い方は fdisk と同じです.

# gdisk /des/sdb

使い方は Funtoo Linuxのドキュメント GUID Booting Guide を眺めると良いと思います.
次にファイルシステムを作ります.FAT32 を使用しますので,sys-fs/dosfstools をいれましょう.
# emerge sys-fs/dosfstools
# mkfs.vfat -F32 /dev/sdb1

2. BootLoaderの設定

Boot Loader には GRUB2 を使用します.
EFIに対応している Boot Loader としては,他に elilo があるようです.

まずUSBメモリをマウントしておき,UEFI と GRUB で使用するディレクトリを作ります.

# mount /dev/sdb1 /mnt/usb
# mkdir -p /mnt/usb/efi/boot

次に GRUB をインストールします.
Funtoo の Portage に含まれている GRUB の ebuild では EFI に対応していないため,flow overlay のを使用します.

# layman -a flow
# echo 'GRUB_PLATFORMS="efi-64"' >> /etc/make.conf
# emerge --autounmask-write =sys-boot/grub-1.99::flow
# dispatch-conf
# emerge =sys-boot/grub-1.99::flow

GRUB のインストールができたら,ブートイメージを作ります.

# grub2-mkimage -d /lib/grub/x86_64-efi -O x86_64-efi -p "" -o /mnt/usb/efi/boot/bootx64.efi part_gpt btrfs fat ext2 normal chain boot configfile linux multiboot efi_gop linux

で,grub.cfg を作ります.
これは,SystemRescueCD 内にある isolinux/isolinux.cfg を参考に作りますが,メニュー全部つくるのはめんどくさいので,必要なモノだけにしました.

# vim /mnt/usb/efi/boot/grub.cfg
timeout=10 
default=0

insmod efi_gop
insmod efi_uga
insmod font

if loadfont efi/BOOT/unifont.pf2
then
  insmod gfxterm
  set gfxmode=auto
  set gfxpayload=keep
  terminal_output gfxterm
fi

menuentry "rescue64 cached" {
  linux /isolinux/rescue64 scandelay=1 docache
  initrd /isolinux/initram.igz
}

3. SystemRescueCD のコピー

難しく考えずに,そのままファイルをコピーするだけです.

 # mount -o loop,ro /path/to/systemrescuecd-x86-2.4.0.iso /mnt/cdrom
 # cp -a /mnt/cdrom/* /mnt/usb/


BIOS のようにマスターブートレコードに書き込むとかは必要ないようです.



続いて Funtoo Linux のインストール記事でも書こうかと思ってたんですが Thinkwiki に Gentoo インストール手順がまとまってました.
Installing Gentoo on a ThinkPad X220

2011年10月22日土曜日

Amazon EC2 の Micro インスタンスで使用可能な CPU リソースを調べる

2013年現在のデータで測定し直しました。


 先日 Amazon EC2 Micro インスタンスを使う機会があり,色々と試してみた.
使っていると,すぐにターミナルの応答性が悪くなったり Ping の応答時間が不安定になるといったことが起きた.

top コマンド実行してみたところ,Steal が極端に多くなっていた.

Cpu(s):  2.2%us,  0.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si, 97.8%st
Steal は@ITの記事によると,使いたいけど使えなかった時間らしい.
  steal列には、ゲストOSがリソース要求を行ったにもかかわらずCPUリソースを割り当ててもらえなかった時間の割合が表示されます。
@IT リソース制御でサービスレベルを確保せよ 
 CPUリソースはバーストできるじゃないのかよー,と思って調べてみた.


計測方法

ループするだけのプログラムで負荷を掛け,どれだけ CPU リソースを利用できたかをグラフ化させる.
ついでに,使用する CPU リソースをどれだけ制限すれば,Steal を少なくできるかも調べてみる.

使用するモノ

  • EC2 の Micro インスタンス.
    • 今回は Amazon Linux AMI x86_64 を使用した.
  • ループするだけのプログラム
  • cgroup
  • schedtool
  • cgroup から値を盗ってくるスクリプト
まず,ループするだけのプログラム

void main()
{
 while(1){}
}

次に cgroup をマウントする.
$ sudo mount -t cgroup cgroup /sys/fs/cgroup
で,適当なディレクトリを掘ってシェルのプロセスIDを入れる
$ sudo mkdir /sys/fs/cgroup/test
$ echo $$ | tee /sys/fs/cgroup/test/tasks
最後にループするプログラムを起動しつつ,cpuacct.stat から値をとり続ける.

CPU リソースの制限は cpu.rt_period_us と cpu.rt_runtime_us で行う.
cpu.rt_period_us で指定した時間のうち,cpu.rt_runtime_us で指定した時間だけ CPU を使用できる.
時間の単位はファイル名の通りマイクロ秒.

例えば,以下のような値を入れた場合は1秒のうち0.5秒まで CPU リソースを消費できる.
cpu.rt_period_uscpu.rt_runtime_us
1,000,000500,000

今回は以下のパターンで計測した.
cpu.rt_period_uscpu.rt_runtime_us
1,000,000100,000
1,000,000125,000
1,000,000150,000
1,000,000250,000
1,000,000500,000


計測結果



0.5秒に制限した場合だいたい30秒ほどでリソースを使い切ってしまっているので,制限なしだと10秒〜15秒ほどで使い物にならなくなってしまう.
1秒あたり0.15秒以下の時間だけ使うことにすれば,安定的に CPU リソースを使うことが出来る.


まとめ

計測してて自分が何を求めているのかよく判らなくなったりしたが,とりあえず記録として残しておく.

だいたい2分毎に使用リソースがリセットされていることがわかった.
なので,こんな用途に向いてるんじゃないかなあと思う.

  • 1分もしくは2分毎に少量のバッチ処理.
    • Tweet の取得とか
  • CPUリソースをあまり喰わない低負荷な処理
    • アクセス数が多くないスタティックなサイトとか?

と,これくらいしか思い浮かばない.みんなどんなことに使ってるんだろう.
結局のところ,Amazon EC2 のサイトに書かれている説明の通りってことなんだけど.

このファミリーのインスタンスは、少量の整合性のあるCPUリソースを提供し、他のサイクルが可能になると、CPU 容量をバーストできます。定期的にかなりの計算サイクルを消費する、少量のスループットアプリケーションやウェブサイトに最適です。
「少量の整合性のあるCPUリソース」と言われて理解できる人っているのかなあ.

あ,リソースを制限したところで,使用できる CPU リソースは変わらないが,ネットワークの安定性とかターミナルの応答性は安定します.

2011年5月2日月曜日

Thinkpad X61 でピークシフト機能を使う

Thinkpad X61 でピークシフト機能を使う


Thinkpad にはピークシフト機能が搭載されています. [*]
ピークシフトとは電力使用量が多い時間帯に AC アダプターからの電力供給をカットしバッテリー駆動にすることでその時間帯の電力消費を抑える機能です.
Windows ではソフトウェアが提供されているらしいのですが,Linux ではどうやるんだろうということで調べてみました.

[*]http://www-06.ibm.com/jp/pc/environment/peakshift.shtml

tp_smapi

ThinkPad のことを調べたいと思ったら,まず ThinkWiki です.
探してみたところ,tp_smapi というカーネルモジュールがありました.

http://www.thinkwiki.org/wiki/Tp_smapi

インストール

Gentoo では app-laptop/tp_smapi というパッケージがあるので,一発で入ります.

$ sudo emerge -av app-laptop/tp_smapi

もし,kernel の方で HDAPS を Y もしくは M として利用しているのであれば外しておいた方がいいようです.
外した上で,tp_smapi の hdaps use-flag をオンにしましょう.
外さなくても,利用することは出来ますが,モジュールをロードするときに以下のようなメッセージがでてロードできないことがあるようです.

thinkpad_ec: cannot claim IO ports 0x1600-0x161f... consider using force_io=1.

この場合は /etc/modprobe.d/hoge.conf に以下のような記述を追加しておけば利用できます.

options thinkpad_ec force_io=1

使い方

まずはモジュールをロードします.

$ sudo modprobe tp_smapi

ロードすると,/sys/devices/platform/smapi/ ができます.

$ ls /sys/devices/platform/smapi/
BAT0  BAT1  ac_connected  driver  modalias  power  smapi_request  subsystem  uevent

$ ls /sys/devices/platform/smapi/BAT0
-rw-r--r-- 1 root root 4096 May  1 20:44 barcoding
-rw-r--r-- 1 root root 4096 May  1 20:44 charging_max_current
-rw-r--r-- 1 root root 4096 May  1 20:44 charging_max_voltage
-rw-r--r-- 1 root root 4096 May  1 20:44 chemistry
-rw-r--r-- 1 root root 4096 May  1 20:44 current_avg
-rw-r--r-- 1 root root 4096 May  1 20:44 current_now
-rw-r--r-- 1 root root 4096 May  1 20:44 cycle_count
-rw-r--r-- 1 root root 4096 May  1 20:44 design_capacity
-rw-r--r-- 1 root root 4096 May  1 20:44 design_voltage
-rw-r--r-- 1 root root 4096 May  1 20:44 dump
-rw-r--r-- 1 root root 4096 May  1 20:44 first_use_date
-rw-r--r-- 1 root root 4096 May  1 21:05 force_discharge
-rw-r--r-- 1 root root 4096 May  1 20:44 group0_voltage
-rw-r--r-- 1 root root 4096 May  1 20:44 group1_voltage
-rw-r--r-- 1 root root 4096 May  1 20:44 group2_voltage
-rw-r--r-- 1 root root 4096 May  1 20:44 group3_voltage
-rw-r--r-- 1 root root 4096 May  1 20:44 inhibit_charge_minutes
-rw-r--r-- 1 root root 4096 May  1 20:44 installed
-rw-r--r-- 1 root root 4096 May  1 20:44 last_full_capacity
-rw-r--r-- 1 root root 4096 May  1 20:44 manufacture_date
-rw-r--r-- 1 root root 4096 May  1 20:44 manufacturer
-rw-r--r-- 1 root root 4096 May  1 20:44 model
-rw-r--r-- 1 root root 4096 May  1 20:44 power_avg
-rw-r--r-- 1 root root 4096 May  1 20:44 power_now
-rw-r--r-- 1 root root 4096 May  1 20:44 remaining_capacity
-rw-r--r-- 1 root root 4096 May  1 20:44 remaining_charging_time
-rw-r--r-- 1 root root 4096 May  1 20:44 remaining_percent
-rw-r--r-- 1 root root 4096 May  1 20:44 remaining_percent_error
-rw-r--r-- 1 root root 4096 May  1 20:44 remaining_running_time
-rw-r--r-- 1 root root 4096 May  1 20:44 remaining_running_time_now
-rw-r--r-- 1 root root 4096 May  1 20:44 serial
-rw-r--r-- 1 root root 4096 May  1 20:44 start_charge_thresh
-rw-r--r-- 1 root root 4096 May  1 20:44 state
-rw-r--r-- 1 root root 4096 May  1 20:44 stop_charge_thresh
-rw-r--r-- 1 root root 4096 May  1 20:44 temperature
-rw-r--r-- 1 root root 4096 May  1 20:44 voltage

色々ありますが,いくつか説明します.

state
現在の状態. discharging, charging, idle の3種類
remaining_percent
バッテリー残量(%)
start_charge_thresh

充電を開始する閾値.

echo 70 > start_charge_thresh

とすると,70% 以下になったときに充電を開始する.

stop_charge_thresh

充電を停止する閾値

echo 90 > stop_charge_thresh

とすると,90%になった段階で充電が止まる.

force_discharge

放電モードにする. ACアダプタをつけてるときに機能します.

1 を入れるとこの機能が働き,ACアダプタをつなげていてもバッテリー駆動になります.

inhibit_charge_minutes
指定した時間(分)の間,充電を停止する.

これらのうち,force_discharge と inhibit_charge_minutes あたりの機能が使えそうです.

tp_peakshift

というわけで,簡単なスクリプトを書いてみました.
Yahoo!Japanの電気予報APIを利用し,1時間後もしくは2時間後の消費電力予測を見て 95% を超えたときに電池駆動モードに移行もしくは充電の停止をするものです.



使い方

スクリプトを /etc/cron.hourly/ 以下に放り込んで実行権限をつけてください.

欠点

force_discharge をオンにした状態でバッテリーが空になると,自動的に充電が始まってしまう.
充電が始まると,通常使用分+充電で余計に電力を使用してしまうので逆効果になってしまう場合がある.
バッテリーが空になったときは inhibit_charge_minutes に適当な値を自動的に入れるような仕組みが欲しいところ.


ThinkPad X61 での動作は確認しています.
他の機種でも動くとは思いますが判りません.


参考までに,通常使用時が 20W〜25W ほどで充電中は 55W〜60W くらいでした.

2011年3月6日日曜日

ja_JP.UTF-8 vs ja_JP.utf8

それは某IRCチャンネルの何気ない一言から始まった.
@xxxx | .UTF-8 or .utf8?

僕は何も疑問を持たずに,こう答えた.
@Kojima | ja_JP.UTF-8

そしたら彼は,
@xxxx | .utf8 on 'locale -a'
と返答してきた.

確かに,手元の環境で
locale -a
を実行してみると,utf8 になっている.
$ locale -a
C
POSIX
en_US
en_US.iso88591
en_US.utf8
ja_JP
ja_JP.eucjp
ja_JP.ujis
ja_JP.utf8
japanese
japanese.euc

@matsuu 先生が以前 eselect locale を入れたときにこうつぶやいていたのを思い出したので,「matsuu先生がこういってるんだから,.UTF-8なんだよ!」としておいた.

ja_JP.utf8ではなくja_JP.UTF-8で設定すべし RT @naota344: 気がつけば @matsuu せんせーの eselect locale が入っていた。 eselect locale ja_JP.utf8 しておけばいいんだろうか…。less than a minute ago via web



とはいえ,ちょっと気になったので調べてみた.


LFS のドキュメントにこんな記述がある.
キャラクターマップはたくさんの別名を持つことが出来ます。 例:“ISO-8859-1”は、“iso8859-1”と“iso88591”として参照されます。 いくつかのアプリケーションは、様々な別名を正しく取り扱えません(例:“UTF-8”は、“utf8”ではなく“UTF-8”と書く必要がある)。

いくつかのアプリケーションは "UTF-8" と書いておかないといけないらしい.

"UTF-8" と書く理由はわかったけど,"utf8" と "UTF-8" は同価なのだろうか.

"locale -a" の結果はどこから持ってきてるのか調べてみる

$ strace locale -a
(snip)
open("/usr/lib64/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3677376, ...}) = 0
(snip)
"/usr/lib64/locale/locale-archive" を参照しているようだ.
これはきっと localedef で作られるはずだ,ということで localedef のコードを追ってみた.

glibc-2.11.2 の intl/l10nflist.c:_nl_normalize_codeset で以下のような処理をしていた.

347   if (retval != NULL)
348     {
349       if (only_digit)
350         wp = stpcpy (retval, "iso");
351       else
352         wp = retval;
353 
354       for (cnt = 0; cnt < name_len; ++cnt)
355         if (isalpha ((unsigned char) codeset[cnt]))
356           *wp++ = tolower ((unsigned char) codeset[cnt]);
357         else if (isdigit ((unsigned char) codeset[cnt]))
358           *wp++ = codeset[cnt];
359 
360       *wp = '\0';
361     }

locale-archive に書き込む際に,アルファベットは小文字に,アルファベットと数字以外は無視するようにしているようだ.

ちなみに,LC_* とか LANG のシンタックスは次のような形式らしい.
[language[_territory][.codeset][@modifier]]


結論

"ja_JP.utf8" も "ja_JP.UTF-8" も同じ意味.しかし,一部のアプリケーションでは ".UTF-8" と書かなければ正常に動作しないことがあるので "ja_JP.UTF-8" が推奨される.


たぶん.