|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v4 7/7] plat/xen: Add driver state functions to client API
Extend the client API with functions for dealing with Xenbus driver
states.
Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
plat/xen/include/xenbus/client.h | 24 ++++++++++
plat/xen/xenbus/client.c | 95 ++++++++++++++++++++++++++++++++++++++++
plat/xen/xenbus/exportsyms.uk | 2 +
3 files changed, 121 insertions(+)
diff --git a/plat/xen/include/xenbus/client.h b/plat/xen/include/xenbus/client.h
index 8b7e8c1..a9417a9 100644
--- a/plat/xen/include/xenbus/client.h
+++ b/plat/xen/include/xenbus/client.h
@@ -98,4 +98,28 @@ int xenbus_watch_notify_event(struct xenbus_watch *watch);
*/
XenbusState xenbus_read_driver_state(const char *path);
+/*
+ * Changes the state of a Xen PV driver
+ *
+ * @param xbt Xenbus transaction id
+ * @param xendev Xenbus device
+ * @param state The new Xenbus state
+ * @return 0 on success, a negative errno value on error.
+ */
+int xenbus_switch_state(xenbus_transaction_t xbt,
+ struct xenbus_device *xendev, XenbusState state);
+
+/*
+ * Waits for the driver state found at the given Xenstore path to change by
+ * using watches.
+ *
+ * @param path Xenstore path
+ * @param state The returned Xenbus state
+ * @param watch Xenbus watch. It may be NULL, in which case a local watch
+ * will be created.
+ * @return 0 on success, a negative errno value on error.
+ */
+int xenbus_wait_for_state_change(const char *path, XenbusState *state,
+ struct xenbus_watch *watch);
+
#endif /* __XENBUS_CLIENT_H__ */
diff --git a/plat/xen/xenbus/client.c b/plat/xen/xenbus/client.c
index 274e6e7..86725e3 100644
--- a/plat/xen/xenbus/client.c
+++ b/plat/xen/xenbus/client.c
@@ -142,3 +142,98 @@ XenbusState xenbus_read_driver_state(const char *path)
return state;
}
+
+int xenbus_switch_state(xenbus_transaction_t xbt,
+ struct xenbus_device *xendev, XenbusState state)
+{
+ char state_path[strlen(xendev->nodename) + sizeof("/state")];
+ char new_state_str[2];
+ XenbusState crnt_state;
+ int need_transaction_end = 0; /* non-zero if local transaction */
+ int abort;
+ int err;
+
+ if (xendev == NULL)
+ return -EINVAL;
+
+ sprintf(state_path, "%s/state", xendev->nodename);
+
+ do {
+ abort = 1;
+
+ if (xbt == XBT_NIL) {
+ err = xs_transaction_start(&xbt);
+ if (err)
+ goto exit;
+ need_transaction_end = 1;
+ }
+
+ /* check if state is already set */
+ err = xs_read_integer(xbt, xendev->nodename,
+ (int *) &crnt_state);
+ if (err || crnt_state == state)
+ goto exit;
+
+ /* set new state */
+ snprintf(new_state_str, sizeof(new_state_str), "%d", state);
+ err = xs_write(xbt, state_path, NULL, new_state_str);
+
+ abort = 0;
+exit:
+ if (need_transaction_end) {
+ int _err;
+
+ _err = xs_transaction_end(xbt, abort);
+ if (!err)
+ err = _err;
+ xbt = XBT_NIL;
+ }
+ } while (err == -EAGAIN);
+
+ if (err)
+ uk_printd(DLVL_ERR, "Error switching state to %s: %d\n",
+ xenbus_state_to_str(state), err);
+
+ return err;
+}
+
+int xenbus_wait_for_state_change(const char *path, XenbusState *state,
+ struct xenbus_watch *watch)
+{
+ XenbusState crnt_state;
+ int err = 0, watch_is_local = 0;
+
+ if (path == NULL || state == NULL) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (watch == NULL) {
+ /* create a local watch */
+ watch = xs_watch_path(XBT_NIL, path);
+ if (PTRISERR(watch)) {
+ err = PTR2ERR(watch);
+ goto out;
+ }
+ watch_is_local = 1;
+ }
+
+ for (;;) {
+ err = xs_read_integer(XBT_NIL, path, (int *) &crnt_state);
+ if (err)
+ break;
+
+ if (crnt_state != *state) {
+ *state = crnt_state;
+ break;
+ }
+
+ xenbus_watch_wait_event(watch);
+ }
+
+out:
+ if (watch_is_local)
+ xs_unwatch(XBT_NIL, watch);
+
+ return err;
+}
diff --git a/plat/xen/xenbus/exportsyms.uk b/plat/xen/xenbus/exportsyms.uk
index d57a2a5..a750ff2 100644
--- a/plat/xen/xenbus/exportsyms.uk
+++ b/plat/xen/xenbus/exportsyms.uk
@@ -28,3 +28,5 @@ xenbus_devtype_to_str
xenbus_str_to_devtype
xenbus_watch_wait_event
xenbus_read_driver_state
+xenbus_switch_state
+xenbus_wait_for_state_change
--
2.11.0
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |