Walk-Through of Sample Program
The sample program is the same for Windows as for Linux, with #ifdef blocks for Win32.
Include Files
Windows dynamic link library (DLL) declarations are in process.h, while Linux shared object (.so) declarations are in dlfcn.h. Windows offers the tchar.h extension for Unicode generic text mappings, not readily available in Linux.
Definitions and Structures
The sample program uses twelve bitwise shift operations (1 << 11) to track its available commands and the multithread option. The Virtual Disk API has about 30 library functions, some for initialization and cleanup. The following library functions are not demonstrated in the sample program:
The sample program transmits state in the appGlobals structure.
Dynamic Loading
The #ifdef DYNAMIC_LOADING block is long, starting on line 97 and ending at line 339. This block contains function definitions for dynamic loading. It also contains the LoadOneFunc() procedure to obtain any requested function from the dynamic library and the DynLoadDiskLib() procedure to bind it. This demonstration feature could also be called “runtime loading” to distinguish it from dynamic linking.
To try the program with runtime loading enabled on Linux, add -DDYNAMIC_LOADING after g++ in the Makefile and recompile. On Windows, define DYNAMIC_LOADING in the project.
Wrapper Classes
Below the dynamic loading block are two wrapper classes, one for error codes and descriptive text, and the other for the connection handle to disk.
The error wrapper appears in catch and throw statements to simplify error handling across functions.
Wrapper class VixDisk is a clean way to open and close connections to disk. The only time that library functions VixDiskLib_Open() and VixDiskLib_Close() appear elsewhere, aside from dynamic loading, is in the CopyThread() function near the end of the sample program.
Command Functions
The print-usage message appears next, with output partially shown in Usage Message.
Next comes the main() function, which sets defaults and parses command-line arguments to determine the operation and possibly set options to change defaults. Dynamic loading occurs, if defined. Notice the all-zero initialization of the VixDiskLibConnectParams declared structure:
VixDiskLibConnectParams cnxParams = {0};
For connections to an ESXi host, credentials including user name and password must be correctly supplied in the -user and -password command-line arguments. Both the -host name of the ESXi host and its -vm inventory path (vmxSpec) must be supplied. When set, these values populate the cnxParams structure. Initialize all parameters, especially vmxSpec, or else the connection might behave unexpectedly.
A call to VixDiskLib_Init() initializes the library. In a production application, you can supply appropriate log, warn, and panic functions as parameters, in place of NULL.
A call to VixDiskLib_Connect() creates a connection to disk. If host cnxParams.serverName is null, as it is without the -host argument, a connection is made to hosted disk on the local host. Otherwise a connection is made to managed disk on the remote host. With -ssmoref argument, advanced transport is used.
Next, an appropriate function is called for the requested operation, followed by error information if applicable. Finally, the main() function closes the library connection to disk and exits.
DoInfo()
This procedure calls VixDiskLib_GetInfo() for information about the virtual disk, displays results, and calls VixDiskLib_FreeInfo() to reclaim memory. The parameter disk.Handle() comes from the VixDisk wrapper class discussed in Wrapper Classes.
In this example, the sample program connects to an ESXi host named esx5 and displays virtual disk information for a Red Hat Enterprise Linux client. For an ESXi host, path to disk is often something like [datastore1] followed by the virtual machine name and the VMDK filename.
vix-diskLib-sample -info -host esx5 -user root -password secret "[datastore1] RHEL6/RHEL6.vmdk"
Disk "[datastore1] RHEL6/RHEL6.vmdk" is open using transport mode "nbd".
capacity = 4194304 sectors
number of links = 1
adapter type = LsiLogic SCSI
BIOS geometry = 0/0/0
physical geometry = 261/255/63
Transport modes supported by vixDiskLib: file:nbdssl:nbd
If you multiply physical geometry numbers (261 cylinders * 255 heads per cylinder * 63 sectors per head) the result is a capacity of 4192965 sectors, although the first line says 4194304. A small discrepancy is possible due to rounding. In general, you get at least the capacity that you requested. The number of links specifies the separation of a child from its original parent in the disk chain (redo logs), starting at one. The parent has one link, its child has two links, the grandchild has three links, and so forth.
DoCreate()
This procedure calls VixDiskLib_Create() to allocate virtual disk. Adapter type is SCSI unless specified as IDE on the command line. Size is 100MB, unless set by -cap on the command line. Because the sector size is 512 bytes, the code multiplies appGlobals.mbsize by 2048 instead of 1024. Type is always monolithic sparse and Workstation 5. In a production application, progressFunc and callback data can be defined rather than NULL. Type these commands to create a sample VMDK file (the first line is for Linux only):
export LD_LIBRARY_PATH=/usr/lib/vmware-vix-disklib/lib64
vix-disklib-sample -create sample.vmdk
As a VMDK file, monolithic sparse (growable in a single file) virtual disk is initially 65536 bytes (2 ^ 16) in size, including overhead. The first time you write to this type of virtual disk, as with DoFill() below, the VMDK expands to 131075 bytes (2 ^ 17), where it remains until more space is needed. You can verify file contents with the -dump option.
DoRedo()
This procedure calls VixDiskLib_CreateChild() to establish a redo log. A child disk records disk sectors that changed since the parent disk or previous child. Children can be chained as a set of redo logs.
The sample program does not demonstrate use of VixDiskLib_Attach(), which you can use to access a link in the disk chain. VixDiskLib_CreateChild() establishes a redo log, with the child replacing the parent for read/write access. Given a pre-existing disk chain, VixDiskLib_Attach() creates a related child, or a cousin you might say, that is linked into some generation of the disk chain.
For a diagram of the attach operation, see Child Disks Created from Parent.
Write by DoFill()
This procedure calls VixDiskLib_Write() to fill a disk sector with ones (byte value FF) unless otherwise specified by -val on the command line. The default is to fill only the first sector, but this can be changed with options -start and -count on the command line.
DoReadMetadata()
This procedure calls VixDiskLib_ReadMetadata() to serve the -rmeta command-line option. For example, type this command to obtain the universally unique identifier:
vix-disklib-sample -rmeta uuid sample.vmdk
DoWriteMetadata()
This procedure calls VixDiskLib_WriteMetadata() to serve the -wmeta command-line option. For example, you can change the tools version from 1 to 2 as follows:
vix-disklib-sample -wmeta toolsVersion 2 sample.vmdk
DoDumpMetadata()
This procedure calls VixDiskLib_GetMetadataKeys() then VixDiskLib_ReadMetadata() to serve the -meta command-line option. Two read-metadata calls are needed for each key: one to determine length of the value string and another to fill in the value. See Get Metadata Table from Disk.
In the following example, the sample program connects to an ESXi host named esx3 and displays the metadata of the Red Hat Enterprise Linux client’s virtual disk. For an ESXi host, path to disk might be [storage1] followed by the virtual machine name and the VMDK filename.
vix-diskLib-sample -meta -host esx3 -user admin -password secret “[storage1]RHEL5/RHEL5.vmdk"
geometry.sectors = 63
geometry.heads = 255
geometry.cylinders = 522
adapterType = buslogic
toolsVersion = 1
virtualHWVersion = 7
Tools version and virtual hardware version appear in the metadata, but not in the disk information retrieved by DoInfo(). Geometry information and adapter type are repeated, but in a different format. Other metadata items not listed above might exist.
DoDump()
This procedure calls VixDiskLib_Read() to retrieve sectors and displays sector contents on the output in hexadecimal. The default is to dump only the first sector numbered zero, but you can change this with the -start and -count options. Here is a sequence of commands to demonstrate:
vix-disklib-sample -create sample.vmdk
vix-disklib-sample -fill -val 1 sample.vmdk
vix-disklib-sample -fill -val 2 -start 1 -count 1 sample.vmdk
vix-disklib-sample -dump -start 0 -count 2 sample.vmdk
od -c sample.vmdk
On Linux (or Cygwin) you can run the od command to show overhead and metadata at the beginning of file, and the repeated ones and twos in the first two sectors. The -dump option of the sample program shows only data, not overhead.
DoTestMultiThread()
This procedure employs the Windows thread library to make multiple copies of a virtual disk file. Specify the number of copies with the -multithread command-line option. For each copy, the sample program calls the CopyThread() procedure, which in turn calls a sequence of six Virtual Disk API routines.
On Linux the multithread option is unimplemented.
DoClone()
This procedure calls VixDiskLib_Clone() to make a copy of the data on virtual disk. A callback function, supplied as the sixth parameter, displays the percent of cloning completed. For local hosted disk, the adapter type is SCSI unless specified as IDE on the command line, size is 200MB, unless set by -cap option, and type is monolithic sparse, for Workstation 5. For an ESXi host, adapter type is taken from managed disk itself, using the connection parameters established by VixDiskLib_Connect().
The final parameter TRUE means to overwrite if the destination VMDK exists.
The clone option is an excellent backup method. Often the cloned virtual disk is smaller, because it can be organized more efficiently. Moreover, a fully allocated flat file can be converted to a sparse representation.
SSL Certificate Thumbprint
The sample program in the VDDK 5.1 release added the -thumb option to allow an SSL certificate thumbprint to be provided and used. The thumbprint is used for authentication through vCenter Server.