OvmfPkg/XenBusDxe: Add XenStore function into the XenBus protocol

Change in V3:
- Have XenStoreWaitWatch/XenBusWaitForWatch return a XENSTORE_STATUS
  instead of VOID.
- Add description of the introducted member of the protocol.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16269 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Anthony PERARD 2014-10-29 06:51:04 +00:00 committed by jljusten
parent 02a6bcff71
commit c23c037fb3
3 changed files with 474 additions and 0 deletions

View File

@ -68,6 +68,136 @@ typedef enum {
/// Function prototypes
///
/**
Get the contents of the node Node of the PV device. Returns the contents in
*Result which should be freed after use.
@param This A pointer to XENBUS_PROTOCOL instance.
@param Transaction The XenStore transaction covering this request.
@param Node The basename of the file to read.
@param Result The returned contents from this file.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of failure.
@note The results buffer is malloced and should be free'd by the
caller.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_XS_READ)(
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node,
OUT VOID **Result
);
/**
Get the contents of the node Node of the PV device's backend. Returns the
contents in *Result which should be freed after use.
@param This A pointer to XENBUS_PROTOCOL instance.
@param Transaction The XenStore transaction covering this request.
@param Node The basename of the file to read.
@param Result The returned contents from this file.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of failure.
@note The results buffer is malloced and should be free'd by the
caller.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_XS_BACKEND_READ)(
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node,
OUT VOID **Result
);
/**
Print formatted write to a XenStore node.
@param This A pointer to XENBUS_PROTOCOL instance.
@param Transaction The XenStore transaction covering this request.
@param Directory The dirname of the path to read.
@param Node The basename of the path to read.
@param Format AsciiSPrint format string followed by a variable number
of arguments.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of write failure.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_XS_PRINTF) (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Directory,
IN CONST CHAR8 *Node,
IN CONST CHAR8 *Format,
...
);
/**
Remove a node or directory (directories must be empty) of the PV driver's
subdirectory.
@param This A pointer to XENBUS_PROTOCOL instance.
@param Transaction The XenStore transaction covering this request.
@param Node The basename of the node to remove.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of failure.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_XS_REMOVE) (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node
);
/**
Start a transaction.
Changes by others will not be seen during the lifetime of this
transaction, and changes will not be visible to others until it
is committed (XsTransactionEnd).
@param This A pointer to XENBUS_PROTOCOL instance.
@param Transaction The returned transaction.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of failure.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_XS_TRANSACTION_START)(
IN XENBUS_PROTOCOL *This,
OUT XENSTORE_TRANSACTION *Transaction
);
/**
End a transaction.
@param This A pointer to XENBUS_PROTOCOL instance.
@param Transaction The transaction to end/commit.
@param Abort If TRUE, the transaction is discarded
instead of committed.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of failure.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_XS_TRANSACTION_END) (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN BOOLEAN Abort
);
/**
Grant access to the page Frame to the domain DomainId.
@ -101,6 +231,83 @@ EFI_STATUS
IN grant_ref_t Ref
);
/**
Register a XenStore watch.
XenStore watches allow a client to wait for changes to an object in the
XenStore.
@param This A pointer to the XENBUS_PROTOCOL.
@param Node The basename of the path to watch.
@param Token A token.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of write failure. EEXIST errors from the
XenStore are supressed, allowing multiple, physically different,
xenbus_watch objects, to watch the same path in the XenStore.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_REGISTER_WATCH) (
IN XENBUS_PROTOCOL *This,
IN CONST CHAR8 *Node,
OUT VOID **Token
);
/**
Register a XenStore watch on a backend's node.
XenStore watches allow a client to wait for changes to an object in the
XenStore.
@param This A pointer to the XENBUS_PROTOCOL.
@param Node The basename of the path to watch.
@param Token A token.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of write failure. EEXIST errors from the
XenStore are supressed, allowing multiple, physically different,
xenbus_watch objects, to watch the same path in the XenStore.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_REGISTER_WATCH_BACKEND) (
IN XENBUS_PROTOCOL *This,
IN CONST CHAR8 *Node,
OUT VOID **Token
);
/**
Unregister a XenStore watch.
@param This A pointer to the XENBUS_PROTOCOL.
@param Token An token previously returned by a successful
call to RegisterWatch ().
**/
typedef
VOID
(EFIAPI *XENBUS_UNREGISTER_WATCH) (
IN XENBUS_PROTOCOL *This,
IN VOID *Token
);
/**
Block until the node watch by Token change.
@param This A pointer to the XENBUS_PROTOCOL.
@param Token An token previously returned by a successful
call to RegisterWatch or RegisterWatchBackend.
@return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value
indicating the type of failure.
**/
typedef
XENSTORE_STATUS
(EFIAPI *XENBUS_WAIT_FOR_WATCH) (
IN XENBUS_PROTOCOL *This,
IN VOID *Token
);
///
/// Protocol structure
@ -109,11 +316,27 @@ EFI_STATUS
/// should not be used outside of the EDK II tree.
///
struct _XENBUS_PROTOCOL {
XENBUS_XS_READ XsRead;
XENBUS_XS_BACKEND_READ XsBackendRead;
XENBUS_XS_PRINTF XsPrintf;
XENBUS_XS_REMOVE XsRemove;
XENBUS_XS_TRANSACTION_START XsTransactionStart;
XENBUS_XS_TRANSACTION_END XsTransactionEnd;
XENBUS_GRANT_ACCESS GrantAccess;
XENBUS_GRANT_END_ACCESS GrantEndAccess;
XENBUS_REGISTER_WATCH RegisterWatch;
XENBUS_REGISTER_WATCH_BACKEND RegisterWatchBackend;
XENBUS_UNREGISTER_WATCH UnregisterWatch;
XENBUS_WAIT_FOR_WATCH WaitForWatch;
//
// Protocol data fields
//
CONST CHAR8 *Type;
UINT16 DeviceId;
CONST CHAR8 *Node;
CONST CHAR8 *Backend;
};
extern EFI_GUID gXenBusProtocolGuid;

View File

@ -941,6 +941,46 @@ XenStoreUnwatch (
return XenStoreTalkv (XST_NIL, XS_UNWATCH, WriteRequest, 2, NULL, NULL);
}
STATIC
XENSTORE_STATUS
XenStoreWaitWatch (
VOID *Token
)
{
XENSTORE_MESSAGE *Message;
LIST_ENTRY *Entry = NULL;
LIST_ENTRY *Last = NULL;
XENSTORE_STATUS Status;
while (TRUE) {
EfiAcquireLock (&xs.WatchEventsLock);
if (IsListEmpty (&xs.WatchEvents) ||
Last == GetFirstNode (&xs.WatchEvents)) {
EfiReleaseLock (&xs.WatchEventsLock);
Status = XenStoreProcessMessage ();
if (Status != XENSTORE_STATUS_SUCCESS && Status != XENSTORE_STATUS_EAGAIN) {
return Status;
}
continue;
}
for (Entry = GetFirstNode (&xs.WatchEvents);
Entry != Last && !IsNull (&xs.WatchEvents, Entry);
Entry = GetNextNode (&xs.WatchEvents, Entry)) {
Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
if (Message->u.Watch.Handle == Token) {
RemoveEntryList (Entry);
EfiReleaseLock (&xs.WatchEventsLock);
FreePool(Message->u.Watch.Vector);
FreePool(Message);
return XENSTORE_STATUS_SUCCESS;
}
}
Last = GetFirstNode (&xs.WatchEvents);
EfiReleaseLock (&xs.WatchEventsLock);
}
}
VOID
EFIAPI
NotifyEventChannelCheckForEvent (
@ -1384,3 +1424,127 @@ XenStoreUnregisterWatch (
FreePool (Watch->Node);
FreePool (Watch);
}
//
// XENBUS protocol
//
XENSTORE_STATUS
EFIAPI
XenBusWaitForWatch (
IN XENBUS_PROTOCOL *This,
IN VOID *Token
)
{
return XenStoreWaitWatch (Token);
}
XENSTORE_STATUS
EFIAPI
XenBusXenStoreRead (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node,
OUT VOID **Value
)
{
return XenStoreRead (Transaction, This->Node, Node, NULL, Value);
}
XENSTORE_STATUS
EFIAPI
XenBusXenStoreBackendRead (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node,
OUT VOID **Value
)
{
return XenStoreRead (Transaction, This->Backend, Node, NULL, Value);
}
XENSTORE_STATUS
EFIAPI
XenBusXenStoreRemove (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN const char *Node
)
{
return XenStoreRemove (Transaction, This->Node, Node);
}
XENSTORE_STATUS
EFIAPI
XenBusXenStoreTransactionStart (
IN XENBUS_PROTOCOL *This,
OUT XENSTORE_TRANSACTION *Transaction
)
{
return XenStoreTransactionStart (Transaction);
}
XENSTORE_STATUS
EFIAPI
XenBusXenStoreTransactionEnd (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN BOOLEAN Abort
)
{
return XenStoreTransactionEnd (Transaction, Abort);
}
XENSTORE_STATUS
EFIAPI
XenBusXenStoreSPrint (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *DirectoryPath,
IN CONST CHAR8 *Node,
IN CONST CHAR8 *FormatString,
...
)
{
VA_LIST Marker;
XENSTORE_STATUS Status;
VA_START (Marker, FormatString);
Status = XenStoreVSPrint (Transaction, DirectoryPath, Node, FormatString, Marker);
VA_END (Marker);
return Status;
}
XENSTORE_STATUS
EFIAPI
XenBusRegisterWatch (
IN XENBUS_PROTOCOL *This,
IN CONST CHAR8 *Node,
OUT VOID **Token
)
{
return XenStoreRegisterWatch (This->Node, Node, (XENSTORE_WATCH **) Token);
}
XENSTORE_STATUS
EFIAPI
XenBusRegisterWatchBackend (
IN XENBUS_PROTOCOL *This,
IN CONST CHAR8 *Node,
OUT VOID **Token
)
{
return XenStoreRegisterWatch (This->Backend, Node, (XENSTORE_WATCH **) Token);
}
VOID
EFIAPI
XenBusUnregisterWatch (
IN XENBUS_PROTOCOL *This,
IN VOID *Token
)
{
XenStoreUnregisterWatch ((XENSTORE_WATCH *) Token);
}

View File

@ -289,4 +289,91 @@ XenStoreDeinit (
IN XENBUS_DEVICE *Dev
);
//
// XENBUS protocol
//
XENSTORE_STATUS
EFIAPI
XenBusWaitForWatch (
IN XENBUS_PROTOCOL *This,
IN VOID *Token
);
XENSTORE_STATUS
EFIAPI
XenBusXenStoreRead (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node,
OUT VOID **Value
);
XENSTORE_STATUS
EFIAPI
XenBusXenStoreBackendRead (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node,
OUT VOID **Value
);
XENSTORE_STATUS
EFIAPI
XenBusXenStoreRemove (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *Node
);
XENSTORE_STATUS
EFIAPI
XenBusXenStoreTransactionStart (
IN XENBUS_PROTOCOL *This,
OUT XENSTORE_TRANSACTION *Transaction
);
XENSTORE_STATUS
EFIAPI
XenBusXenStoreTransactionEnd (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN BOOLEAN Abort
);
XENSTORE_STATUS
EFIAPI
XenBusXenStoreSPrint (
IN XENBUS_PROTOCOL *This,
IN XENSTORE_TRANSACTION Transaction,
IN CONST CHAR8 *DirectoryPath,
IN CONST CHAR8 *Node,
IN CONST CHAR8 *FormatString,
...
);
XENSTORE_STATUS
EFIAPI
XenBusRegisterWatch (
IN XENBUS_PROTOCOL *This,
IN CONST CHAR8 *Node,
OUT VOID **Token
);
XENSTORE_STATUS
EFIAPI
XenBusRegisterWatchBackend (
IN XENBUS_PROTOCOL *This,
IN CONST CHAR8 *Node,
OUT VOID **Token
);
VOID
EFIAPI
XenBusUnregisterWatch (
IN XENBUS_PROTOCOL *This,
IN VOID *Token
);
#endif /* _XEN_XENSTORE_XENSTOREVAR_H */