めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

libgfapiの使い方

libgfapiとは

こちらの記事の図1にあるように、アプリケーションから直接にGlusterFSのボリュームにアクセスするためのAPIを提供するライブラリです。FUSEマウントせずに、直接にボリュームにアクセスできるので性能向上が期待できます。

LevelDBをGlusterFSの上で使えるか試してみる機会があって、FUSEマウント経由では普通に動いたのですが、「libgfapi使ってみたらどうだろう?」という素朴な思いつきで、LevelDBのソースを覗きつついろいろやってみまたした[1]。その際に調べたlibgfapiの使い方をざっくりとメモしておく次第です。

Hello, World!

まずは、「Hello, World!」的なサンプルを動かしてみましょう。前提として、RHEL6.4に次の手順で、開発ツールと「glusterfs-api-devel」を導入しておきます。

# yum install http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
# yum groupinstall "Development Tools"
# yum install glusterfs-api-devel

同じく、別のサーバにて、GlusterFSのボリュームを作成しておきます。ここでは、サーバ「gluster01」、ボリューム「testvol01」とします。FUSEマウントをせずに、このボリュームにファイルを作成するサンプルが次になります。

hellogluster.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glusterfs/api/glfs.h>
 
int main (int argc, char** argv) {
    const char *gfserver = "gluster01";
    const char *gfvol = "testvol01";

    int ret;
    glfs_t *fs;
    glfs_fd_t *fd;
 
    fs = glfs_new(gfvol);   // Virtual filesystem type struct
    glfs_set_volfile_server (fs, "tcp", gfserver, 24007);
    ret = glfs_init (fs);
    if (ret) {
        printf( "Failed to connect server/volume: %s/%s\n", gfserver, gfvol ); 
        exit(ret);
    }

    char *greet = "Hello, Gluster!\n";
    fd = glfs_creat(fs, "greeting.txt", O_RDWR, 0644);
    glfs_write(fd, greet, strlen(greet), 0);
    glfs_close(fd);
    return 0;
}

コンパイルと実行は次の手順です。

# gcc hellogluster.c -lgfapi 
# ./a.out

画面には何も表示されませんが、testvol01を別途、FUSEマウントして確認すると、greeting.txtというファイルができています。

libgfapiの利用の流れ

先のサンプルを見ると、基本的なお作法がすぐに分かります。

はじめにボリューム名を指定して、仮想的にこのボリューム(ファイルシステム)を表す構造体を用意します。

    glfs_t *fs;
    fs = glfs_new(gfvol);   // Virtual filesystem type struct

次の2つの関数で、実際にボリュームを持つGlusterFSサーバに接続します。

    glfs_set_volfile_server (fs, "tcp", gfserver, 24007);
    ret = glfs_init (fs);

これで、通常のファイルシステムにおいてファイルディスクリプタを取得するようなシステムコールのgfapi版を実行できます。次は、ボリューム内のファイルをオープンする例です。

    glfs_fd_t *fd;
    fd = glfs_open(fs, "greeting.txt", O_RDWR, 0644);

第一引数として、先に用意したボリューム(仮想ファイルシステム)を表すポインタが入っている点に注意してください。実際にマウントしているわけではないので、ファイルパスは、このボリュームのルートからのパスになります。この例では、このボリュームのルート上の「greeting.txt」になります。なお、glfs_open()では、O_CREATは使えないので、新規ファイル作成の際は、次のglfs_creat()を使用します。

    fd = glfs_creat(fs, "greeting.txt", O_RDWR, 0644);

当然ながら、一度、ポインタfsを用意すれば、ここから複数のファイルディスクリプタを取得することも可能です。ファイルディスクリプタが取得できれば、これに読み書きするシステムコールのgfapi版が使用できます。次は、挨拶文を書き込んでクローズする例です。

    glfs_write(fd, greet, strlen(greet), 0);
    glfs_close(fd);

glfs_write()の最後の引数は、必要に応じて、「O_ASYNC / O_DIRECT」を指定します。

その他の関数

その他、利用可能なglfs版システムコール(glfs_*)の一覧はヘッダファイル[2]を参照ください。わりとnativeなものが揃っていますが、File Stream系やらmmap系はありません。このあたりは、既存のアプリケーションをgfapi用に書きなおす際は、ちょっと手間がかかるかも知れません。