|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 2/3] libxl: add support for channels
A 'channel' is a low-bandwidth private communication channel that
resembles a physical serial port.
This patch adds a list of channels to the IDL for the domain config.
Each channel has a 'kind' which describes what should happen to
the data. Currently defined kinds are:
* PTY: the I/O surfaces as a pty in the backend domain
* SOCKET: a listening Unix domain socket accepts a connection in
the backend domain and proxies
Channels are implemented using PV consoles backed by qemu (not
xenconsoled).
Channels may be listed but don't currently support hotplug/unplug.
Signed-off-by: David Scott <dave.scott@xxxxxxxxxx>
---
tools/libxl/libxl.c | 235 ++++++++++++++++++++++++++++++++--
tools/libxl/libxl.h | 17 +++
tools/libxl/libxl_create.c | 38 ++++--
tools/libxl/libxl_dm.c | 43 ++++++-
tools/libxl/libxl_internal.h | 10 +-
tools/libxl/libxl_types.idl | 37 ++++++
tools/libxl/libxl_types_internal.idl | 4 +
7 files changed, 359 insertions(+), 25 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 900b8d4..8a069cd 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -3185,11 +3185,11 @@ const char *libxl__device_nic_devname(libxl__gc *gc,
/******************************************************************************/
int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
libxl__device_console *console,
- libxl__domain_build_state *state)
+ libxl__domain_build_state *state,
+ libxl__device *device)
{
flexarray_t *front, *ro_front;
flexarray_t *back;
- libxl__device device;
int rc;
if (console->devid && state) {
@@ -3201,12 +3201,12 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t
domid,
ro_front = flexarray_make(gc, 16, 1);
back = flexarray_make(gc, 16, 1);
- device.backend_devid = console->devid;
- device.backend_domid = console->backend_domid;
- device.backend_kind = LIBXL__DEVICE_KIND_CONSOLE;
- device.devid = console->devid;
- device.domid = domid;
- device.kind = LIBXL__DEVICE_KIND_CONSOLE;
+ device->backend_devid = console->devid;
+ device->backend_domid = console->backend_domid;
+ device->backend_kind = LIBXL__DEVICE_KIND_CONSOLE;
+ device->devid = console->devid;
+ device->domid = domid;
+ device->kind = LIBXL__DEVICE_KIND_CONSOLE;
flexarray_append(back, "frontend-id");
flexarray_append(back, libxl__sprintf(gc, "%d", domid));
@@ -3219,6 +3219,19 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t
domid,
flexarray_append(back, "protocol");
flexarray_append(back, LIBXL_XENCONSOLE_PROTOCOL);
+ if (console->name) {
+ flexarray_append(ro_front, "name");
+ flexarray_append(ro_front, console->name);
+ }
+ if (console->kind) {
+ flexarray_append(back, "kind");
+ flexarray_append(back, console->kind);
+ }
+ if (console->path) {
+ flexarray_append(back, "path");
+ flexarray_append(back, console->path);
+ }
+
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(gc, "%d", console->backend_domid));
@@ -3245,8 +3258,7 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t
domid,
flexarray_append(front, "protocol");
flexarray_append(front, LIBXL_XENCONSOLE_PROTOCOL);
}
-
- libxl__device_generic_add(gc, XBT_NULL, &device,
+ libxl__device_generic_add(gc, XBT_NULL, device,
libxl__xs_kvs_of_flexarray(gc, back,
back->count),
libxl__xs_kvs_of_flexarray(gc, front,
front->count),
libxl__xs_kvs_of_flexarray(gc, ro_front,
ro_front->count));
@@ -3257,6 +3269,209 @@ out:
/******************************************************************************/
+int libxl__init_console_from_channel(libxl__gc *gc,
+ libxl__device_console *console,
+ int dev_num,
+ libxl_device_channel *channel)
+{
+ int rc;
+ libxl__device_console_init(console);
+ console->devid = dev_num;
+ console->consback = LIBXL__CONSOLE_BACKEND_IOEMU;
+ if (!channel->name){
+ LIBXL__LOG(CTX, LIBXL__LOG_ERROR,
+ "channel %d has no name", channel->devid);
+ return ERROR_INVAL;
+ }
+ console->name = libxl__strdup(NOGC, channel->name);
+
+ if (channel->backend_domname) {
+ rc = libxl_domain_qualifier_to_domid(CTX, channel->backend_domname,
+ &channel->backend_domid);
+ if (rc < 0) return rc;
+ }
+
+ console->backend_domid = channel->backend_domid;
+
+ switch (channel->kind) {
+ case LIBXL_CHANNEL_KIND_UNKNOWN:
+ LIBXL__LOG(CTX, LIBXL__LOG_ERROR,
+ "channel %d has no kind", channel->devid);
+ return ERROR_INVAL;
+ case LIBXL_CHANNEL_KIND_PTY:
+ console->kind = libxl__strdup(NOGC, "pty");
+ console->output = libxl__sprintf(NOGC, "pty");
+ break;
+ case LIBXL_CHANNEL_KIND_SOCKET:
+ console->kind = libxl__strdup(NOGC, "socket");
+ if (!channel->u.socket.path) {
+ LIBXL__LOG(CTX, LIBXL__LOG_ERROR,
+ "channel %d has no path", channel->devid);
+ return ERROR_INVAL;
+ }
+ console->path = libxl__strdup(NOGC, channel->u.socket.path);
+ console->output = libxl__sprintf(NOGC, "chardev:libxl-channel%d",
+ channel->devid);
+ break;
+ default:
+ /* We've forgotten to add the clause */
+ LOG(ERROR, "%s: unknown channel kind %d", __func__, channel->kind);
+ return ERROR_INVAL;
+ }
+
+ return 0;
+}
+
+static int libxl__device_channel_from_xs_be(libxl__gc *gc,
+ const char *be_path,
+ libxl_device_channel *channel)
+{
+ const char *tmp;
+ int rc;
+
+ libxl_device_channel_init(channel);
+
+ /* READ_BACKEND is from libxl__device_nic_from_xs_be above */
+ channel->name = READ_BACKEND(NOGC, "name");
+ tmp = READ_BACKEND(gc, "kind");
+ if (!strcmp(tmp, "pty")) {
+ channel->kind = LIBXL_CHANNEL_KIND_PTY;
+ } else if (!strcmp(tmp, "socket")) {
+ channel->kind = LIBXL_CHANNEL_KIND_SOCKET;
+ channel->u.socket.path = READ_BACKEND(NOGC, "path");
+ } else {
+ rc = ERROR_INVAL;
+ goto out;
+ }
+
+ rc = 0;
+ out:
+ return rc;
+}
+
+static int libxl__append_channel_list_of_type(libxl__gc *gc,
+ uint32_t domid,
+ const char *type,
+ libxl_device_channel **channels,
+ int *nchannels)
+{
+ char *fe_path = NULL, *be_path = NULL;
+ char **dir = NULL;
+ unsigned int n = 0, devid = 0;
+ libxl_device_channel *next = NULL;
+ int rc = 0, i;
+
+ fe_path = GCSPRINTF("%s/device/%s",
+ libxl__xs_get_dompath(gc, domid), type);
+ dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &n);
+ if (!dir || !n)
+ goto out;
+
+ for (i = 0; i < n; i++) {
+ const char *p, *name;
+ libxl_device_channel *tmp;
+ p = libxl__sprintf(gc, "%s/%s", fe_path, dir[i]);
+ name = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name", p));
+ /* 'channels' are consoles with names, so ignore all consoles
+ without names */
+ if (!name) continue;
+ be_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/backend", p));
+ tmp = realloc(*channels,
+ sizeof(libxl_device_channel) * (*nchannels + devid + 1));
+ if (!tmp) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
+ *channels = tmp;
+ next = *channels + *nchannels + devid;
+ rc = libxl__device_channel_from_xs_be(gc, be_path, next);
+ if (rc) goto out;
+ next->devid = devid;
+ devid++;
+ }
+ *nchannels += devid;
+ return 0;
+
+ out:
+ return rc;
+}
+
+libxl_device_channel *libxl_device_channel_list(libxl_ctx *ctx,
+ uint32_t domid,
+ int *num)
+{
+ GC_INIT(ctx);
+ libxl_device_channel *channels = NULL;
+ int rc;
+
+ *num = 0;
+
+ rc = libxl__append_channel_list_of_type(gc, domid, "console", &channels,
num);
+ if (rc) goto out_err;
+
+ GC_FREE;
+ return channels;
+
+out_err:
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to list channels");
+ while (*num) {
+ (*num)--;
+ libxl_device_channel_dispose(&channels[*num]);
+ }
+ free(channels);
+ return NULL;
+}
+
+int libxl_device_channel_getinfo(libxl_ctx *ctx, uint32_t domid,
+ libxl_device_channel *channel,
+ libxl_channelinfo *channelinfo)
+{
+ GC_INIT(ctx);
+ char *dompath, *fe_path;
+ char *val;
+
+ dompath = libxl__xs_get_dompath(gc, domid);
+ channelinfo->devid = channel->devid;
+
+ fe_path = libxl__sprintf(gc, "%s/device/console/%d", dompath,
+ channelinfo->devid + 1);
+ channelinfo->backend = xs_read(ctx->xsh, XBT_NULL,
+ libxl__sprintf(gc, "%s/backend",
+ fe_path), NULL);
+ if (!channelinfo->backend) {
+ GC_FREE;
+ return ERROR_FAIL;
+ }
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/backend-id", fe_path));
+ channelinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", fe_path));
+ channelinfo->state = val ? strtoul(val, NULL, 10) : -1;
+ channelinfo->frontend = xs_read(ctx->xsh, XBT_NULL,
+ GCSPRINTF("%s/frontend",
+ channelinfo->backend), NULL);
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/frontend-id",
+ channelinfo->backend));
+ channelinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/ring-ref", fe_path));
+ channelinfo->rref = val ? strtoul(val, NULL, 10) : -1;
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/port", fe_path));
+ channelinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+ channelinfo->kind = channel->kind;
+ switch (channel->kind) {
+ case LIBXL_CHANNEL_KIND_PTY:
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/tty", fe_path));
+ channelinfo->u.pty.path = strdup(val);
+ break;
+ default:
+ break;
+ }
+ GC_FREE;
+ return 0;
+}
+
+/******************************************************************************/
+
int libxl__device_vkb_setdefault(libxl__gc *gc, libxl_device_vkb *vkb)
{
int rc;
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 80947c3..8d54456 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -482,6 +482,15 @@
*/
#define LIBXL_HAVE_DEVICE_PCI_SEIZE 1
+/*
+ * LIBXL_HAVE_DEVICE_CHANNEL
+ *
+ * If this is defined, then the libxl_device_channel struct exists
+ * and channels can be attached to a domain both at build-time and at
+ * run-time by hotplug.
+ */
+#define LIBXL_HAVE_DEVICE_CHANNEL 1
+
/* Functions annotated with LIBXL_EXTERNAL_CALLERS_ONLY may not be
* called from within libxl itself. Callers outside libxl, who
* do not #include libxl_internal.h, are fine. */
@@ -956,6 +965,14 @@ libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx,
uint32_t domid, int *num
int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid,
libxl_device_nic *nic, libxl_nicinfo *nicinfo);
+/* Virtual Channels */
+libxl_device_channel *libxl_device_channel_list(libxl_ctx *ctx,
+ uint32_t domid,
+ int *num);
+int libxl_device_channel_getinfo(libxl_ctx *ctx, uint32_t domid,
+ libxl_device_channel *channel,
+ libxl_channelinfo *channelinfo);
+
/* Virtual TPMs */
int libxl_device_vtpm_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vtpm
*vtpm,
const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index d015cf4..ec5a4d6 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -355,14 +355,16 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
return 0;
}
-static int init_console_info(libxl__device_console *console, int dev_num)
+static int init_console_info(libxl__gc *gc,
+ libxl__device_console *console,
+ int dev_num)
{
- memset(console, 0x00, sizeof(libxl__device_console));
+ libxl__device_console_init(console);
console->devid = dev_num;
console->consback = LIBXL__CONSOLE_BACKEND_XENCONSOLED;
- console->output = strdup("pty");
- if (!console->output)
- return ERROR_NOMEM;
+ console->output = libxl__strdup(NOGC, "pty");
+ /* console->{name,kind,path} are NULL on normal consoles.
+ Only 'channels' when mapped to consoles have a string name. */
return 0;
}
@@ -1110,17 +1112,31 @@ static void domcreate_launch_dm(libxl__egc *egc,
libxl__multidev *multidev,
}
}
+ /* For both HVM and PV the 0th console is a regular console. We
+ map channels to IOEMU consoles starting at 1 */
+ for (i = 0; i < d_config->num_channels; i++) {
+ libxl__device_console console;
+ libxl__device device;
+ ret = libxl__init_console_from_channel(gc, &console, i + 1,
+ &d_config->channels[i]);
+ if ( ret )
+ goto error_out;
+ libxl__device_console_add(gc, domid, &console, NULL, &device);
+ libxl__device_console_dispose(&console);
+ }
+
switch (d_config->c_info.type) {
case LIBXL_DOMAIN_TYPE_HVM:
{
libxl__device_console console;
+ libxl__device device;
libxl_device_vkb vkb;
- ret = init_console_info(&console, 0);
+ ret = init_console_info(gc, &console, 0);
if ( ret )
goto error_out;
console.backend_domid = state->console_domid;
- libxl__device_console_add(gc, domid, &console, state);
+ libxl__device_console_add(gc, domid, &console, state, &device);
libxl__device_console_dispose(&console);
libxl_device_vkb_init(&vkb);
@@ -1138,22 +1154,24 @@ static void domcreate_launch_dm(libxl__egc *egc,
libxl__multidev *multidev,
{
int need_qemu = 0;
libxl__device_console console;
+ libxl__device device;
for (i = 0; i < d_config->num_vfbs; i++) {
libxl__device_vfb_add(gc, domid, &d_config->vfbs[i]);
libxl__device_vkb_add(gc, domid, &d_config->vkbs[i]);
}
- ret = init_console_info(&console, 0);
+ ret = init_console_info(gc, &console, 0);
if ( ret )
goto error_out;
need_qemu = libxl__need_xenpv_qemu(gc, 1, &console,
d_config->num_vfbs, d_config->vfbs,
- d_config->num_disks, &d_config->disks[0]);
+ d_config->num_disks, &d_config->disks[0],
+ d_config->num_channels, &d_config->channels[0]);
console.backend_domid = state->console_domid;
- libxl__device_console_add(gc, domid, &console, state);
+ libxl__device_console_add(gc, domid, &console, state, &device);
libxl__device_console_dispose(&console);
if (need_qemu) {
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 51ab2bf..4338b08 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -394,8 +394,9 @@ static char ** libxl__build_device_model_args_new(libxl__gc
*gc,
const libxl_sdl_info *sdl = dm_sdl(guest_config);
const char *keymap = dm_keymap(guest_config);
flexarray_t *dm_args;
- int i;
+ int i, kind, devid;
uint64_t ram_size;
+ const char *path, *chardev;
dm_args = flexarray_make(gc, 16, 1);
@@ -412,6 +413,27 @@ static char **
libxl__build_device_model_args_new(libxl__gc *gc,
flexarray_append(dm_args, "-mon");
flexarray_append(dm_args, "chardev=libxl-cmd,mode=control");
+ for (i = 0; i < guest_config->num_channels; i++) {
+ kind = guest_config->channels[i].kind;
+ devid = guest_config->channels[i].devid;
+ switch (kind) {
+ case LIBXL_CHANNEL_KIND_PTY:
+ chardev = GCSPRINTF("pty,id=libxl-channel%d", devid);
+ break;
+ case LIBXL_CHANNEL_KIND_SOCKET:
+ path = guest_config->channels[i].u.socket.path;
+ chardev = GCSPRINTF("socket,id=libxl-channel%d,path=%s,"
+ "server,nowait", devid, path);
+ break;
+ default:
+ /* We've forgotten to add the clause */
+ LOG(ERROR, "%s: unknown channel kind %d", __func__, kind);
+ return NULL;
+ }
+ flexarray_append(dm_args, "-chardev");
+ flexarray_append(dm_args, (void*)chardev);
+ }
+
/*
* Remove default devices created by qemu. Qemu will create only devices
* defined by xen, since the devices not defined by xen are not usable.
@@ -1067,6 +1089,7 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
}
for (i = 0; i < num_console; i++) {
+ libxl__device device;
console[i].devid = i;
console[i].consback = LIBXL__CONSOLE_BACKEND_IOEMU;
/* STUBDOM_CONSOLE_LOGGING (console 0) is for minios logging
@@ -1097,7 +1120,8 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
break;
}
ret = libxl__device_console_add(gc, dm_domid, &console[i],
- i == STUBDOM_CONSOLE_LOGGING ? stubdom_state : NULL);
+ i == STUBDOM_CONSOLE_LOGGING ? stubdom_state : NULL,
+ &device);
if (ret)
goto out;
}
@@ -1517,7 +1541,8 @@ int libxl__destroy_device_model(libxl__gc *gc, uint32_t
domid)
int libxl__need_xenpv_qemu(libxl__gc *gc,
int nr_consoles, libxl__device_console *consoles,
int nr_vfbs, libxl_device_vfb *vfbs,
- int nr_disks, libxl_device_disk *disks)
+ int nr_disks, libxl_device_disk *disks,
+ int nr_channels, libxl_device_channel *channels)
{
int i, ret = 0;
uint32_t domid;
@@ -1557,6 +1582,18 @@ int libxl__need_xenpv_qemu(libxl__gc *gc,
}
}
+ if (nr_channels > 0) {
+ ret = libxl__get_domid(gc, &domid);
+ if (ret) goto out;
+ for (i = 0; i < nr_channels; i++) {
+ if (channels[i].kind == LIBXL_CHANNEL_KIND_SOCKET &&
+ channels[i].backend_domid == domid) {
+ ret = 1;
+ goto out;
+ }
+ }
+ }
+
out:
return ret;
}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 082749e..8053663 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1018,7 +1018,8 @@ _hidden int libxl__device_disk_dev_number(const char
*virtpath,
_hidden int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
libxl__device_console *console,
- libxl__domain_build_state *state);
+ libxl__domain_build_state *state,
+ libxl__device *device);
_hidden int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t,
libxl__device *device, char **bents, char **fents, char **ro_fents);
@@ -1031,6 +1032,10 @@ _hidden int libxl__wait_for_backend(libxl__gc *gc, const
char *be_path,
const char *state);
_hidden int libxl__nic_type(libxl__gc *gc, libxl__device *dev,
libxl_nic_type *nictype);
+_hidden int libxl__init_console_from_channel(libxl__gc *gc,
+ libxl__device_console *console,
+ int dev_num,
+ libxl_device_channel *channel);
/*
* For each aggregate type which can be used as an input we provide:
@@ -1450,7 +1455,8 @@ _hidden const char *libxl__domain_device_model(libxl__gc
*gc,
_hidden int libxl__need_xenpv_qemu(libxl__gc *gc,
int nr_consoles, libxl__device_console *consoles,
int nr_vfbs, libxl_device_vfb *vfbs,
- int nr_disks, libxl_device_disk *disks);
+ int nr_disks, libxl_device_disk *disks,
+ int nr_channels, libxl_device_channel *channels);
/*
* This function will cause the whole libxl process to hang
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 52f1aa9..025bffd 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -51,6 +51,14 @@ libxl_domain_type = Enumeration("domain_type", [
(2, "PV"),
], init_val = -1)
+libxl_channel_kind = Enumeration("channel_kind", [
+ (0, "UNKNOWN"),
+ # Connect to a pty in the backend domain:
+ (1, "PTY"),
+ # Listen on a Unix domain socket in the backend domain:
+ (2, "SOCKET"),
+ ])
+
libxl_device_model_version = Enumeration("device_model_version", [
(0, "UNKNOWN"),
(1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm)
@@ -245,6 +253,22 @@ libxl_cpupoolinfo = Struct("cpupoolinfo", [
("cpumap", libxl_bitmap)
], dir=DIR_OUT)
+libxl_channelinfo = Struct("channelinfo", [
+ ("backend", string),
+ ("backend_id", uint32),
+ ("frontend", string),
+ ("frontend_id", uint32),
+ ("devid", libxl_devid),
+ ("state", integer),
+ ("evtch", integer),
+ ("rref", integer),
+ ("u", KeyedUnion(None, libxl_channel_kind, "kind",
+ [("unknown", None),
+ ("pty", Struct(None, [("path", string),])),
+ ("socket", None),
+ ])),
+ ], dir=DIR_OUT)
+
libxl_vminfo = Struct("vminfo", [
("uuid", libxl_uuid),
("domid", libxl_domid),
@@ -457,6 +481,18 @@ libxl_device_vtpm = Struct("device_vtpm", [
("uuid", libxl_uuid),
])
+libxl_device_channel = Struct("device_channel", [
+ ("backend_domid", libxl_domid),
+ ("backend_domname", string),
+ ("devid", libxl_devid),
+ ("name", string),
+ ("u", KeyedUnion(None, libxl_channel_kind, "kind",
+ [("unknown", None),
+ ("pty", None),
+ ("socket", Struct(None, [("path", string)])),
+ ])),
+])
+
libxl_domain_config = Struct("domain_config", [
("c_info", libxl_domain_create_info),
("b_info", libxl_domain_build_info),
@@ -467,6 +503,7 @@ libxl_domain_config = Struct("domain_config", [
("vfbs", Array(libxl_device_vfb, "num_vfbs")),
("vkbs", Array(libxl_device_vkb, "num_vkbs")),
("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
+ ("channels", Array(libxl_device_channel, "num_channels")),
("on_poweroff", libxl_action_on_shutdown),
("on_reboot", libxl_action_on_shutdown),
diff --git a/tools/libxl/libxl_types_internal.idl
b/tools/libxl/libxl_types_internal.idl
index cb9444f..7d1e22c 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -32,6 +32,10 @@ libxl__device_console = Struct("device_console", [
("devid", integer),
("consback", libxl__console_backend),
("output", string),
+ # These are specific to the 'channels', built on top of consoles:
+ ("name", string),
+ ("kind", string),
+ ("path", string),
])
libxl__device_action = Enumeration("device_action", [
--
1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |