Skip to main content

ログ取得ツール

Category: GNU/Linux

VPSアップデート

使っているVPSがアップデートされました。

## uname -srvmpio

Linux 2.6.32-042stab055.10 #1 SMP Thu May 10 15:38:32 MSD 2012 i686 i686 i386 GNU/Linux

これですね。1週間前にOpenVZからリリースされたカーネルです。アップデート以前はRHEL5ベースのカーネルでしたから、それをRHEL6ベースにしたということで、以前にアップデートに失敗していたものにリトライしたという感じ。うんこレベル寸前だった当時からだいぶ安定していたので乗り換え先の選定も進んでいない。

別にユーザランドはCentOS5なのでユーザとしての使い勝手に違いはないですが、/procに出てくるエントリもそれなりに増えてるのがまあ違いと言えなくもない。eventfdが使えるようになったのかな? CPU(Xeon L5520)とかは変わってないです。

それで、このVPS業者にはまだ選べるOSの選択肢の問題が残っている。「CentOS」とか「debian」で64ビットか32ビットは選べるんだけど、何とバージョンが書かれていないのだ。いま選んだらCentOS6になるのかな? それとも、5になるのかな??

coLinux

勤務先でcoLinuxが意外と使えることを知った私は、自宅のマシンにも入れてみるのであった。これでVMware Playerをアンインストールできるかもしれない。ネットワークの設定は面倒ですがググれば問題ないレベル。

勤務先では配布物のarchLinuxをpacmanしまくってカスタマイズしていった。cygwinのtruncateコマンドでイメージファイルを広げてresize2fsで増やしていろいろ入れつつ、tune2fsでext4にして…だが、自宅では最初からCentOS6のイメージを自作しようかなと。

でも、やってみるとarchLinuxよりも起動が遅いですね。会社ではnet start…だけ書いたスクリプトを叩いてマウスを移動する時間よりも早く起動が終わり、sshですんなり入れる感じでしたけど、ちょっと待たされます。SSDとHDDの違いか、XPとVistaの違いかもしれないが。

基本的には、

  • VMwareでCentOS6(32bit)を最小構成でインストール。ディスクサイズは小さくする。私は1GBでやりました
  • パーティションはカスタマイズして、/だけをsda1に定義
  • qemu-img等でrawに変換…最初からqemuでインストールすれば良かった
  • dd if=/path/to/img.raw of=cent6/root.fs bs=512 skip=2048

これでroot.fsができます。coLinuxのcobd(block device)はパーティションを扱えないんで、sda1の部分を抜き出す必要があります。scsi0=disk,d:\path\to\img.rawとやればパーティションを扱えるそうですが…

落ちた話 (2012年1月18日)

久々にこのサーバが落ちました。uptimeは約40日。40日前はglibcのバージョンアップなどが行われたため、手動でrebootした。

今回もENOMEMですね。このときと同じような現象です。約1日ずっと落ちてました。最初にspamassassinが落ちたらしく、迷惑メールが大量にメールボックスに入るようになったのがきっかけで、18日の夜には問題に気づいていましたが不覚にも寝落ちしてしまい、19日の朝はもうsshで入れない状態。管理画面から再起動をかけましたが、起動しませんでした。19日の夜に再度の再起動をかけると戻りました。

メモリは以下のとおりスカスカですが、ENOMEMでほとんど何も動かなくなる。

memory-week

VPSの場合はこういうのはしょうがないのかもしれませんね。あとはどう気づいて、動く間にrebootなり重要度の低いプロセスを落とすなり管理者にメールで通知するか、という話になるのかな。

clacは使えるよ!

簡単な計算をするときに長らく重宝していたのがcalcというソフト。コマンドラインから十分な精度で計算してくれる。非常に便利で、私はここ数年というもの、毎日のように使っていた。

  • calc “9**100”
    265613988875874769338781322035779626829233452653394495974574961739092490901302182994384699044001
  • calc 1/10
    0.1
  • calc “sqrt(2)”
    1.4142135623730950488

