2018年12月6日木曜日

VDDK API の VixDiskLib_Read と VixDiskLib_Write の挙動を確認してみた

概要

VDDK API にある VixDiskLib_ReadVixDiskLib_Write の挙動を確認してみました
それぞれ vmdk ファイルをセクタ単位で読み込み/書き込みするための API になります

環境

  • CentOS 7
  • VCSA 6.5.0 9451637
  • VDDK API 6.7.1

事前準備

ライブラリの配置、ワークスペースの確認、Makefile の作成などは前回の記事を参考に準備しておいてください

VixDiskLib_Read

まずは挙動を確認してみます

サンプルコード全体

#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;

static void DumpBytes(const unsigned char *buf, size_t n, int step) {
  size_t lines = n / step;
  size_t i;
  for (i = 0; i < lines; i++) {
    int k, last;
    printf("%04" FMTSZ "x : ", i * step);
    for (k = 0; n != 0 && k < step; k++, n--) {
      printf("%02x ", buf[i * step + k]);
    }
    printf("  ");
    last = k;
    while (k --) {
      unsigned char c = buf[i * step + last - k - 1];
      if (c < ' ' || c >= 127) {
        c = '.';
      }
      printf("%c", c);
    }
    printf("\n");
  }
  printf("\n");
}

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", &params.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);

  uint8 *buf = new uint8[VIXDISKLIB_SECTOR_SIZE];
  VixDiskLibSectorType i;
  VixDiskLibSectorType start = 0;
  VixDiskLibSectorType count = 1;
  for (i = 0; i < count; i++) {
      err = VixDiskLib_Read(_handle, start + i, 1, buf);
      DumpBytes(buf, sizeof(buf[0]) * VIXDISKLIB_SECTOR_SIZE, 16);
      // printf("%lu\n", err);
  }
  delete[] buf;

  VixDiskLib_Disconnect(params.connection);
  return 0;
}

大部分は前回と同じなので説明を省略します
DumpBytes はサンプルにあるバッファ情報を出力するための関数でそのままコピペしています 
ポイントは最後のあたりです

uint8 *buf = new uint8[VIXDISKLIB_SECTOR_SIZE];
VixDiskLibSectorType i;
VixDiskLibSectorType start = 0;
VixDiskLibSectorType count = 1;
for (i = 0; i < count; i++) {
    err = VixDiskLib_Read(_handle, start + i, 1, buf);
    DumpBytes(buf, sizeof(buf[0]) * VIXDISKLIB_SECTOR_SIZE, 16);
    // printf("%lu\n", err);
}
delete[] buf;

_handle はその前までで作成した vmdk を操作するためのハンドラになります
buf をあらかじめ定義しておきます
ここに VIXDISKLIB_SECTOR_SIZE byte 分のセクタ領域を count 回読み込んで buf に保存していきます
VIXDISKLIB_SECTOR_SIZEvixDiskLIb.h のヘッダファイルで定義されており 512 となっています
start + i が開始セクタでそこから 1 セクタ分読み込みます (たぶん、、、1 の引数が何を表しているのか調べてもわからず)
つまりセクタを先頭から 1 セクタ (512bytes) の情報を読み込んで buf に保存するサンプルコードになります

count の値を上げていくと次のセクタ情報も表示してくれます

コマンドで実行

サンプルを使って実行する場合は dump コマンドを使います

  • ./vix-disklib-sample -dump -host 192.168.100.20 -user "administrator@vsphere.local" -password 'xxxxxxxxx' -mode nbdssl -vm "moref=vm-10" -ssmoref "" -thumb "96:09:d6:5b:e0:83:58:1b:ba:2b:cc:78:22:88:33:36:64:50:32:eb" "[datastore1] vm01/vm01.vmdk"

実行結果は先程コードで実行した情報と同じものが表示されます

