/* ********************************************************** * Copyright 2012 - 2013 VMware, Inc. All rights reserved. * **********************************************************/ /* * @VMKAPIMOD_LICENSE@ */ /* *********************************************************************** * Management Interfaces */ /** * \defgroup Mgmt Management * * Interfaces that allow management of vmkapi modules (runtime * parameterization, notifications to modules from user space and * to user space from modules). * * @{ *********************************************************************** */ /* * vmkapi_mgmt.h -- * * vmkernel declarations for datatypes & functions used for * enabling per-module management APIs between user-space and * vmkernel modules. */ #ifndef _VMKAPI_MGMT_H_ #define _VMKAPI_MGMT_H_ /** \cond never */ #ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H #error This vmkapi file should never be included directly but only via vmkapi.h #endif /** \endcond never */ #include "base/vmkapi_mgmt_types.h" /** \brief Opaque generic handle allocated by the API */ typedef struct vmkMgmtHandleInt * vmk_MgmtHandle; /** \brief Opaque session ID assigned during session announcement */ typedef vmk_uint64 vmk_MgmtSessionID; /** * \brief The session ID to send a callback to all current sessions. * \note Using this session ID in the envelope's sessionId member * will send a callback request, via vmk_MgmtCallbackInvoke, * to all current sessions. */ #define VMK_MGMT_SESSION_ID_ALL ((vmk_uint64) 0) /** * \brief Addressing information describing a callback invocation. * \note An envelope structure is used both when receiving a callback * (as the second parameter to the kernel callback) and * when sending a callback to user-space from via * vmk_MgmtCallbackInvoke. When receiving a callback in * the kernel, the envelope describes the session from * which the callback originates and the instance to * which the callback is addressed (if any). When sending * a callback to user-space, the envelope describes the * session to which the callback should be sent and the * instance from which the callback originates (if any). */ typedef struct vmk_MgmtEnvelope { /** * \brief Instance ID this callback is being sent to or coming from. * \note VMK_MGMT_NO_INSTANCE_ID can be provided if the callback is * not originating from any specific instance or is not * addressed to a specific instance. */ vmk_MgmtInstanceID instanceId; /** * \brief Session ID this callback is being sent to or coming from. * \note VMK_MGMT_SESSION_ID_ALL can be used to address all * sessions simultaneously from the kernel, but * VMK_MGMT_SESSION_ID_ALL will never be provided as * the session from which a callback originated. */ vmk_MgmtSessionID sessionId; } vmk_MgmtEnvelope; /** * \brief Cookie information provided to a single callback invocation. */ typedef struct vmk_MgmtCookies { /** * \brief Handle cookie that was provided to vmk_MgmtInit */ vmk_uint64 handleCookie; /** * \brief Session cookie assigned by session announcement function. */ vmk_uint64 sessionCookie; } vmk_MgmtCookies; /** *********************************************************************** * vmk_MgmtSessionAnnounceFn -- */ /** * * \brief Session-announce function prototype * * This function runs when a new managing session (usually a user-space * program such as a CIM provider) connects to a management handle. * You can use this function to initialize per-session state. To * refer to that session state later, assign the state metadata (such * as a pointer) to the sessionCookie output parameter. The * sessionCookie will be provided to subsequent callbacks originating * from this particular session and to the session cleanup function * when the session ends. * * \param[in] handle The handle associated with the session * being created. * \param[in] handleCookie The cookie that was provided to * vmk_MgmtInit. * \param[in] sessionId A unique identifier for the new session. * \param[out] sessionCookie Optional developer-provided cookie that * will be provided on subsequent * callback invocations and to the * session cleanup function. * * \retval VMK_OK The session could be established. * *********************************************************************** */ typedef VMK_ReturnStatus (*vmk_MgmtSessionAnnounceFn)(vmk_MgmtHandle handle, vmk_uint64 handleCookie, vmk_MgmtSessionID sessionId, vmk_uint64 *sessionCookie); /** *********************************************************************** * vmk_MgmtSessionCleanupFn -- */ /** * * \brief Session-cleanup function prototype. * * This function runs when a managing session (usually a user-space * program such as a CIM provider) disconnects from the management * handle. Note that if your cleanup function encounters an * internal error that prevents it from successfully completing, * the management session will still be removed and will not be * used again. * * \note You must not use vmk_MgmtCallbackInvoke() from within * your session-cleanup function to the session that * is being cleaned up. * * \param[in] handle The handle associated with the session * being cleaned up. * \param[in] handleCookie The cookie that was provided to * vmk_MgmtInit. * \param[in] sessionId A unique identifier for session. * \param[in] sessionCookie The cookie that was established by the * announce function when the session * started. * * \retval None. * *********************************************************************** */ typedef void (*vmk_MgmtSessionCleanupFn)(vmk_MgmtHandle handle, vmk_uint64 handleCookie, vmk_MgmtSessionID sessionId, vmk_AddrCookie sessionCookie); /** *********************************************************************** * vmk_MgmtCleanupFn -- */ /** * * \brief Prototype for a management interface's cleanup callback. * * \param[in] private Optional cookie data to be used by the callback, * as was originally provided to vmk_MgmtInit(). * *********************************************************************** */ typedef void (*vmk_MgmtCleanupFn)(vmk_uint64 handleCookie); /** *********************************************************************** * vmk_MgmtKeyGetFn -- */ /** * * \brief Prototype for get-key function. * * \note This prototype is for a module-supplied "get" function * for fetching a key's value, for a key that was registered * using vmk_MgmtAddKey. * * \param[in] cookie Cookie supplied with vmk_MgmtInit. * \param[out] keyVal Value of the key that was read. The type of * pointer this represents depends on the type * of key that was added using this function. * * \retval VMK_OK The 'get' function executed correctly. * This is not an indicator of the success or failure of * the operations in the function, but merely that they * ran. * *********************************************************************** */ typedef VMK_ReturnStatus (*vmk_MgmtKeyGetFn)(vmk_uint64 cookie, void *keyVal); /** *********************************************************************** * vmk_MgmtKeySetFn -- */ /** * * \brief Prototype for set-key function. * * \note This prototype is for a module-supplied "set" function * for storing a key's value, for a key that was registered * using vmk_MgmtAddKey. * * \param[in] cookie Cookie supplied with vmk_MgmtKeyValueInit. * \param[in] keyVal Value of the key to set. The type of * pointer this represents depends on the type * of key that was added using this function. * * \retval VMK_OK The 'set' function executed correctly. * This is not an indicator of the success or failure of * the operations in the function, but merely that they * ran. * *********************************************************************** */ typedef VMK_ReturnStatus (*vmk_MgmtKeySetFn)(vmk_uint64 cookie, void *keyVal); /** * \brief Properties of a kernel management handle being initialized. */ typedef struct vmk_MgmtProps { /** * \brief Module ID registering this handle. */ vmk_ModuleID modId; /** * \brief Heap ID used for allocating metadata and parameter data. * \note The heap must have sufficient capacity to handle static * allocations associated with metadata overhead and to handle * dynamic allocations associated with backing parameter * data during callback invocations and key-value operations. * The static overhead is approximately 16KB per management * handle plus approximately 2KB per simultaneous * application session (e.g., CIM provider or other * caller of vmk_MgmtUserInit). The dynamic overhead per * callback invocation is a maximum of 9KB plus the total of * all parameter sizes for that specific callback. If multiple * concurrent callbacks (or concurrent callbacks of * different type with different parameter sizes) should * be supported, then the heap should be large enough to * handle the simultaneous allocation of those dynamic * allocations while those callbacks are being processed. * Similarly, dynamic overhead for a key-value operation is * approximately 9KB per operation while that operation is * ongoing. Typically key-value operations are processed * serially from user-space, and only one operation is * ongoing at any given. */ vmk_HeapID heapId; /** * \brief Signature describing the API being initialized. * \note To be useable, API passed must have an equivalent * signature that is passed to the library interface * in user-space. */ vmk_MgmtApiSignature *sig; /** * \brief Cleanup function run during management handle teardown. * \note This is optional and may be NULL. */ vmk_MgmtCleanupFn cleanupFn; /** * \brief Function that runs when a management session starts. * \note This is optional and may be NULL. */ vmk_MgmtSessionAnnounceFn sessionAnnounceFn; /** * \brief Function that runs when a management session ends. * \note This is optional and may be NULL. */ vmk_MgmtSessionCleanupFn sessionCleanupFn; /** * \brief Handle-wide cookie that used by subsequent callbacks. * \note This is optional and may be 0. */ vmk_uint64 handleCookie; } vmk_MgmtProps; /** *********************************************************************** * vmk_MgmtInit */ /** * * \brief Initialize the kernel side of a user/kernel management API * * \param[in] props The properties describing the API being * initialized. * \param[out] handle The handle that will be allocated for * accessing this API. * * \retval VMK_OK Initialization succeeded. * \retval VMK_BAD_PARAM Either the modId or signature were invalid. * \retval VMK_NO_MEMORY Internal metadata for operation could not be * allocated. * *********************************************************************** */ VMK_ReturnStatus vmk_MgmtInit(vmk_MgmtProps *props, vmk_MgmtHandle *handle); /** *********************************************************************** * vmk_MgmtRegisterInstanceCallbacks */ /** * * \brief Register instance-specific management callbacks. * * \note This API registers an instance and instance-specific callbacks * that will be associated with a given management handle. If * you provide instance-specific callbacks, those callbacks will * be invoked instead of the default corresponding callbacks that * were originally registered with the handle. Note that it is * valid to supply a subset of instance-specific callbacks * (or even none). * * \param[in] handle The management handle that was initialized. * \param[in] instanceId The unique instance that will have its * callbacks registered. Must be unique for * the current handle, and must not be 0. * \param[in] modId The modId of the module where the * callbacks reside. * \param[in] heapId The heapId from the module where the * callbacks reside. * \param[in] displayName The name that will be displayed for * this instance when it's listed. * \param[in] numCallbacks The number of instance-specific * callbacks that are being registered. 0 * is valid, if the instance does not * supply instance-specific callbacks. * \param[in] callbacks The callback information for each * instance-specific callback, corresponding * to callbacks that override those * registered in the API signature * for this handle. * * \retval VMK_OK Initialization succeeded. * \retval VMK_BAD_PARAM Parameters couldn't be validated. * \retval VMK_NO_MEMORY Internal metadata for operation could not be * allocated. * *********************************************************************** */ VMK_ReturnStatus vmk_MgmtRegisterInstanceCallbacks(vmk_MgmtHandle handle, vmk_uint64 instanceId, vmk_ModuleID modId, vmk_HeapID heapId, vmk_Name *displayName, vmk_uint32 numCallbacks, vmk_MgmtCallbackInfo *callbacks); /** *********************************************************************** * vmk_MgmtUnregisterInstanceCallbacks */ /** * * \brief Unregister an instance from being management handle. * * \param[in] handle The management handle that was initialized * and to which this instance is associated. * \param[in] instanceId The unique instance that was already * registered for management. * * \retval VMK_OK Unregistration succeeded. * \retval VMK_BAD_PARAM The instance was not already registered. * *********************************************************************** */ VMK_ReturnStatus vmk_MgmtUnregisterInstanceCallbacks(vmk_MgmtHandle handle, vmk_uint64 instanceId); /** *********************************************************************** * vmk_MgmtDestroy */ /** * * \brief Destroy the kernel side of a user/kernel management API * * \param[in] handle The handle that was passed and initialized with * vmk_MgmtInit * * \note The heap that was passed to vmk_MgmtInit should not be * destroyed until all access to the management channel has * stopped, and thus the cleanup function has run. If you call * vmk_MgmtDestroy during module-unload, you are assured that the * management channel is not in use & thus you can safely destroy * the heap immediately. * * \retval VMK_BAD_PARAM The API has already been destroyed or has * already been requested to be destroyed. * \retval VMK_OK The API will be destroyed once all in-flight * operations conclude (may be immediate, if * none are currently in-flight). * *********************************************************************** */ VMK_ReturnStatus vmk_MgmtDestroy(vmk_MgmtHandle handle); /* *********************************************************************** * vmk_MgmtCallbackInvokeInt -- * * This is used by vmk_MgmtCallbackInvoke(). VMKAPI clients should * never call this function directly. * *********************************************************************** */ /** \cond nodoc */ VMK_ReturnStatus vmk_MgmtCallbackInvokeInt(vmk_MgmtHandle handle, vmk_MgmtEnvelope *envelope, vmk_uint64 callbackId, vmk_uint32 argCount, ...); /** \endcond */ /** *********************************************************************** * vmk_MgmtCallbackInvoke */ /** * * \brief Invoke a user-space callback that has zero or more parameters. * \note The callback will be asynchronously delivered to user-space, * but only if there currently is a user-space process associated * with this management handle that is listening for callback * requests. This call does not block. * \note Parameters are immediately copied for delivery. Sizes are * determined by the API signature that was registered with * vmk_MgmtInit. Additionally, the data cookie that was * registered with the receiver (in user space) will be provided * as the first argument to the callback that is delivered in * user space. * * \param[in] handle The handle that was passed and initialized with * vmk_MgmtInit * \param[in] envelope The envelope describing the instanceId from * which this callback originates and the * session ID to which this callback should be * sent. If this callback should be sent to * all current sessions, use VMK_MGMT_SESSION_ID_ALL * as the session ID. If this callback is not * instance-specific, use VMK_MGMT_NO_INSTANCE_ID * as the instance ID. * specific invocation, use VMK_MGMT_NO_INSTANCE_ID. * \param[in] callbackId The unique ID corresponding to the callback to * invoke, as registered with the API signature. * \param[in] ... Pointers to the parameters to copy and pass. * The number of parameters passed here must match * the number used by the callback indicated by * callbackId. Any parameter that is declared * as a vector type must be encapsulated in a * vmk_MgmtVectorParm structure. * * \retval VMK_OK The callback was prepared for delivery. This does not indicate that it has run, however. * \retval VMK_BAD_PARAM The callback or number of parameters supplied * was invalid. * \retval VMK_NO_MEMORY Temporary storage required to deliver the event * was unavailable. * \retval VMK_NOT_FOUND There is no listening user-space process * running that can receive this callback request. * *********************************************************************** */ #define vmk_MgmtCallbackInvoke( \ /* (vmk_MgmtHandle) */ handle, \ /* (vmk_MgmtEnvelope *) */ envelope, \ /* (vmk_uint64) */ callbackId, \ ...) \ vmk_MgmtCallbackInvokeInt(handle, envelope, callbackId, VMK_UTIL_NUM_ARGS(__VA_ARGS__), ##__VA_ARGS__) /** *********************************************************************** * vmk_MgmtAddKey */ /** * * \brief Add a key to be managed as a key-value pair. * * \note This creates a key-value pair that can be managed using * the vmkmgmt_keyval utility. The name of the management * handle that was initialized is the name of the key-value * instance that would be the "instance" argument to * vmkmgmt_keyval. For the get and set functions registered * here, the cookie that is given back is the cookie that * was initialized with vmk_MgmtInit. * * \param[in] handle The handle that was initialized by * vmk_MgmtInit. * \param[in] keyType The type of the key being added. * \param[in] keyName The name of the key being added. Must be * unique compared to other registered * keys for this management handle. * \param[in] getFn The function that will be used to get the key * value at runtime. * \param[in] setFn The function that will be used to set the key * value at runtime. * * \note Both the getFn and setFn must be provided. * * \retval VMK_OK The key was added. * \retval VMK_BAD_PARAM A bad parameter was given. * \retval VMK_NO_MEMORY Memory was not available to allocate the required * metadata structures. * *********************************************************************** */ VMK_ReturnStatus vmk_MgmtAddKey(vmk_MgmtHandle handle, vmk_MgmtKeyType keyType, vmk_Name *keyName, vmk_MgmtKeyGetFn getFn, vmk_MgmtKeySetFn setFn); #endif /* _VMKAPI_MGMT_H_ */ /** @} */