別にPython起動してもいいんですけどね。シェルの入力でそのまま計算できるというのは便利なもんです。

しかしFedoraならいいけど、EPELにパッケージがないのでCentOSでは使いにくいという問題があった。しょうがないので自分でrpm作って入れてたんです。

そこに登場したのがPythonのeval()をうまく使ったclacというソフト。似たような使い勝手で、Pythonなので無限桁の整数を苦もなく使える。拡張もやりやすい。ソースはPythonのスクリプト1本なので、Cygwinのような環境にも持ち歩ける(Cygwinのパッケージには入ってませんが)。

これは良い! 非常に!!

…のだけど、

  • clac “9**100”
    265613988875874769338781322035779626829233452653394495974574961739092490901302182994384699044001
  • clac 1/10
    0.10000000000000001
  • clac “sqrt(2)”
    1.4142135623730951

うーむ。浮動小数点の演算で誤差が入るのはどうもアレですよねー。

しかし、拡張可能というのがこういう時に使えることを私は知っている。Pythonには分数や10進演算のモジュールがある。分数は確かPython 2.7以降だから入ってない古い環境もあるかもしれないが。なので、~/.clacrcに以下のように書いておく。

try:
  from fractions import Fraction
  frac=Fraction
except ImportError,detail:
  #old python
  pass
from decimal import Decimal
dec=Decimal

これによって、正確に計算することができるのだ。

main()の外でargcとargvを見るには?

少しググッてみたけど答えは見つからなかった。とにかくmain()に渡されるargcとargv。これを引数で渡すことナシに別の関数から勝手に参照したいと思い立った。

なんでそんなことをしたくなったのか分からない。でも思い立ったものはしょうがない。

それなりに調べていくと、環境変数を示すenvironというグローバル変数を使えば良いようだ。

extern char **environ;

そしてenvironとargc/argvは以下のような関係にあるらしい。

  • (long)environ[-2-argc] = argc
  • environ[-2-(argc-1)] = argv[0] (= 実行ファイルを示す文字列)
  • environ[-2-(argc-2)] = argv[1] (= 第1引数)
  • :
  • environ[-2] = argv[argc-1]
  • environ[-1] = argv[argc] (= NULL)
  • environ[0] = ここから環境変数
  • :

とても移植性があるとは思えないですね。Linuxでは動作したが。

#include 

