ようへいの日々精進XP

よかろうもん

lxc-info のソースコードを grep だけを頼りに深追いしてみた

きっかけ

lxc-info に存在しないコンテナ名を引数で渡した際にエラーでは無く、存在するんだけど止まっているコンテナとして認識してしまうようなので、なんでそんなんことになっているのかソースコードを追ってみることにした。

存在するコンテナの lxc-info

sudo lxc-ls --fancy

を実行すると以下のようにコンテナのリストが取得可能。

NAME            STATE    IPV4        IPV6  AUTOSTART
----------------------------------------------------
centos-master   STOPPED  -           -     NO       
squeeze-master  STOPPED  -           -     NO       
squeeze-test1   RUNNING  10.0.3.xxx  -     NO       

上記のリストをもとにして lxc-info を実行する。

sudo lxc-info -n squeeze-master
state:   STOPPED
pid:        -1

上記のようにステータスが表示され、停止中のコンテナであることが判る。

存在するしないコンテナの lxc-info

で、気になるのが、存在しないコンテナ名を typo してしまった場合の挙動。

sudo lxc-info -n squeeze-maste

とコンテナ名を打ち間違っても...

state:   STOPPED
pid:        -1

と表示される。そんなコンテナ居ないよってエラーを出してくれると個人的には嬉しい。


lxc-info とは

lxc-info とはコンテナの情報を取得するコマンド

$ sudo lxc-info --help
Usage: lxc-info --name=NAME

lxc-info display some information about a container with the identifier NAME

Options :
  -n, --name=NAME       NAME for name of the container
  -s, --state           shows the state of the container
  -p, --pid             shows the process id of the init container
  -t, --state-is=STATE  test if current state is STATE
                        returns success if it matches, false otherwise

Common options :
  -o, --logfile=FILE               Output log to FILE instead of stderr
  -l, --logpriority=LEVEL          Set log priority to LEVEL
  -q, --quiet                      Don't produce any output
  -P, --lxcpath=PATH               Use specified container path
  -?, --help                       Give this help list
      --usage                      Give a short usage message

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.

See the lxc-info man page for further information.

確認した環境

lxc のバージョンは以下の通り。

sudo lxc-version

を実行。

lxc version: 0.9.0

では lxc-info のソースコードを追ってみる

ソースコードは github で管理されているのでその気があればだれでも見れる。但し、「見れる」のと「解る」のはかなり異なる orz

lxc_info.c

lxc-info のもとになる(と思われる)ソースコード。コンテナ状態を確認している部分を抜粋。

lxc_getstate でステータスを取得、lxc_cmd_get_init_pid で PID を取得していると思われ、引数は -n で渡しているコンテナ名が my_args.name に展開されている。my_args.lxcpath[0] はコンテナへのパスが展開される。

state.c

lxc_info.clxc_getstate から呼ばれているいるのが state.c にある以下の部分。

何をしているかはイマイチわからないが if (state != FROZEN && state != FREEZING) という判断が true であればさらに state = lxc_cmd_get_state(name, lxcpath); を叩いている。

commands.c

上記の state.c で叩かれていた関数の lxc_cmd_get_statecommands.c の以下の部分。

奥深く切り込んできてやっと馴染みのメッセージに似た文言を発見。更に lxc_cmd を叩いて、更に深堀しなければ真実には辿りつけそうにないが、こうやって見てきて気づいたのが、どうやら -n オプションで渡されるコンテナ名の内容をちゃんとチェックしていないのではという疑問。


ちょっと虐めてみる

コンテナ名の限界数

lxc-info が認識するコンテナ名の限界。

sudo lxc-info -n squeeze-mastergreggksgsegsegresgsregsreggergergergregregregregregregreggghhhhhhjkloyiy

引数に 86 文字入力すると...

lxc-info: Name too long
lxc-info: failed to send command
lxc-info: Name too long
lxc-info: failed to send command

85 文字以上はダメのようですな。

引数の文字

2 バイト文字のコンテナ名をうっかりつけてしまった場合(lxc-create で作ることが出来た)

sudo lxc-create -t debian -n 日本男児

作ることが出来たので当然...

sudo lxc-info -n 日本男児
state:   STOPPED
pid:        -1

その他のコマンドオプションとの組み合わせ

-l オプションをつけてみる。

sudo lxc-info -l -n
lxc-info: missing container name, use --name option

とエラーとなるが...

sudo lxc-info -n -l

とすると...

state:   STOPPED
pid:        -1

コマンドオプションまでもがコンテナ名。


ということで

予想と何となく解ったこと

  • lxc-info は -n でコンテナ名をチェックする際、有無のチェックは当然チェックしている
  • ただ引数の中身のチェックが厳格ではないように思われる
  • ただし 85 文字(バイト)以上は認識しない
  • -n 以降の文字列はコンテナ名として認識される

結論

  • C の事はサッパリ判らないけどソースコードを追うのは面白かったし、新たな発見があった
  • lxc-ls でコンテナ一覧を取得出来るからそのリストをコンテナ名のチェックにに利用することが出来ないのかなと思ったりした