パスワードを忘れた? アカウント作成

mishimaさんのトモダチの日記みんなの日記も見てね。 Idle.srad.jpは、あなたの人生において完全な時間の浪費です。見るなよ、見るなよ。

13185004 journal
日記

mishimaの日記: fluentd の forest plugin を Time slice で使用するとfluentd再起動時にログが消失する

日記 by mishima

https://github.com/tagomoris/fluent-plugin-forest

ここに以下のような設定例があるんだけど

<match service.*>
    @type forest
    subtype file
    remove_prefix service
    <template>
        time_slice_format %Y%m%d%H
        compress gz
        path /var/log/${tag}.*.log
    </template>
</match>

このような設定をしている場合、以下の条件が重なるとログが消失(バッファ内に格納されたまま吐き出されない)する。

* 再起動後、
* 同一 Time slice の期間内に、
* 同一タグのログが入力されない

forest プラグインは新規のタグを見つけるたびにスレッドを作成し、そのスレッドがそのタグについてのバッファファイルも管理するような構成になっている。再起動するとスレッドが全部停止するが、このときバッファファイルのことも忘れてしまうので、Time slice の期間が終わってもバッファファイルの書き出しが発生しない。

対策として flush_at_shutdown true を追記しておくことが必要(停止時にバッファファイルを書き出してくれる)。

11032381 journal
日記

mishimaの日記: Redmine のデータ移設(SQLite → MySQL)

日記 by mishima

Debian的に正しい手法(パッケージで提供されているファイルを変更しない)で、データをダンプする手順がわかりにくかったので、きちんと書き留めておく。

1. yaml_db をインストール

  # aptitude install ruby-yaml-db

2. 適当なディレクトリに redmine をコピー

%  rsync -aSvx /usr/share/redmine/ /tmp/redmine/

3. その中に yaml_db を入れる

  % rsync -aSvx /usr/lib/ruby/vendor_ruby/tasks/ /tmp/redmine/lib/tasks/.

4. ダンプする。

  % cd  /tmp/redmine
  % rake RAILS_ENV=production -r yaml_db db:dump

5. 移行先のデータベース情報に書き換える。

  # vi /etc/redmine/default/database.yml
 
production:
  adapter: mysql
  database: redmine_default
  host: localhost
  port:
  username: redmine_default
  password: XXXXXXXXX
  encoding: utf8

6. データをロードする。

  % rake RAILS_ENV=production -r yaml_db db:load

「Rake には tasks という概念がある。それは lib/tasks の下に格納される」
「yaml_db はデータダンプの tasks である db:dump を提供する。それは単独では機能せず、 db:schema:dump を提供する他の tasks を組み合わせて使う」
「Redmineのホームディレクトリには Rakefile があって、いろいろな tasks を提供する。その中に db:schema:dump も含まれている」

このあたりの前提条件がわからないと、何をやったらいいかわからないよ〜

10007348 journal
日記

mishimaの日記: VMware上の仮想サーバでfluentdが使えない件 4

日記 by mishima

http://d.hatena.ne.jp/oranie/20121107/1352298768
VMWareのバグで、ちいさなUDPパケットが破棄されてしまうんだと。なんだこのバグ…

fluentd では死活確認のため、1バイトの内容("\0")のパケットを送り合ってるんだけど、これが欠落しているのが原因。ソースコードを書き換えてパケットの中身を増やせば対応可能。うちでは12バイト以上にすればパケットの受信が確認できた。

2013-09-11 08:51:11 +0900 [warn]: temporarily failed to flush the buffer. next_retry=2013-09-11 08:51:12 +0900 error_class="RuntimeError" error="no nodes are available" instance=159840520

こんなエラーメッセージが出ているのがポイント。
あまりこのバグに引っかかる人は多くないような気がするが、一度引っかかると原因を探すのがなかなかむずかしい(アプリ側の設定を疑ってしまう)のでとりあえず情報を拡散してみる

9818418 journal
日記

mishimaの日記: 一般ユーザ権限でGemをインストールする

日記 by mishima

次のことをやればおk

mkdir ~/gems
cat >>~/.zshenv <<'EOF'
########
########
########
export GEM_HOME=$HOME/gems
export GEM_PATH=$HOME/gems
export PATH=$PATH:$HOME/gems/bin
EOF

zsh 使ってない?しらんがな

9669337 journal
日記

mishimaの日記: libkeepalive がDebianに入った!

日記 by mishima

今年の2月から入った模様。jessieとsidで使える。知らんかった~

8840055 journal
日記

mishimaの日記: ajaxterm より shellinabox

日記 by mishima

緊急時用の端末として ajaxterm を用意していたのだが、気がついたら最近の firefox ではちゃんと表示できないみたい。
ajaxterm は、固定のHTMLの中に AJAX で端末画面を埋め込むような動きになっていて、正常稼働の場合、DOMはこんな階層構造になるはず。

 div id="term" 要素 ← 静的なHTML中に記載
  div style="cursor: auto;" 要素 ← AJAX で挿入
   pre class="term" 要素 ← AJAX で挿入