Disk[0] "[datastore1] vm01/vm01.vmdk" is opened using transport mode "nbd".
0000 : eb 63 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0   .c..............
0010 : fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00   ...|.........!..
0020 : 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75   ....8.u........u
0030 : f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b   .........|...t..
0040 : 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00   L.....|.........
0050 : 00 00 00 00 00 00 00 00 00 00 00 80 01 00 00 00   ................
0060 : 00 00 00 00 ff fa 90 90 f6 c2 80 74 05 f6 c2 70   ...........t...p
0070 : 74 02 b2 80 ea 79 7c 00 00 31 c0 8e d8 8e d0 bc   t....y|..1......
0080 : 00 20 fb a0 64 7c 3c ff 74 02 88 c2 52 bb 17 04   . ..d|<.t...R...
0090 : f6 07 03 74 06 be 88 7d e8 17 01 be 05 7c b4 41   ...t...}.....|.A
00a0 : bb aa 55 cd 13 5a 52 72 3d 81 fb 55 aa 75 37 83   ..U..ZRr=..U.u7.
00b0 : e1 01 74 32 31 c0 89 44 04 40 88 44 ff 89 44 02   ..t21..D.@.D..D.
00c0 : c7 04 10 00 66 8b 1e 5c 7c 66 89 5c 08 66 8b 1e   ....f..\|f.\.f..
00d0 : 60 7c 66 89 5c 0c c7 44 06 00 70 b4 42 cd 13 72   `|f.\..D..p.B..r
00e0 : 05 bb 00 70 eb 76 b4 08 cd 13 73 0d 5a 84 d2 0f   ...p.v....s.Z...
00f0 : 83 d0 00 be 93 7d e9 82 00 66 0f b6 c6 88 64 ff   .....}...f....d.
0100 : 40 66 89 44 04 0f b6 d1 c1 e2 02 88 e8 88 f4 40   @f.D...........@
0110 : 89 44 08 0f b6 c2 c0 e8 02 66 89 04 66 a1 60 7c   .D.......f..f.`|
0120 : 66 09 c0 75 4e 66 a1 5c 7c 66 31 d2 66 f7 34 88   f..uNf.\|f1.f.4.
0130 : d1 31 d2 66 f7 74 04 3b 44 08 7d 37 fe c1 88 c5   .1.f.t.;D.}7....
0140 : 30 c0 c1 e8 02 08 c1 88 d0 5a 88 c6 bb 00 70 8e   0........Z....p.
0150 : c3 31 db b8 01 02 cd 13 72 1e 8c c3 60 1e b9 00   .1......r...`...
0160 : 01 8e db 31 f6 bf 00 80 8e c6 fc f3 a5 1f 61 ff   ...1..........a.
0170 : 26 5a 7c be 8e 7d eb 03 be 9d 7d e8 34 00 be a2   &Z|..}....}.4...
0180 : 7d e8 2e 00 cd 18 eb fe 47 52 55 42 20 00 47 65   }.......GRUB .Ge
0190 : 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 65 61   om.Hard Disk.Rea
01a0 : 64 00 20 45 72 72 6f 72 0d 0a 00 bb 01 00 b4 0e   d. Error........
01b0 : cd 10 ac 3c 00 75 f4 c3 8f f0 6c c8 00 00 80 20   ...<.u....l....
01c0 : 21 00 83 35 37 3e 00 08 00 00 00 38 0f 00 00 35   !..57>.....8...5
01d0 : 38 3e 82 8e 51 3d 00 40 0f 00 00 98 3e 00 00 8e   8>..Q=.@....>...
01e0 : 52 3d 83 fe ff ff 00 d8 4d 00 00 20 72 03 00 00   R=......M.. r...
01f0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa   ..............U.

VixDiskLib_Write

今回のサンプルは fill コマンドを元に作成しています
vmdk に異常なデータを書き込む操作になるので実行する際には十分注意して実行してください
もちろん fill のようなコマンドではなく正常なセクタデータを書き込むことも可能です

サンプルコード全体

#include <iostream>
#include <cstring>
#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-20"};
  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", &params.connection);
  printf("%lu\n", err);

  VixDiskLibHandle _handle = NULL;
  err = VixDiskLib_Open(params.connection, "[datastore1] wtest/wtest.vmdk", VIXDISKLIB_FLAG_OPEN_SINGLE_LINK , &_handle);
  printf("%lu\n", err);

  uint8 *buf = new uint8[VIXDISKLIB_SECTOR_SIZE];
  VixDiskLibSectorType wstart;
  VixDiskLibSectorType start = 0;
  VixDiskLibSectorType count = 1;
  int filler = 0xff;
  memset(buf, filler, sizeof(buf[0]) * VIXDISKLIB_SECTOR_SIZE);
  for (wstart = 0; wstart < count; ++wstart) {
    err = VixDiskLib_Write(_handle, start + wstart, 1, buf);
    printf("%lu\n", err);
  }
  delete[] buf;

  VixDiskLib_Disconnect(params.connection);
  return 0;
}

少し細かいですが初期化の部分も変わっています
memset を使うので <cstring> を include しています
また、vmdk に対して write の処理を行うので ReadOnly で接続していた部分を書き込み可能なオプションで開くようにしています
具体的には VixDiskLib_Open でオプションを VIXDISKLIB_FLAG_OPEN_SINGLE_LINK に変更しています

err = VixDiskLib_Open(params.connection, "[datastore1] wtest/wtest.vmdk", VIXDISKLIB_FLAG_OPEN_SINGLE_LINK , &_handle);

そして肝心の書き込み (VixDiskLib_Write) 部分ですが以下になります

uint8 *buf = new uint8[VIXDISKLIB_SECTOR_SIZE];
VixDiskLibSectorType wstart;
VixDiskLibSectorType start = 0;
VixDiskLibSectorType count = 1;
int filler = 0xff;
memset(buf, filler, sizeof(buf[0]) * VIXDISKLIB_SECTOR_SIZE);
for (wstart = 0; wstart < count; ++wstart) {
  err = VixDiskLib_Write(_handle, start + wstart, 1, buf);
  printf("%lu\n", err);
}
delete[] buf;

基本的な流れは VixDiskLib_Read と同じで書き込み開始セクタを指定してそこから書き込むセクタ分ループさせているだけです
一回で書き込むデータ量は Read 時と同じで VIXDISKLIB_SECTOR_SIZE (512) を指定しています
書き込むデータは buf 変数に入っているデータ になります
今回は memset にあるように filler = 0xff で buf を作っているのですべて 0xff で上書きされます
上記のサンプルで実行すると先頭セクタから 1 セクタ分 512 bytes が 0xff で上書きされます

実際に実行した結果の比較は以下でしています

コマンドで実行

先程の dump の代わりに fill オプションを使うだけです
デフォルトでは上記同様 0xff で上書きします

  • ./vix-disklib-sample -fill -host 192.168.100.20 -user "administrator@vsphere.local" -password 'xxxxxxxxx' -mode nbdssl -vm "moref=vm-10" -ssmoref "" -thumb "96:09:d6:5b:e0:83:58:1b:ba:2b:cc:78:22:88:33:36:64:50:32:eb" "[datastore1] wtest/wtest.vmdk"

実行する前と後で先頭セクタを比較したのは以下です

0000 : eb 63 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0   .c..............
0010 : fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00   ...|.........!..
0020 : 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75   ....8.u........u
0030 : f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b   .........|...t..
0040 : 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00   L.....|.........
0050 : 00 00 00 00 00 00 00 00 00 00 00 80 01 00 00 00   ................
0060 : 00 00 00 00 ff fa 90 90 f6 c2 80 74 05 f6 c2 70   ...........t...p
0070 : 74 02 b2 80 ea 79 7c 00 00 31 c0 8e d8 8e d0 bc   t....y|..1......
0080 : 00 20 fb a0 64 7c 3c ff 74 02 88 c2 52 bb 17 04   . ..d|<.t...R...
0090 : f6 07 03 74 06 be 88 7d e8 17 01 be 05 7c b4 41   ...t...}.....|.A
00a0 : bb aa 55 cd 13 5a 52 72 3d 81 fb 55 aa 75 37 83   ..U..ZRr=..U.u7.
00b0 : e1 01 74 32 31 c0 89 44 04 40 88 44 ff 89 44 02   ..t21..D.@.D..D.
00c0 : c7 04 10 00 66 8b 1e 5c 7c 66 89 5c 08 66 8b 1e   ....f..\|f.\.f..
00d0 : 60 7c 66 89 5c 0c c7 44 06 00 70 b4 42 cd 13 72   `|f.\..D..p.B..r
00e0 : 05 bb 00 70 eb 76 b4 08 cd 13 73 0d 5a 84 d2 0f   ...p.v....s.Z...
00f0 : 83 d0 00 be 93 7d e9 82 00 66 0f b6 c6 88 64 ff   .....}...f....d.
0100 : 40 66 89 44 04 0f b6 d1 c1 e2 02 88 e8 88 f4 40   @f.D...........@
0110 : 89 44 08 0f b6 c2 c0 e8 02 66 89 04 66 a1 60 7c   .D.......f..f.`|
0120 : 66 09 c0 75 4e 66 a1 5c 7c 66 31 d2 66 f7 34 88   f..uNf.\|f1.f.4.
0130 : d1 31 d2 66 f7 74 04 3b 44 08 7d 37 fe c1 88 c5   .1.f.t.;D.}7....
0140 : 30 c0 c1 e8 02 08 c1 88 d0 5a 88 c6 bb 00 70 8e   0........Z....p.
0150 : c3 31 db b8 01 02 cd 13 72 1e 8c c3 60 1e b9 00   .1......r...`...
0160 : 01 8e db 31 f6 bf 00 80 8e c6 fc f3 a5 1f 61 ff   ...1..........a.
0170 : 26 5a 7c be 8e 7d eb 03 be 9d 7d e8 34 00 be a2   &Z|..}....}.4...
0180 : 7d e8 2e 00 cd 18 eb fe 47 52 55 42 20 00 47 65   }.......GRUB .Ge
0190 : 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 65 61   om.Hard Disk.Rea
01a0 : 64 00 20 45 72 72 6f 72 0d 0a 00 bb 01 00 b4 0e   d. Error........
01b0 : cd 10 ac 3c 00 75 f4 c3 8f f0 6c c8 00 00 80 20   ...<.u....l....
01c0 : 21 00 83 35 37 3e 00 08 00 00 00 38 0f 00 00 35   !..57>.....8...5
01d0 : 38 3e 82 8e 51 3d 00 40 0f 00 00 98 3e 00 00 8e   8>..Q=.@....>...
01e0 : 52 3d 83 fe ff ff 00 d8 4d 00 00 20 72 03 00 00   R=......M.. r...
01f0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa   ..............U.
0000 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0010 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0020 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0030 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0040 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0050 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0060 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0070 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0080 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0090 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00a0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00b0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00c0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00d0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00e0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
00f0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0100 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0110 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0120 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0130 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0140 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0150 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0160 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0170 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0180 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
0190 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
01a0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
01b0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
01c0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
01d0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
01e0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................
01f0 : ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff   ................

こんな感じで 1 セクタ (512 bytes) 分すべてが 0xff で上書きされています
ちなみに元の vmdk は Ubuntu18 の vmdk だったのですが fill 後は正常に VM を起動できなくなりました

最後に

VDDK API の VixDiskLib_ReadVixDiskLib_Write の挙動を確認してみた
基本はどちらもセクタ単位で読み込み/書き込みができる API でした
使い方はいろいろあると思いますが、vixDiskLibSample.cpp に CopyThread という関数が実装されています
内容は source から destination の vmdk に対して同じないようのバッファを上書きしています
単純なコピー作業のようなコードになっています
おそらくはそのような感じで source/destination の 2 つの vmdk を対象に使う API なのかなと思います

0 件のコメント:

コメントを投稿