[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 14/19] OvmfPkg/XenBusDxe: Add XenStore function into the XenBus protocol



Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>

---
Change in V3:
- Have XenStoreWaitWatch/XenBusWaitForWatch return a XENSTORE_STATUS
  instead of VOID.
- Add description of the introducted member of the protocol.
---
 OvmfPkg/Include/Protocol/XenBus.h | 223 ++++++++++++++++++++++++++++++++++++++
 OvmfPkg/XenBusDxe/XenStore.c      | 164 ++++++++++++++++++++++++++++
 OvmfPkg/XenBusDxe/XenStore.h      |  87 +++++++++++++++
 3 files changed, 474 insertions(+)

diff --git a/OvmfPkg/Include/Protocol/XenBus.h 
b/OvmfPkg/Include/Protocol/XenBus.h
index 2c28a97..47750af 100644
--- a/OvmfPkg/Include/Protocol/XenBus.h
+++ b/OvmfPkg/Include/Protocol/XenBus.h
@@ -85,6 +85,136 @@ typedef enum {
 ///
 
 /**
+  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.
 
   @param This       A pointer to XENBUS_PROTOCOL instance.
@@ -117,6 +247,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
@@ -125,11 +332,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;
diff --git a/OvmfPkg/XenBusDxe/XenStore.c b/OvmfPkg/XenBusDxe/XenStore.c
index 8ba4328..4af4c6e 100644
--- a/OvmfPkg/XenBusDxe/XenStore.c
+++ b/OvmfPkg/XenBusDxe/XenStore.c
@@ -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);
+}
diff --git a/OvmfPkg/XenBusDxe/XenStore.h b/OvmfPkg/XenBusDxe/XenStore.h
index f0dcb64..b3c5c6e 100644
--- a/OvmfPkg/XenBusDxe/XenStore.h
+++ b/OvmfPkg/XenBusDxe/XenStore.h
@@ -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 */
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.