TenForward

技術ブログ。はてなダイアリーから移転しました

CRIU (1)

CRIU とは "Checkpoint Restart In Userspace" で Linux のプロセスの状態を保存して停止させ,また同じ状態で再開させる機能 (の実装) の事です.面白そうな機能なので試してみました.

なお,丁度 技術評論社から出ている Software Design 誌の 2012 年 11 月号 の連載「Linuxカーネル観光ガイド」のテーマが「【8】checkpoint/restoreとLTO」というもので,そこに書いてある事とほぼ同じです.きっとそちらをご覧になる方が役に立つかと.

この機能に必要な実装は,まだカーネル側の機能もバンバン実装中ですし,ツールの方も開発がすごい勢いで進んでいます.現時点の stable カーネルでは動きません.

以下は Plamo-5.0(x86_64) の現時点での最新上で試しました.

インストール

CRIU が動く環境の準備は CRIU サイトの "Installation" のページにあるとおりです.

  1. カーネルLinux checkpoint/restore ツリーを取得し,crtools-v3.7-rc1 ブランチを checkout します.
    git clone git://git.kernel.org/pub/scm/linux/kernel/git/gorcunov/linux-cr.git
    cd linux-cr
    git checkout crtools-v3.7-rc1
  2. 普通にカーネルの config を行います.
    make menuconfig
    ここで必要なのはページに書かれてあるとおりです.
    • CONFIG_CHECKPOINT_RESTORE
    • CONFIG_FHANDLE
    • CONFIG_EVENTFD
    • CONFIG_EPOLL
    • CONFIG_INOTIFY_USER
    • CONFIG_IA32_EMULATION
    • CONFIG_UNIX_DIAG
    • CONFIG_INET_DIAG
    • CONFIG_PACKET_DIAG
    • CONFIG_EXPERT
    • CONFIG_EMBEDDED
  3. カーネルをmakeしてインストールします.名前の通りバージョン 3.7-rc1 ベースのカーネルがインストールされるようです.
  4. Checkpoint/Restore 処理を行うツールである crtools をインストールするには protobuf とその C bindings の protobuf-c が必要なのでインストールします.どちらも ./configure ; make ; make install で OK でした.
  5. crtools をインストールします.CRIU ページにある crtools-0.2 は,私の環境ではコンパイルが通りませんでしたので,リポジトリより最新を取得しました.
    git clone git://git.criu.org/crtools.git
    cd crtools
    make
    make が終わると crtools というバイナリができますので,これを適当な場所にコピーします.他は不要です.
  6. 環境が crtools が動くのに必要な機能が揃っているかどうかチェックします.
    # crtools check -vvv
    (00.000024) Image dir fd is 1021
    (00.004438) Eventfd fdinfo works OK (13 vs 13)
    (00.004543) Epoll fdinfo works OK (5 vs 5)
    (00.007002) Inotify fdinfo works OK (1 vs 1)
    (00.007033) Unaligned vmsplice works OK
    (00.007033) Looks good.

簡単な dump/restore 処理

まずは簡単なものを dump/restore してみます.

  1. こんなシェルスクリプトで試してみました.testfile というファイルに 1 秒に 1 行ずつインクリメントされた数字が書かれていくだけです.
    #!/bin/bash
    n=0
    while :
    do
    echo $n >> testfile
    n=`expr $n + 1`
    sleep 1
    done
  2. これを実行します.
    # ./test.sh
  3. pstree で見るとこんな感じに.
            |-gnome-terminal(1854)-+-bash(1858)---su(7531)---bash(7534)---test.sh(10989)---sleep(10995)
  4. testfile を見ると 1 秒おきに数字が追加されていっています.
    # tail -f testfile
  5. ここで dump します.
    # crtools dump -t 10989 -j -vvv > dumplog 2>&1
    # ls
    core-10989.img eventpoll-tfd.img fs-10989.img itimers-10989.img pages-11131.img sigacts-10989.img tty-info.img
    core-11131.img eventpoll.img fs-11131.img itimers-11131.img pipes-data.img sigacts-11131.img tty.img
    creds-10989.img fdinfo-10989.img inetsk.img mm-10989.img pipes.img signalfd.img unixsk.img
    creds-11131.img fdinfo-11131.img inotify-wd.img mm-11131.img pstree.img sk-queues.img vmas-10989.img
    dumplog fifo-data.img inotify.img packetsk.img reg-files.img test.sh* vmas-11131.img
    eventfd.img fifo.img inventory.img pages-10989.img remap-fpath.img testfile
    • "-t" で dump したいプロセスの PID を指定します."-j" は今回のようにシェルスクリプトを dump/restore する場合に指定します.
    • 以上の dump を実行すると,test.sh は終了します.
      # ./test.sh 
      強制終了
    • 当然ですが,前述の testfile への書き込みは止まっています.
  6. ここでおもむろに restore します.
    # crtools restore -t 10989 -j -vvv > restorelog 2>&1
  7. pstree してみると,
            |                      |-bash(7248)---sudo(8413)---bash(8420)---crtools(11142)---test.sh(10989)---sleep(11234)
    crtools の子供として test.sh が復活しており,testfile を見ると,書き込みも復活しているのがわかります.
  8. crtools を実行したシェルで Ctrl+C してしまうとシェルスクリプトも止まりますので,crtools を kill します.
    # kill 11142
  9. シェルスクリプトを確認すると,init の子供として生き残っています.
    # ps axjf
    1 10989 11142 7248 pts/4 11375 S 0 0:00 /bin/bash ./test.sh
    10989 11374 11142 7248 pts/4 11375 S 0 0:00 \_ sleep 1

とりあえず簡単な dump/restore は出来ました.次回はもう少し複雑なのに挑戦します (多分 ^^;).

(続く)