ところが、最近の firefox ではDOMの構造はこうなる。

 div id="term" 要素 ← これは変更なし
  div style="cursor: auto;" 要素 ← これも変更なし
  div class="term" 要素 ← 階層が違うし、pre のはずが div になってる

HTML要素の挿入がミスってるぽい。JavaScriptは専門じゃないし、これを修正するのはめんどくせーなーと思ってしらべてたら ajaxterm と同じようなツールで shellinabox というのが最近の Debian に入ったらしい。
早速使ってみた。

…うわ、ちょうすごい!
うごきがいい!
しかも、ajaxterm みたいに、いじってないとすぐセッションが切断されちゃったりすることもない。
UTF-8 への対応もバッチリ。
こっちに乗り換えるぜ!

…と思ったのもつかの間、いくつかの記号が入力できないことに気がついた。「@」とか「:」とか。
ソフトウェアキーボードがあるにしても、これは常用するには辛い。
バグ報告にはイタリア語レイアウトのキーボードでも記号が入力できない事例が登録されていたので、たぶん日本語キーボードの問題だ。
こういうのは開発側で再現できないので、単にバグ報告を出しても修正されないことが多い。
もっと調べて見ることにする。

サーバ側で strace してみると、「ふつうの記号はキーを押すとサーバにリクエストが来る」
「入力されない記号の場合、キーを押してもサーバにリクエストがこない」ということが分かった。
ブラウザ側、JavaScript の実装に問題があるという事だ。

