/* **************************************************************************** * Copyright 2009-2020 VMware, Inc. All rights reserved. -- VMware Confidential * * vixDiskLibNasPlugin.h -- * * Interface for NAS plugins into disklib. * A NAS plugin consists of an API frontend exporting the following entry * points: * o init_session * o execute_primitive * o end_session * * The following functions are available for NAS plugins to call: * o complete_primitive * * Please refer to the "vStorage API Architecture and Specification" document * for more detailed information. * * ***************************************************************************** */ #ifndef __VIXDISKLIBNASPLUGIN__ #define __VIXDISKLIBNASPLUGIN__ #include "vixDiskLibPlugin.h" #if defined(__cplusplus) extern "C" { #endif /* * Current major and minor version of the DiskLib NAS Plugin interface as * described by this header file. */ #define VIXDISKLIB_NASPLUGIN_MAJOR_VERSION 1 #define VIXDISKLIB_NASPLUGIN_MINOR_VERSION 2 #define VIXDISKLIB_NASPLUGIN_FSTYPE_NFS "NFS" #define VIXDISKLIB_NASPLUGIN_FSTYPE_NFS41 "NFS41" #define VIXDISKLIB_NASPLUGIN_FSTYPE_VMFS "VMFS" #define VIXDISKLIB_NASPLUGIN_FSTYPE_VMFSL "VMFS-L" typedef struct { /* * String containing the ESX file-system type. * E.g. "VMFS" or "NFS". */ char *fsType; /* * File-system's ESX major version. */ uint32 fsVersion; /* * String with the IP address of the NAS server or * NULL if file-system is not of the NAS type. */ char *remoteIP; /* * String with the remote mount point on the NAS server or * NULL if file-system is not of the NAS type. */ char *remoteMountPoint; /* * Path to the ESX local mount point for the file-system. * E.g. "/vmfs/volumes/xyz" */ char *localMountPoint; } VixDiskLibNasPluginDataStoreParams; typedef struct { /* * Session Network timeout. * The plugin should fail any operation in progress (session establishment * or execution of the offload primitives) if an individual communication with * the NAS server (e.g. RPC call) does not complete within timeoutMS * milliseconds. * If timeoutMS is not specified, the nasPlugin shall select a network * timeout appropriate for the NAS device it manages. */ uint64 timeoutMS; } VixDiskLibNasPluginSessionParams; typedef uint64 VixDiskLibNasPluginSessionID; #define VIXDISKLIB_NASPLUGIN_INVALID_SESSION_ID (0LL) typedef enum { VIXDISKLIB_NASPLUGIN_PRIM_INVALID = (('N' << 24) | ('A' << 16) | ('S' << 8) | '0'), VIXDISKLIB_NASPLUGIN_PRIM_CLONEFILE, VIXDISKLIB_NASPLUGIN_PRIM_RESVSPACE, VIXDISKLIB_NASPLUGIN_PRIM_STATX, } VixDiskLibNasPluginPrimitiveID; struct VixDiskLibNasPluginProgressRecord; typedef Bool (VixDiskLibNasPluginPeriodicCallback)(struct VixDiskLibNasPluginProgressRecord *pRec); typedef struct VixDiskLibNasPluginProgressRecord { /* * Plugin must not modify disklib-private data. */ void *private; /* * The plugin should call the progress callback for every * updateBytes completed. Set by the disklib. */ uint64 updateBytes; /* * The number of bytes completed up since the last callback. * Set by the plugin whenever calling the callback. */ uint64 progressBytes; /* * This progress/abort callback that should be called by the plugin * periodically. */ VixDiskLibNasPluginPeriodicCallback *callback; } VixDiskLibNasPluginProgressRecord; typedef struct { VixError status; } VixDiskLibNasPluginResultCommon; /* * Keeping same structure as 'DiskLibFileAllocationType': * * Copied from file: ./bora/lib/public/diskLibTypes.h * * typedef enum DiskLibFileAllocationType { * DISKLIB_FILE_ALLOCATION_THICK, * DISKLIB_FILE_ALLOCATION_ZEROEDTHICK, * DISKLIB_FILE_ALLOCATION_THIN, * DISKLIB_FILE_ALLOCATION_NFS_THIN, * DISKLIB_FILE_ALLOCATION_UNKNOWN = -1, * } DiskLibFileAllocationType; */ typedef enum VixDiskLibNasPluginAllocType { VIXDISKLIB_NASPLUGIN_FILE_ALLOC_EZT, VIXDISKLIB_NASPLUGIN_FILE_ALLOC_LZT, VIXDISKLIB_NASPLUGIN_FILE_ALLOC_THIN, VIXDISKLIB_NASPLUGIN_FILE_ALLOC_UNKNOWN = -1, } VixDiskLibNasPluginAllocType; typedef struct { VixDiskLibNasPluginResultCommon common; /* * Logical size of the file. */ uint64 totalBytes; /* * Number of bytes actually allocated for a file; may be less than * totalBytes. */ uint64 allocedBytes; /* * Number of bytes that are allocated and are not shared with * any other files or snapshots. Always less or equal to allocedBytes. */ uint64 uniqueBytes; VixDiskLibNasPluginAllocType allocType; } VixDiskLibNasPluginStatXResult; typedef struct { VixDiskLibNasPluginPrimitiveID primitiveID; VixDiskLibNasPluginProgressRecord *progressRecord; VixDiskLibNasPluginResultCommon *result; } VixDiskLibNasPluginCommonParams; typedef enum { /* If this flag is set, the clone operation should fail if the destination * file already exists. * If this flag is not set, the clone operation should silently overwrite * the destination file if it already exists. */ VIXDISKLIB_NASPLUGIN_CLONEFILE_FLAG_GUARDED = (1 << 0), /* * If this flag is set, the NAS device is requested to complete the * clone operation as fast as possible, and postpone the actual work * of moving the data to the future using technology such as COW. * * If this flag is not set, the NAS device is requested to complete the * actual data movement before the clone operation is completed. * This is used to maximize performance of subsequent IO to the * destination file. */ VIXDISKLIB_NASPLUGIN_CLONEFILE_FLAG_LAZY = (1 << 1), /* * If this flag is set, the source and destinaion files are on * different datastores. The srcDataStoreInfo field in the * VixDiskLibNasPluginCloneFileParams is valid, and points to the * datastore parameters of the source file. */ VIXDISKLIB_NASPLUGIN_CLONEFILE_FLAG_SRCDATASTORE_VALID = (1 << 2), /* * If this flag is set, the NAS plugin is requested to * check whether the clone for the given source, destination, * and flags is supported. * If the native clone is supported, success should be returned * without actually doing the clone operation. * If the native clone is not supported, an error should be returned. */ VIXDISKLIB_NASPLUGIN_CLONEFILE_FLAG_DRYRUN = (1 << 3), /* * If this flag is set, the NAS device is requested to optimize the clone * by skipping un-allocated or zeroed source file blocks. * E.g. if the source file is thin, the destination file should also be thin. * If the flag is not set, the NAS device is requested to * write zeroes to the destination file for the source file * blocks which are un-allocated or zero. * E.g. the destination file is always thick. */ VIXDISKLIB_NASPLUGIN_CLONEFILE_FLAG_SKIPZEROES = (1 << 4), } VixDiskLibNasPluginCloneFileFlags; typedef struct { VixDiskLibNasPluginCommonParams common; /* * Absolute source and destination file-paths on ESX with all links resolved. */ char *srcFileName; char *dstFileName; /* * Flags for the cloning operation */ VixDiskLibNasPluginCloneFileFlags cloneFlags; /* * Parameters describing the datastore of the source file. * Only valid if VIXDISKLIB_NASPLUGIN_CLONEFILE_FLAG_SRCDATASTORE_VALID * flag is set. */ VixDiskLibNasPluginDataStoreParams *srcDataStoreInfo; } VixDiskLibNasPluginCloneFileParams; typedef struct { VixDiskLibNasPluginCommonParams common; /* * Absolute file-path on ESX with all links resolved. */ char *fileName; } VixDiskLibNasPluginResvSpaceParams; typedef struct { VixDiskLibNasPluginCommonParams common; /* * Absolute file-path on ESX with all links resolved. * The file has to exist and have a non-zero logical length prior to the * execution of the VIXDISKLIB_NASPLUGIN_PRIM_RESVSPACE primitive. * The NAS device is requested to reserve space for the logical length of * the file. * The file may be empty (new file creation) or partially filled with * data (file growth). The VIXDISKLIB_NASPLUGIN_PRIM_RESVSPACE primitive * has to preserve any existing file data. */ char *fileName; } VixDiskLibNasPluginStatXParams; /** * Prototype for VixDiskLibNasPlugin session initialization. * * The NAS plugin needs configuration information to establish connectivity to * the NAS device. VI already stores this information as part of NFS datastore * configuration for VMFS. The NAS plugin is provided NAS configuration * information as part of an init session request. The configuration data * contains the NAS device IP address, NAS device mount point, corresponding * datastore name on the ESX host, and the ESX filesystem type * and version. This should enable a NAS plugin writer to * connect to, say, a RPC program running on the NAS device and * exchange other vendor-specific setup information and * configuration data. The plugin should return a session * identifier for the virtual disk library to use as a context * for a single or a set of VM operations. The client can also * negotiate session properties like timeouts, priority etc. * during session initiation. The session initialization may * fail if the plugin does not support the given NAS volume. * * Note that this entry point may be called for a datastore * which the plugin does not support. For example, it may be a * called for a datastore on a NAS server from a different * vendor, or datastore on a NAS server whose firmware does not * support NAS offloads. It is the plugin's responsibility to * verify it can communicate with the NAS server and that the * NAS server supports the offload primitives and that the remote * mount point exists on the NAS server. * * * @param nasConfigData IN The configuration data contains the NAS device IP * address, NAS device mount point, corresponding datastore name * on the ESX host, and the ESX filesystem type and version. * @param flags IN sessionParams Session properties like timeouts, priority * @param sessionID OUT Structure returned in the case of a successful * session; it is an identifier for the virtual disk library to use as a context * for a single or a set of VM operations. * @return VIX_OK if the session was successfully established, a VIX_* error * otherwise. * */ typedef VixError (VixDiskLibNasPluginStartSession)(const VixDiskLibNasPluginDataStoreParams *nasConfigData, const VixDiskLibNasPluginSessionParams *sessionParams, VixDiskLibNasPluginSessionID *sessionID); /** * Prototype for VixDiskLibNasPlugin session teardown. * * The caller may issue multiple sets of VixDiskLibNasPluginExecutePrimitive * calls in a given session. A session may end at the request of the caller * or after the plugin hits a timeout. * * @param VixDiskLibNasPluginSessionID sessionID IN Structure that was returned * by the corresponding VixDiskLibNasPluginStartSession call. * @return VIX_OK if the session was successfully terminated, a VIX_* error * otherwise. */ typedef VixError (VixDiskLibNasPluginEndSession)(VixDiskLibNasPluginSessionID sessionID); /** * Prototype for VixDiskLibNasPlugin entrypoint to check if a primitive is * supported. * * Once a session is established, the caller can ask for the support status of * a vStorage primitive in the context of an established session ID. For * example, the caller may ask for support status of the * VIXDISKLIB_NASPLUGIN_PRIM_STATX primitive. The plugin shall determine if * the offload primitive is supported on the datastore. This may require * communication with the NAS device, and the method is vendor specific. * * @param sessionID IN Handle identifying a live session * @param primitiveID IN Primitive ID to get the support status for. * * @return VIX_OK if the session support was successfully determined, a VIX_* * error otherwise. */ typedef VixError (VixDiskLibNasPluginSupportStatus)(VixDiskLibNasPluginSessionID sessionID, const VixDiskLibNasPluginPrimitiveID primitiveID); /** * Prototype for VixDiskLibNasPlugin primitive execution. * * Once a session is established, the caller can ask for a vStorage primitive to * be done on a set of files in the context of an established session ID. For * example, the caller may ask for a file to be quick-cloned (snapshotted) to * another file on the same datastore. The plugin shall issue the request to the * NAS device in a vendor specific format. * * One example of a primitive that would be very useful on NFS is the ability to * reserve physical space to back the logical size of a file. * The preferred disk format to run enterprise workloads in ESX virtual machines * is zeroedthick; VMFS-3 reserves space for zeroedthick virtual disk files at * file creation time, thus removing the possibility of the virtual machine * crashing because of lack of physical space at the time the application writes * to the virtual disk. A newly created virtual disk file on a NFS server could * be set to an arbitrary length (many tens or hundreds of GB in this case) using * POSIX lseek and write, but the NFS server will not allocate backing storage to * the file. This violates the space guarantee requirement of zeroedthick disk * format. On NAS devices that understand the vStorage API for file devices, one * can issue an VixDiskLibNasPluginExecutePrimitive with primitiveID set to * VIXDISKLIB_NASPLUGIN_PRIM_RESVSPACE to instruct the NAS device to use * vendor-specific mechanisms to reserve space for a newly * created or existing virtual disk of non-zero logical size. * * This entrypoint can block until the client request is * successfully completed on the NAS device. However, the plugin * must periodically invoke the provided update callback. * Specifically, the plugin must invoke * execParams->progressRecord->callback for every * execParams->progressRecord->updateBytes bytes that it * transfers, each time setting the * execParams->progressRecord->progressBytes appropriately. If * the callback returns FALSE, it is an indication that the user * has requested to abort the operation; as such, the plugin * must abort the operation (including the cleanup of any * internal state), set the execParams->result data * appropriately, and return. If communication with the NAS * device is broken or timed out or no progress is reported by * the NAS device within the session timeout period, the NAS * plugin must abort the operation and return. * * @param sessionID IN Handle identifying a live session * @param execParams IN Parameters to the operation. * */ typedef void (VixDiskLibNasPluginExecutePrimitive)(VixDiskLibNasPluginSessionID sessionID, const VixDiskLibNasPluginCommonParams *execParams); /** * Plugin function table to be exported by a NAS plugin. * See the description of the various data types for explanation. * */ typedef struct { VixDiskLibPlugin diskLibPlugin; /* Must be first field */ VixDiskLibNasPluginStartSession *StartSession; VixDiskLibNasPluginEndSession *EndSession; VixDiskLibNasPluginExecutePrimitive *ExecPrimitive; VixDiskLibNasPluginSupportStatus *SupportStatus; } VixDiskLibNasPlugin; #if defined(__cplusplus) } #endif #endif