LXCをC言語から操作する②(コンテナの場所、ファイルシステムを指定)

LXCをC言語から操作する①でC言語からコンテナの作成、起動、終了、削除までをサンプルコードベースで動かしてみました。

今度はちょっとオプションを変えて、rootfsの設定と、コンテナの場所を変えてみます。

lxc_container_newの第2引数が設定ファイルなどのパスになります。

createlの第2引数がrootfsのファイルタイプになります。NULLにしておくとdirになります。今回はloopデバイス(イメージファイル)を指定します。

第2引数を指定する場合、第3引数にはbdev_specs構造体のポインタを指定する必要があります。bdev_specs構造体はデバイスの設定になります。

loopデバイスの場合、fstypeにファイルシステムの種別、fssizeにバイト単位でファイルシステムのサイズを指定します。

#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <memory>
#include <lxc/lxccontainer.h>

#define SIZE_FSTYPE 16

int main() {
    struct lxc_container* c;
    int ret = 1;
    const char* pszDevType = "loop";
    std::unique_ptr<bdev_specs> pstSpecs(new bdev_specs);
    memset(pstSpecs.get(), 0x00, sizeof(bdev_specs));
    pstSpecs->fstype = new char[SIZE_FSTYPE];

    strncpy(pstSpecs->fstype, "ext4", SIZE_FSTYPE-1);
    pstSpecs->fssize =        1024*1024*1024*1;

    /* Setup container struct */
    c = lxc_container_new("apicontainer", "/shared/lxc");
    if (!c) {
        fprintf(stderr, "Failed to setup lxc_container struct\n");
        goto out;
    }

    if (c->is_defined(c)) {
        fprintf(stderr, "Container already exists\n");
        goto out;
    }

    /* Create the container */
    if (!c->createl(c, "download", pszDevType, pstSpecs.get(), LXC_CREATE_QUIET,
                    "-d", "centos", "-r", "9-Stream", "-a", "amd64", NULL)) {
        fprintf(stderr, "Failed to create container rootfs\n");
        goto out;
    }

    /* Start the container */
    if (!c->start(c, 0, NULL)) {
        fprintf(stderr, "Failed to start the container\n");
        goto out;
    }

    /* Query some information */
    printf("Container state: %s\n", c->state(c));
    printf("Container PID: %d\n", c->init_pid(c));

    /* Stop the container */
    if (!c->shutdown(c, 30)) {
        printf("Failed to cleanly shutdown the container, forcing.\n");
        if (!c->stop(c)) {
            fprintf(stderr, "Failed to kill the container.\n");
            goto out;
        }
    }

    /* Destroy the container */
    if (!c->destroy(c)) {
        fprintf(stderr, "Failed to destroy the container.\n");
        goto out;
    }

    ret = 0;
    if(pstSpecs->fstype != nullptr){
        delete[] pstSpecs->fstype;
    }
    
out:
    lxc_container_put(c);
    return ret;
}

コードを上記のように書き換えて、コンパイルします。

# g++ -llxc lxctest.cpp -o lxctest

実行中に、/shared/lxcを確認すると、以下のようにrootfsが1GBのディスクイメージになっているのが確認できると思います

# cd /shared/lxc/apicontainer
# ll
total 474888
-rw-r----- 1 nobody nobody        798 Oct  7 21:57 config
-rw------- 1 nobody nobody 1073741825 Oct  7 21:57 rootdev
drwxr-xr-x 2 nobody nobody          6 Oct  7 21:57 rootfs

とりあえずはC++からオプションを指定しつつ、コンテナを動かせました。

ただ、C言語のAPIとあるだけあって、APIに渡すパラメータが構造体になるだけあって、ちょっと使いにくいですね。クラスにラッパーしたいですね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)