幸い firefox には開発者向けのデバッグ機能が載ってるので、そのまま JavaScript をデバッグする。
ちょっと調べた結果、次のようなことが分かった。

  1. keyDown, keyPress, keyUp あたりのイベントで面倒くさい処理をしている。
  2. 一文字のキーを押した時に、「keyDown/keyUp」の1組イベントが発生する場合と「keyPress」のイベント一つが発生する場合がある。どちらか一方だけが発生するはずだが、世の中のブラウザ実装では両方発生してしまうことも多いらしい。
  3. そのためshellinaboxでは「keyDownイベントでキー入力を処理した場合、keyPressイベントの処理は無視する」という実装をとっている。
  4. keyDownイベントは、通常のキー(ASCII文字=数字、アルファベット、記号など)以外に、シフトキー押下などでも発生する。そのため、keyDown時にこれを判定して、通常のキーの場合だけキー入力処理をおこなう。
  5. ところが、USキーボードでは、@ や : はシフトキーを押しながらでないと入力できないので、shellinaboxでは keyDown 時のチェック範囲から漏れている。
  6. そのため、JPキーボードでは、 - ^ @ : の4つのキーは「通常キーでもないけど特殊キーでもない」ものとして扱われてしまい、入力が無効になる
  7. シフトキーを押しながら - ^ @ : を入力した時に発生するはずの = ~ ` * も同様に入力が無効になる。

これに対して、次のようにパッチを作成した。

  1. apt-get source shellinabox でソースを取得し、 debuild でコンパイルできることを確認する。
  2. dch で適当に changelog を書く。
  3. dquilt new fix-keycode.patch でパッチを作成する。(dquiltはDebianのNew Mainteiner Guideを参照)
  4. dquilt add shellinabox/vt100.js
  5. vt100.jsを修正する。

    add ascii keycode.
    --- a/shellinabox/vt100.js
    +++ b/shellinabox/vt100.js
    @@ -2933,8 +2933,10 @@
       // } 107
       var asciiKey                  =
         event.keyCode ==  32                         ||
    -    event.keyCode >=  48 && event.keyCode <=  57 ||
    -    event.keyCode >=  65 && event.keyCode <=  90;
    +    event.keyCode == 160                         ||
    +    event.keyCode == 173                         ||
    +    event.keyCode >=  48 && event.keyCode <=  58 ||
    +    event.keyCode >=  64 && event.keyCode <=  90;
       var alphNumKey                =
         asciiKey                                     ||
         event.keyCode ==  59 ||

  6. dquilt refresh
  7. dquilt header -e
  8. 再度 debuild で完成!

これで @ も * も入力できる。パスワード入力時に「なんでパスワード間違いになっちゃうんだろう」とか悩まなくても良くなるわけです。
ということで、みなさん安心して shellinabox に乗り換えればいいと思うよ!

8796995 journal
日記

mishimaの日記: usbrhで温度が取得できない

日記 by mishima

usbrhという、USB経由で温度を取得できる大変便利なデバイスがある。
このデバイスを Linux で使用する場合、カーネルドライバでの利用することもできるし、コマンドで利用することもできる。
導入が簡単なのはもちろんコマンドの方だよね。usbrh というコマンドで温度が拾える。

http://www.dd.iij4u.or.jp/~briareos/soft/usbrh.html
ここでソースコードは公開している。

で、最近PCを変更したら、usbrh で温度が取得できなくなった。

# usbrh
-40.00 -4.25

こんなふうになる。
libusb -v を実行した直後だけ、ちゃんと値が取れるので、いろいろ調べていくと、どうもデバイスの状態が USB ドライバでキャッシュされていることが原因のように見える。同じ状態で前回と同一内容のメッセージを転送しようとすると、デバイスへの実際のメッセージ転送が発生しないみたいだ。 その結果 usbrh デバイスへの温度取得要求が発行されず、いつまで待っても温度を取得できないのだろう、たぶん。
対策として、状態を一度変更すればよいと考えた。usbrh_main.c の232 行目に以下の内容を追加する。

    if((rc = usb_set_configuration(dh, 0))<0){
        puts("usb_set_configuration error");
        usb_close(dh);
        exit(3);
    }

これで、温度・湿度が確実に取得できるようになった。

# usbrh
23.64 42.65

7358348 journal
日記

mishimaの日記: 古いカーネルで最新のDebianを動かす

日記 by mishima

lxc や chroot 等で Debian を動かす状況はあるかと思う。
最近までは Debian の glibc は最適化をそれほどしていなかったため、けっこう問題なく動いていた。
ところが wheezy 以降ではきっちり最適化をしており、wheezyのカーネルとして使用している「2.6.26」以前の、古いカーネル上では動かなくなってしまっている。

libc の debian/changelog の該当部分はこうなってる。

  * debian/sysdeps/*.mk, debhelper.in/libc.preinst: bump minimal Linux
    kernel version to 2.6.26, and minimal FreeBSD kernel version to
    8.0.0.  Closes: #610475.

やりとりの詳細はここ。
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=610475

さて、古いカーネルでもなんとかなるようにするには次のように変更が必要だ。

apt-get source libc6
cd eglibc-2.13
grep '2\.6\.26' **/*
# ↑これで debian/sysdeps/linux.mk debian/debhelper.in/libc.preinst を修正すればいいことがわかる
vi debian/sysdeps/linux.mk debian/debhelper.in/libc.preinst
# 2\.6\.26 の部分を好きな版に修正する
debuild

これでいい…はずなんだけど、これだけだと Apache が動かない…
(sycall socket でSOCK_CLOEXECを使っていて、これが古いカーネルだとサポートされてないから)
libc 内の socket() を書き換えて、SOCK_CLOSEXEC が設定されていたらこれを外しで syscall socket し、直後に fcntl すればいいんだけどめんどくさい…
( http://www.gcd.org/blog/2009/12/181/ をみるとそれだけじゃダメみたいだし )

7333906 journal
日記

mishimaの日記: 仮想化するときのブリッジにはフィルタリングを無効化しよう

日記 by mishima

あまりiptablesをいじらないなら問題は起きない。
でもこんな構成のとき。

[ PC ] -----> eth0 [ L/B ] br0 ----> [ REAL SERVER ]

PC から L/B に向けた通信に対し、L/Bが内部で DNAT をして、REAL SERVER に振り分けていたとする。
行きのパケットは意図したとおりに DNAT される。しかし、帰りのパケットはうまく PC に戻らない。なぜか。それはブリッジが複数の仮想イーサネットから構成されているからだ。

[ PC ] <----- eth0 [ L/B ] br0( vethXXX1 <---- vethXXX2 ) <---- [ REAL SERVER ]

vethXXX2 にパケットが入ってきた時点で DNAT の帰りのパケットの逆変換をして、パケットの送信元 IP アドレスを eth0 のアドレスに書き換えてしまう。
すると、vethXXX1 は「eth0 の IP アドレス」を送信元として持ったパケットを受け取ることとなる。 br0ではeth0のセグメントのパケットは受け取らないため、パケットはフォワーディングされることなく破棄されてしまう。
ブリッジの「中」で iptables が有効になっていることが原因といえる。

このことに気づかないと、4時間を無駄にするぞ!

無効にするためには/etc/sysctrl.d/mybridge.conf とかに次のように書いておく。

net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0

↑だけだと再起動するまでは無効化されないので、すぐに無効化したい場合は echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables とか別途実行すること。

6503173 journal
日記

mishimaの日記: 文字コードエラー時にajaxtermが停止する問題への対策 6

日記 by mishima

どうせ日本語圏にしか影響がなく、パッチを受け取って貰えそうにもないのでとりあえずここに書く。

ajaxterm.py を2点修正すればよい。

一点目

utf8decoder = codecs.getincrementaldecoder('utf8')()

utf8decoder = codecs.getincrementaldecoder('utf8')('replace')

二点目

if c == 0:
    span+=u' '
elif c > 0x10000:
    span+=u'?'

if c == 0:
    span+=u' '
elif c < 0x20:
    span+=u'?'
elif c >= 0xd800:
    span+=u'?'

typodupeerror

犯人は巨人ファンでA型で眼鏡をかけている -- あるハッカー

読み込み中...