|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 25 of 29 RFC] libxl: add libxl_hotplug_dispatch
# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
# Date 1328179686 -3600
# Node ID 94532199f647fc03816fc5ae50ab53c8c5b80cd8
# Parent 1506b1f2ab0fe5f4cd5bcd86a566d5a7be5f838b
libxl: add libxl_hotplug_dispatch
Added a new function to libxl API to handle device hotplug. Actions to
execute upon hotplug device state changes are handled using the
libxl_device_disk_hotplug_actions and libxl_device_nic_hotplug_actions
depending on the type of device. Currently only VIF and VBD devices
are handled by the hotplug mechanism.
Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
diff -r 1506b1f2ab0f -r 94532199f647 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Thu Feb 02 11:45:03 2012 +0100
+++ b/tools/libxl/libxl.c Thu Feb 02 11:48:06 2012 +0100
@@ -982,6 +982,188 @@ out:
return rc;
}
+static int libxl__hotplug_generic_dispatcher(libxl__gc *gc, char *path,
+ uint32_t domid,
+ libxl__hotplug_status state,
+ libxl__device_generic_hotplug_actions *action,
+ void *device)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *spath = libxl__sprintf(gc, "%s/state", path);
+ int rc = 0;
+
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "processing device %s with state %d",
+ path, state);
+ switch(state) {
+ case HOTPLUG_DEVICE_INIT:
+ if (action->init) {
+ rc = action->init(ctx, domid, device);
+ if (rc < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to init"
+ " device %s", path);
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_ERROR);
+ break;
+ }
+ }
+ libxl__xs_write(gc, XBT_NULL, spath, "%d", HOTPLUG_DEVICE_CONNECT);
+ break;
+ case HOTPLUG_DEVICE_CONNECT:
+ if (action->connect) {
+ rc = action->connect(ctx, domid, device);
+ if (rc < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to connect"
+ " device %s", path);
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_ERROR);
+ break;
+ }
+ }
+ libxl__xs_write(gc, XBT_NULL, spath, "%d", HOTPLUG_DEVICE_CONNECTED);
+ break;
+ case HOTPLUG_DEVICE_CONNECTED:
+ if (action->connected) {
+ rc = action->connected(ctx, domid, device);
+ if (rc < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to execute "
+ "connected action on"
+ " device %s", path);
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_ERROR);
+ break;
+ }
+ }
+ break;
+ case HOTPLUG_DEVICE_DISCONNECT:
+ if (action->disconnect) {
+ rc = action->disconnect(ctx, domid, device);
+ if (rc < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to unplug"
+ " device %s", path);
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_ERROR);
+ break;
+ }
+ }
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_DISCONNECTED);
+ break;
+ case HOTPLUG_DEVICE_DISCONNECTED:
+ if (action->disconnected) {
+ rc = action->disconnected(ctx, domid, device);
+ if (rc < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to execute "
+ "unpluged action on"
+ " device %s", path);
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_ERROR);
+ break;
+ }
+ }
+ break;
+ case HOTPLUG_DEVICE_FORCE_DISCONNECT:
+ if (action->force_disconnect) {
+ rc = action->force_disconnect(ctx, domid, device);
+ if (rc < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to force "
+ "disconnect device "
+ "%s", path);
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_ERROR);
+ break;
+ }
+ }
+ libxl__xs_write(gc, XBT_NULL, spath, "%d",
+ HOTPLUG_DEVICE_DISCONNECTED);
+ break;
+ case HOTPLUG_DEVICE_ERROR:
+ if (action->error)
+ rc = action->error(ctx, domid, device);
+ break;
+ }
+ return rc;
+}
+
+int libxl_hotplug_dispatch(libxl_ctx *ctx,
+ libxl_device_disk_hotplug_actions *disk_handler,
+ libxl_device_nic_hotplug_actions *nic_handler)
+{
+ unsigned int n;
+ char **l1, *sstate, *entry, *spath;
+ libxl__device dev;
+ libxl_device_disk disk;
+ libxl_device_nic nic;
+ libxl__hotplug_status state;
+
+ for (;;) {
+ GC_INIT(ctx);
+ l1 = xs_read_watch(ctx->xsh, &n);
+ if (!l1) {
+ continue;
+ }
+
+ /* Only react to "state" changes */
+ entry = strrchr(l1[0], '/');
+ if (!entry || strcmp(entry, "/state"))
+ goto next;
+
+ spath = libxl__strdup(gc, l1[0]);
+ /* Fetch state info */
+ sstate = libxl__xs_read(gc, XBT_NULL, l1[0]);
+ if (!sstate) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to parse state"
+ "from %s", l1[0]);
+ goto next;
+ }
+ state = atoi(sstate);
+
+ /* remove "state" part from path */
+ *entry = '\0';
+ if (libxl__parse_hotplug_path(gc, l1[0], &dev) < 0)
+ goto next;
+
+ switch(dev.backend_kind) {
+ case LIBXL__DEVICE_KIND_VBD:
+ libxl_device_disk_init(ctx, &disk);
+ if (libxl__parse_disk_hotplug_path(gc, l1[0], &disk)) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to parse disk data"
+ "from %s", l1[0]);
+ goto next;
+ }
+ /* Choose suitable backend */
+ disk.backend = LIBXL_DISK_BACKEND_UNKNOWN;
+ if (libxl__device_disk_set_backend(gc, &disk) < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "no suitable backend for"
+ "disk %s", disk.pdev_path);
+ goto next;
+ }
+ libxl__hotplug_generic_dispatcher(gc, l1[0], dev.domid, state,
+ (libxl__device_generic_hotplug_actions *) disk_handler,
+ (void *) &disk);
+ break;
+ case LIBXL__DEVICE_KIND_VIF:
+ libxl_device_nic_init(ctx, &nic);
+ if (libxl__parse_nic_hotplug_path(gc, l1[0], &nic)) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to parse nic data"
+ "from %s", l1[0]);
+ goto next;
+ }
+ libxl__hotplug_generic_dispatcher(gc, l1[0], dev.domid, state,
+ (libxl__device_generic_hotplug_actions *) nic_handler,
+ (void *) &nic);
+ break;
+ default:
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "unable to handle device type %s from %s",
+ libxl__device_kind_to_string(dev.backend_kind), l1[0]);
+ break;
+ }
+next:
+ free(l1);
+ GC_FREE;
+ }
+}
+
/******************************************************************************/
int libxl_device_disk_init(libxl_ctx *ctx, libxl_device_disk *disk)
diff -r 1506b1f2ab0f -r 94532199f647 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h Thu Feb 02 11:45:03 2012 +0100
+++ b/tools/libxl/libxl.h Thu Feb 02 11:48:06 2012 +0100
@@ -464,6 +464,12 @@ libxl_vminfo * libxl_list_vm(libxl_ctx *
* Set the necessary watches to start monitoring /hotplug/ entries for
* the caller domain.
*
+ * libxl_hotplug_dispatch(ctx, disk_handler, nic_handler):
+ *
+ * React to /hotplug/<domid> changes and execute the necessary handlers
+ * based on the passed disk_handler and nic_handler structs that contain
+ * the pointers to the functions to be executed.
+ *
*/
/* Disks */
@@ -532,7 +538,37 @@ int libxl_device_pci_destroy(libxl_ctx *
libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int
*num);
/* Hotplug */
+typedef int libxl_device_disk_hotplug_handler(libxl_ctx *ctx,
+ uint32_t domid,
+ libxl_device_disk *disk);
+typedef int libxl_device_nic_hotplug_handler(libxl_ctx *ctx,
+ uint32_t domid,
+ libxl_device_nic *nic);
+
+typedef struct libxl_device_disk_hotplug_actions {
+ libxl_device_disk_hotplug_handler *init;
+ libxl_device_disk_hotplug_handler *connect;
+ libxl_device_disk_hotplug_handler *connected;
+ libxl_device_disk_hotplug_handler *disconnect;
+ libxl_device_disk_hotplug_handler *disconnected;
+ libxl_device_disk_hotplug_handler *force_disconnect;
+ libxl_device_disk_hotplug_handler *error;
+} libxl_device_disk_hotplug_actions;
+
+typedef struct libxl_device_nic_hotplug_actions {
+ libxl_device_nic_hotplug_handler *init;
+ libxl_device_nic_hotplug_handler *connect;
+ libxl_device_nic_hotplug_handler *connected;
+ libxl_device_nic_hotplug_handler *disconnect;
+ libxl_device_nic_hotplug_handler *disconnected;
+ libxl_device_nic_hotplug_handler *force_disconnect;
+ libxl_device_nic_hotplug_handler *error;
+} libxl_device_nic_hotplug_actions;
+
int libxl_setup_hotplug_listener(libxl_ctx *ctx);
+int libxl_hotplug_dispatch(libxl_ctx *ctx,
+ libxl_device_disk_hotplug_actions *disk_handler,
+ libxl_device_nic_hotplug_actions *nic_handler);
/*
* Parse a PCI BDF into a PCI device structure.
diff -r 1506b1f2ab0f -r 94532199f647 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Thu Feb 02 11:45:03 2012 +0100
+++ b/tools/libxl/libxl_internal.h Thu Feb 02 11:48:06 2012 +0100
@@ -384,6 +384,22 @@ typedef enum {
_hidden int libxl__device_hotplug_disconnect(libxl__gc *gc, libxl__device *dev,
libxl__hotplug_status disconnect_param);
+/* Generic handlers for hotplug devices */
+/* Hotplug */
+typedef int libxl__device_generic_hotplug_handler(libxl_ctx *ctx,
+ uint32_t domid,
+ void *device);
+
+typedef struct libxl__device_generic_hotplug_actions {
+ libxl__device_generic_hotplug_handler *init;
+ libxl__device_generic_hotplug_handler *connect;
+ libxl__device_generic_hotplug_handler *connected;
+ libxl__device_generic_hotplug_handler *disconnect;
+ libxl__device_generic_hotplug_handler *disconnected;
+ libxl__device_generic_hotplug_handler *force_disconnect;
+ libxl__device_generic_hotplug_handler *error;
+} libxl__device_generic_hotplug_actions;
+
/*
* libxl__device_hotplug - generic function to execute hotplug scripts
* gc: allocation pool
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |