概要
前回はサンプルをコンパイルして実行してみました
今回はサンプルコードのように自分で VDDK API を使ったアプリを作成して動かしてみました
なるべくわかりやすいようにシンプルに作っています
全体を通して API Reference はこれが参考になると思います
が上記も情報がかなり少ないので頑張ってググるか Code の VMware Community を見たりすると解決できるかもしれません (が、基本は情報が少ないのでサンプルと格闘する時間が長くなると思います)
環境
- CentOS 7
- VCSA 6.5.0 9451637
- VDDK API 6.7.1
サンプルコード全体
今回のサンプルは vmdk の情報を取得するサンプルになります
ほぼ同じ手順で別の API もコールできます
mkdir -p vmware-vix-disklib-distrib/doc/samples/firstLib
cd vmware-vix-disklib-distrib/doc/samples/firstLib
- vim firstLib.cpp
#include <iostream>
#include "vixDiskLib.h"
using std::cout;
using std::endl;
#define VIXDISKLIB_VERSION_MAJOR 6
#define VIXDISKLIB_VERSION_MINOR 7
static struct {
VixDiskLibConnection connection;
char *libdir;
char *cfgFile;
} params;
int main() {
VixError err;
err = VixDiskLib_InitEx(VIXDISKLIB_VERSION_MAJOR, VIXDISKLIB_VERSION_MINOR, NULL, NULL, NULL, params.libdir, params.cfgFile);
printf("%lu\n", err);
VixDiskLibConnectParams cnxParams = {0};
cnxParams.vmxSpec = {(char*)"moref=vm-10"};
cnxParams.specType = VIXDISKLIB_SPEC_VMX;
cnxParams.serverName = {(char*)"192.168.100.20"};
cnxParams.credType = VIXDISKLIB_CRED_UID;
cnxParams.creds.uid.userName = {(char*)"administrator@vsphere.local"};
cnxParams.creds.uid.password = {(char*)"xxxxxxxx"};
cnxParams.thumbPrint = {(char*)"96:09:d6:5b:e0:83:58:1b:ba:2b:cc:78:22:88:33:36:64:50:32:eb"};
err = VixDiskLib_ConnectEx(&cnxParams, 1, NULL, "nbd", ¶ms.connection);
printf("%lu\n", err);
VixDiskLibHandle _handle = NULL;
err = VixDiskLib_Open(params.connection, "[datastore1] vm01/vm01.vmdk", VIXDISKLIB_FLAG_OPEN_READ_ONLY, &_handle);
printf("%lu\n", err);
VixDiskLibInfo *info = NULL;
err = VixDiskLib_GetInfo(_handle, &info);
printf("%lu\n", err);
cout << "capacity = " << info->capacity << " sectors" << endl;
cout << "number of links = " << info->numLinks << endl;
cout << "adapter type = ";
switch (info->adapterType) {
case VIXDISKLIB_ADAPTER_IDE:
cout << "IDE" << endl;
break;
case VIXDISKLIB_ADAPTER_SCSI_BUSLOGIC:
cout << "BusLogic SCSI" << endl;
break;
case VIXDISKLIB_ADAPTER_SCSI_LSILOGIC:
cout << "LsiLogic SCSI" << endl;
break;
default:
cout << "unknown" << endl;
break;
}
cout << "BIOS geometry = " << info->biosGeo.cylinders <<
"/" << info->biosGeo.heads << "/" << info->biosGeo.sectors << endl;
cout << "physical geometry = " << info->physGeo.cylinders <<
"/" << info->physGeo.heads << "/" << info->physGeo.sectors << endl;
VixDiskLib_FreeInfo(info);
cout << "Transport modes supported by vixDiskLib: " <<
VixDiskLib_ListTransportModes() << endl;
VixDiskLib_Disconnect(params.connection);
return 0;
}
以下で細かく開設します
解説
最終的に vmdk から情報を取得するための API は VixDiskLib_GetInfo
になります
これをコールするために必ず通る道があります
VixDiskLib_InitEx
VixDiskLib_ConnectEx
VixDiskLib_Open
を順番に実行します
また最後に VixDiskLib_Disconnect
を実行します
VixDiskLib_InitEx
まず VixDiskLib_InitEx
です
以下のように呼び出しています
err = VixDiskLib_InitEx(VIXDISKLIB_VERSION_MAJOR, VIXDISKLIB_VERSION_MINOR, NULL, NULL, NULL, params.libdir, params.cfgFile);`
VIXDISKLIB_VERSION_MAJOR
と VIXDISKLIB_VERSION_MINOR
はマクロとしてコード内で定義します
VDDK API のバージョンを管理するだけなので今回は 6.7 なので「6」「7」を格納します
次から 3 つの引数 NULL ですがこれはログ出力用のコールバックメソッドを指定することができます
ここでは紹介しませんが VDDK API 側の実行ログを細かくみたい場合は指定してください
次の 2 つの params.libdir
と params.cfgFile
はオプショナルなので今回は何も指定していません
定義自体は struct でコードの先頭で行っています
VixDiskLib_ConnectEx
次に VixDiskLib_ConnectEx
です
これは vCenter に対しての接続を確立するための API です
VixDiskLibConnectParams cnxParams = {0};
cnxParams.serverName = {(char*)"192.168.100.20"};
cnxParams.credType = VIXDISKLIB_CRED_UID;
cnxParams.creds.uid.userName = {(char*)"administrator@vsphere.local"};
cnxParams.creds.uid.password = {(char*)"xxxxxxxx"};
cnxParams.thumbPrint = {(char*)"96:09:d6:5b:e0:83:58:1b:ba:2b:cc:78:22:88:33:36:64:50:32:eb"};
cnxParams.vmxSpec = {(char*)"moref=vm-10"};
cnxParams.specType = VIXDISKLIB_SPEC_VMX;
err = VixDiskLib_ConnectEx(&cnxParams, 1, NULL, "nbd", ¶ms.connection);
認証情報などは VixDiskLibConnectParams
クラスの変数に格納していきます
上記の場合は ID/PW による認証ですが session を使った認証もあるので詳しくはリファレンスを見てください
上記で設定しているのではすべて必須になります
serverName
は vCenter の IP アドレスを設定します
credType
は ID/PW 認証の場合 VIXDISKLIB_CRED_UID
を指定します
VIXDISKLIB_CRED_UID
は VDDK API 側に定義されているマクロです
creds.uid.userName
は vCenter にアクセスするユーザを指定します
creds.uid.password
は vCenter にアクセスするユーザのパスワードを指定します
thumbPrint
は SSL 証明書を使っていない場合に必要になります
ブラウザなどで確認できるので各自の vCenter にアクセスしてそれを入力してください
ここまでが認証情報です
あとの vmxSpec
と specType
はアクセスする vmdk の主である VM を指定します
vmxSpec
は少し特殊な方法で指定します
vCenter からみたときの対象の VM の MoRef (Managed Object Reference) ID を指定します
ポイントは vCenter から見たときの MoRef という点で ESXi から見たときと値が異なります
vm-
で始まる MoRef を指定しましょう
また当然ですが取得したい vmdk の主とは異なる VM の MoRef を指定してもエラーになるので注意してください
あとの引数 1
, NULL
, "nbd"
, ¶ms.connection
はそれぞれ ReadOnly かどうか (1 の場合は ReadOnly)、スナップショット ID、アクセスモード、コネクションになります
成功すると params.connection
が使えるようになります
VixDiskLib_Open
3 つ目の VixDiskLib_Open
は対象のディスクにアクセスするための API です
ここで対象の vmdk があるパスを指定します
VixDiskLibHandle _handle = NULL;
err = VixDiskLib_Open(params.connection, "[datastore1] vm01/vm01.vmdk", VIXDISKLIB_FLAG_OPEN_READ_ONLY, &_handle);
先程設定された params.connection
を使ってアクセスします
2 つ目の引数が vmdk のパスになります
フォーマットは Web Cilent でストレージのファイルブラウザで見たときのパスをそのまま入力します
VIXDISKLIB_FLAG_OPEN_READ_ONLY
は ReadOnly かどうかのフラグになります
そして最後の _handle
は vmdk にアクセスするためのハンドラになります
情報を取得する際にはこのハンドラを使ってアクセスします
先程の params.connection
と同じで成功すると _handle
が使えるようになります
VixDiskLib_GetInfo
そして最後の VixDiskLib_GetInfo
で情報を取得します
成功すると VixDiskLibInfo
の変数にいろいろと情報が格納されます
VixDiskLibInfo *info = NULL;
err = VixDiskLib_GetInfo(_handle, &info);
このあとのコードで cout
, endl
で囲まれたコードがたくさん出てきますがこれは info の情報を標準出力に出すためのコードです
サンプルにあったものをそのまま使っているのでここは好きなように編集してもらって大丈夫です
そして出力後に VixDiskLib_FreeInfo
をコールしていますがこれは情報を取得するときに使用したメモリを開放するためにコールします
メモリリークの発生を抑えるためにコールします
コンパイルする
コンパイルする場所は VDDK のサンプルがあるパスで行います
そこじゃなくてもいいですが Makefile もありそれをそのまま流用できるので使うと楽です
cd vmware-vix-disklib-distrib/doc/samples/firstLib
- vim Makefile
INCLUDEDIR=../../../include
LIBDIR=../../../lib64
LIBS=-ldl -lz -lsqlite3 -lcurl -lssl -lcrypto
ifdef VIX_AIO_BUFPOOL_SIZE
CXXFLAGS+= -DVIX_AIO_BUFPOOL_SIZE=$(VIX_AIO_BUFPOOL_SIZE)
endif
GCC_MAJOR_VER_GTEQ_4_8 := $(shell expr `$(CXX) -dumpversion | cut -f1,2 -d.` \>= 4.8)
ifeq "$(GCC_MAJOR_VER_GTEQ_4_8)" "1"
# this version support C++11
CXXFLAGS+= -std=c++11 -lpthread
else
# use boost libs
CXXFLAGS+= -lboost_system-gcc41-mt-1_42 -lboost_thread-gcc41-mt-1_42
endif
all: first-lib
first-lib: firstLib.cpp
$(CXX) $(CXXFLAGS) -o $@ -I$(INCLUDEDIR) -L$(LIBDIR) $? $(LIBS) -lvixDiskLib
clean:
$(RM) -f first-lib
- make
で特にエラーにならなければ OK です
CentOS7 であれば特に必要なライブラリを別途インストール必要もなくコンパイルできると思います
実行
./first-lib
で OK です
以下のように表示されると思います
0
0
0
0
capacity = 62914560 sectors
number of links = 1
adapter type = LsiLogic SCSI
BIOS geometry = 0/0/0
physical geometry = 3916/255/63
Transport modes supported by vixDiskLib: file:nbdssl:nbd
0 の部分は各 API が返却する VixError 変数の値を表示しています
0 が正常終了なのでここが 0 以外であれば何かしら間違っているので修正する必要があります
自分の場合一番ハマったのは VixDiskLib_ConnectEx
でした
パラメータの指定に vmxSpec
が必須なのがどこにも記載がなくTry&Error を繰り返して判明しました
また初めは vCenter ではなく ESXi にアクセスしようとしていたのですが、それだとうまく行きませんでした
ドキュメントには ESXi でもいけるとあるのですがどうやってもできなかったので諦めて vCenter にアクセスするようにしました
最後に
VDDK API を使って vmdk にアクセスするサンプルコードを作ってみました
もしかしたら探せば同じようなコードが出てくるかもしれませんが自分の中では、ここで紹介している記事しかないかなと思います (少なくとも日本語では)
ググって調べるといろいろ分かるのですがこの VDDK API はベンダー製品や OSS 製品でも使われているようです
それらで使われている方法を参考にするのも良いかもしれません
ただ全体として VDDK API の情報はかなり少ないと思います
自分からも少しでも情報発信できればと思います
0 件のコメント:
コメントを投稿