void show_argv(){
  extern char **environ;
  int n=-1;
  if(environ[n]!=NULL) return;
  --n;
  while((long)(environ[n])!=-n-2){
    --n;
  }
  int argc=(long)(environ[n]);
  char **argv=&environ[n+1];
  int i;
  for(i=0; i

以下、実行結果。

# ./test-argv test argument here. 
in-main 
0: ./test-argv 
1: test 
2: argument 
3: here. 
out-main 
0: ./test-argv 
1: test 
2: argument 
3: here.

でも、移植性のある方法はないんでしょうかね?

失礼しました (2)

このサイト、電話等からアクセスできなくなってました。Wordpressのプラグインの相性の問題?

電話から見えるようにするために長らくktai-styleというプラグインを入れていたんですが、検索エンジン用のbotからのアクセスで昔のクエリ文字列が入ったままでアクセスしてくることが多かったのが気になって、1ヶ月くらい前(7/25頃)にPermalink Redirectというプラグインも入れていたんです。

この関係で、どっちが悪いのかわかりませんけど、301ループになってアクセス不能、という状態に。

サーバ側のアクセスログを見ると、末尾に/があるURLからないURLに301、ないURLからあるURLに301、というループのようです。トップページのURLでリダイレクトしてしまうのはおかしいんじゃないかな。

とりあえずPermalink Redirectを外してみました。

しかし1ヶ月か。気づかないもんですね。

失礼しました

このサイトは24日の早朝2:23頃よりアクセスできなくなっていました。部分的に死んでいて、一部のファイルには引き続きアクセスできるという状況で、blogはDBサーバに繋がらなくなって何も表示されなくなってました。この間、メール受信に使っているsendmailとprocmailは生きていましたが、dovecotは死んでいたので結局メールの確認もできませんでした。さきほどようやく回復しました。

気づいたのは24日の17時過ぎです。blogの管理画面にアクセスしようとして気づきました。気づいてから復旧までに1日以上時間がかかったのは私の不徳の致すところです。昨晩は寝てしまったし、起きてからも子供に邪魔されてまともにPCを操作できなかったので…というのは言い訳です。

落ちている間、sshでログインもできない状況ではありましたが、不思議な方法でログファイルにはアクセスできていました。見ると、メモリ不足のようでした。VPSの管理画面から再起動させようと思ったのですが、なぜか管理画面もエラーになって、にっちもさっちも行かない状況でした。エラーの原因は分かってみれば他愛もないことで、少し前にクライアント(Firefox)のエクステンションを変えた関係でcookieのサイト設定が全部消えた(というか消しちゃった)んですけど、管理画面が使っているcookieがオフになっていたためという…まあ、管理画面も部分的に使えていたので思い当たるまでに時間がかかりました。

OpenVZのゲスト(VE)数の推定は可能?

VPSの仮想OSで、同じホストに収容されているゲストの数を推定する方法について考えていた。一般的には他のVEは隠蔽されており、得ることができない情報。

VEIDであれば、/proc/vz/veinfoや/proc/vz/vestatで取得することができる。このサーバで言えば34XXX。ただこの番号はランダムでつけてもいいので、ゲストの数とは直接関連はない。たぶんこのサービスではVEIDを複数のホストで共有していて、言わば契約者IDみたいなものなんだろうと思う。私が契約した時点ですでに3万ユーザ以上いて、単価が月1000円とすると売上は3000万円/月? こんな計算で合ってるかな??

/proc/statのcontext switchの数で推定することができないかなぁと思った。muninで観察していても、ここ以外の値(例えばprocesses=fork数)はどうもVEに閉じた値しか出てこないんですね。ctxt swの項に限って通常のサーバよりもずいぶん大きい値が出てくるので、ホスト全体の値になってるんじゃないかと思います。

gccでtccのようなrun

tccは高速なCコンパイラで、あまりにコンパイルが高速なので、まるでインタプリタのように*.cを起動できるという-runオプションがある。確か、コンパイルしたものをファイルに送らずにメモリ上に置いて、そのままmainのアドレスを呼び出していたような気がする。tccもx86_64に対応してくれて、使いやすくなった。

最近はCPUも速くなったので、gccで一時ファイルを使っても、そう大差ない使用感になるだろう。シェルスクリプトでも書けるけど、Pythonで書いてみた。

  • tgcc.py
  • python tgcc.py program.c othersrc.c – arguments
#! /usr/bin/python

import os,sys
import subprocess
import tempfile

def usage():
    print "Usage: %s files... [-- args...]" %(sys.argv[0])
    exit(0)

def main():
    args=sys.argv[1:]
    try:
        sp=args.index("--")
        files, arg=args[:sp],args[sp+1:]
    except ValueError,detail:
        files=args
        arg=[]
    if len(files)==0:
        usage()
    f=tempfile.mktemp()
    r=subprocess.call(["gcc", "-o", f]+files)
    if r==0:
        r=subprocess.call(["temp"]+arg, executable=f)
    os.unlink(f)
    exit(r)

if __name__=="__main__":
    main()

例えば、

  • echo -e “#include <stdio.h>\nint main(){printf("hello,world\\n");}” > /tmp/hw.c
  • python tgcc.py /tmp/hw.c

で、hello,worldが表示されますね。-Wall等のオプションも有効です。

gcc関係では、もう少しだけ面白い遊びを考えてます。もうかなり長いこと温めていて、まだ温めているってだけですが。