mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
libxl: add vdispl device
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com> Acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
1 parent
1b700c5ae5
commit
191ea81e6f
8 files changed
+352
-1
No files matched your search
@@ -138,7 +138,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
|
||||
libxl_dom_suspend.o libxl_dom_save.o libxl_usb.o \
|
||||
libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
|
||||
libxl_cpupool.o libxl_mem.o libxl_sched.o libxl_tmem.o \
|
||||
libxl_9pfs.o libxl_domain.o \
|
||||
libxl_9pfs.o libxl_domain.o libxl_vdispl.o \
|
||||
$(LIBXL_OBJS-y)
|
||||
LIBXL_OBJS += libxl_genid.o
|
||||
LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
|
||||
|
||||
@@ -1877,6 +1877,30 @@ libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *n
|
||||
int libxl_device_vtpm_getinfo(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_vtpm *vtpm, libxl_vtpminfo *vtpminfo);
|
||||
|
||||
/* Virtual displays */
|
||||
int libxl_device_vdispl_add(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_vdispl *displ,
|
||||
const libxl_asyncop_how *ao_how)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
int libxl_device_vdispl_remove(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
const libxl_asyncop_how *ao_how)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
int libxl_device_vdispl_destroy(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
const libxl_asyncop_how *ao_how)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
|
||||
libxl_device_vdispl *libxl_device_vdispl_list(libxl_ctx *ctx,
|
||||
uint32_t domid, int *num)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
void libxl_device_vdispl_list_free(libxl_device_vdispl* list, int num)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
int libxl_device_vdispl_getinfo(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
libxl_vdisplinfo *vdisplinfo)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
|
||||
/* Keyboard */
|
||||
int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
|
||||
const libxl_asyncop_how *ao_how)
|
||||
|
||||
@@ -1446,6 +1446,7 @@ const struct libxl_device_type *device_type_tbl[] = {
|
||||
&libxl__usbdev_devtype,
|
||||
&libxl__pcidev_devtype,
|
||||
&libxl__dtdev_devtype,
|
||||
&libxl__vdispl_devtype,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -3563,6 +3563,7 @@ extern const struct libxl_device_type libxl__vtpm_devtype;
|
||||
extern const struct libxl_device_type libxl__usbctrl_devtype;
|
||||
extern const struct libxl_device_type libxl__usbdev_devtype;
|
||||
extern const struct libxl_device_type libxl__pcidev_devtype;
|
||||
extern const struct libxl_device_type libxl__vdispl_devtype;
|
||||
|
||||
extern const struct libxl_device_type *device_type_tbl[];
|
||||
|
||||
|
||||
@@ -779,6 +779,20 @@ libxl_device_channel = Struct("device_channel", [
|
||||
])),
|
||||
])
|
||||
|
||||
libxl_connector_param = Struct("connector_param", [
|
||||
("id", string),
|
||||
("width", uint32),
|
||||
("height", uint32)
|
||||
])
|
||||
|
||||
libxl_device_vdispl = Struct("device_vdispl", [
|
||||
("backend_domid", libxl_domid),
|
||||
("backend_domname", string),
|
||||
("devid", libxl_devid),
|
||||
("be_alloc", bool),
|
||||
("connectors", Array(libxl_connector_param, "num_connectors"))
|
||||
])
|
||||
|
||||
libxl_domain_config = Struct("domain_config", [
|
||||
("c_info", libxl_domain_create_info),
|
||||
("b_info", libxl_domain_build_info),
|
||||
@@ -792,6 +806,7 @@ libxl_domain_config = Struct("domain_config", [
|
||||
("vkbs", Array(libxl_device_vkb, "num_vkbs")),
|
||||
("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
|
||||
("p9s", Array(libxl_device_p9, "num_p9s")),
|
||||
("vdispls", Array(libxl_device_vdispl, "num_vdispls")),
|
||||
# a channel manifests as a console with a name,
|
||||
# see docs/misc/channels.txt
|
||||
("channels", Array(libxl_device_channel, "num_channels")),
|
||||
@@ -888,6 +903,27 @@ libxl_physinfo = Struct("physinfo", [
|
||||
("cap_hvm_directio", bool),
|
||||
], dir=DIR_OUT)
|
||||
|
||||
libxl_connectorinfo = Struct("connectorinfo", [
|
||||
("id", string),
|
||||
("width", uint32),
|
||||
("height", uint32),
|
||||
("req_evtch", integer),
|
||||
("req_rref", integer),
|
||||
("evt_evtch", integer),
|
||||
("evt_rref", integer),
|
||||
], dir=DIR_OUT)
|
||||
|
||||
libxl_vdisplinfo = Struct("vdisplinfo", [
|
||||
("backend", string),
|
||||
("backend_id", uint32),
|
||||
("frontend", string),
|
||||
("frontend_id", uint32),
|
||||
("devid", libxl_devid),
|
||||
("state", integer),
|
||||
("be_alloc", bool),
|
||||
("connectors", Array(libxl_connectorinfo, "num_connectors"))
|
||||
], dir=DIR_OUT)
|
||||
|
||||
# NUMA node characteristics: size and free are how much memory it has, and how
|
||||
# much of it is free, respectively. dists is an array of distances from this
|
||||
# node to each other node.
|
||||
|
||||
@@ -26,6 +26,7 @@ libxl__device_kind = Enumeration("device_kind", [
|
||||
(9, "VUSB"),
|
||||
(10, "QUSB"),
|
||||
(11, "9PFS"),
|
||||
(12, "VDISPL"),
|
||||
])
|
||||
|
||||
libxl__console_backend = Enumeration("console_backend", [
|
||||
|
||||
@@ -78,6 +78,10 @@ int libxl_devid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
|
||||
int devid, libxl_device_vtpm *vtpm);
|
||||
int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid,
|
||||
int devid, libxl_device_usbctrl *usbctrl);
|
||||
|
||||
int libxl_devid_to_device_vdispl(libxl_ctx *ctx, uint32_t domid,
|
||||
int devid, libxl_device_vdispl *vdispl);
|
||||
|
||||
int libxl_ctrlport_to_device_usbdev(libxl_ctx *ctx, uint32_t domid,
|
||||
int ctrl, int port,
|
||||
libxl_device_usbdev *usbdev);
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2016 EPAM Systems Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; version 2.1 only. with the special
|
||||
* exception on linking described in file LICENSE.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "libxl_internal.h"
|
||||
|
||||
static int libxl__device_vdispl_setdefault(libxl__gc *gc, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
bool hotplug)
|
||||
{
|
||||
return libxl__resolve_domid(gc, vdispl->backend_domname,
|
||||
&vdispl->backend_domid);
|
||||
}
|
||||
|
||||
static int libxl__device_from_vdispl(libxl__gc *gc, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
libxl__device *device)
|
||||
{
|
||||
device->backend_devid = vdispl->devid;
|
||||
device->backend_domid = vdispl->backend_domid;
|
||||
device->backend_kind = LIBXL__DEVICE_KIND_VDISPL;
|
||||
device->devid = vdispl->devid;
|
||||
device->domid = domid;
|
||||
device->kind = LIBXL__DEVICE_KIND_VDISPL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libxl__vdispl_from_xenstore(libxl__gc *gc, const char *libxl_path,
|
||||
libxl_devid devid,
|
||||
libxl_device_vdispl *vdispl)
|
||||
{
|
||||
char *be_path;
|
||||
|
||||
vdispl->devid = devid;
|
||||
be_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/backend", libxl_path));
|
||||
|
||||
return libxl__backendpath_parse_domid(gc, be_path, &vdispl->backend_domid);
|
||||
}
|
||||
|
||||
static void libxl__update_config_vdispl(libxl__gc *gc,
|
||||
libxl_device_vdispl *dst,
|
||||
libxl_device_vdispl *src)
|
||||
{
|
||||
dst->devid = src->devid;
|
||||
dst->be_alloc = src->be_alloc;
|
||||
}
|
||||
|
||||
static int libxl_device_vdispl_compare(libxl_device_vdispl *d1,
|
||||
libxl_device_vdispl *d2)
|
||||
{
|
||||
return COMPARE_DEVID(d1, d2);
|
||||
}
|
||||
|
||||
static void libxl__device_vdispl_add(libxl__egc *egc, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
libxl__ao_device *aodev)
|
||||
{
|
||||
libxl__device_add_async(egc, domid, &libxl__vdispl_devtype, vdispl, aodev);
|
||||
}
|
||||
|
||||
static int libxl__set_xenstore_vdispl(libxl__gc *gc, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
flexarray_t *back, flexarray_t *front,
|
||||
flexarray_t *ro_front)
|
||||
{
|
||||
int i;
|
||||
|
||||
flexarray_append_pair(ro_front, "be-alloc",
|
||||
GCSPRINTF("%d", vdispl->be_alloc));
|
||||
|
||||
for (i = 0; i < vdispl->num_connectors; i++) {
|
||||
flexarray_append_pair(ro_front, GCSPRINTF("%d/resolution", i),
|
||||
GCSPRINTF("%dx%d", vdispl->connectors[i].width,
|
||||
vdispl->connectors[i].height));
|
||||
flexarray_append_pair(ro_front, GCSPRINTF("%d/id", i),
|
||||
vdispl->connectors[i].id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
libxl_device_vdispl *libxl_device_vdispl_list(libxl_ctx *ctx, uint32_t domid,
|
||||
int *num)
|
||||
{
|
||||
libxl_device_vdispl *r;
|
||||
|
||||
GC_INIT(ctx);
|
||||
|
||||
r = libxl__device_list(gc, &libxl__vdispl_devtype, domid, "vdispl", num);
|
||||
|
||||
GC_FREE;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void libxl_device_vdispl_list_free(libxl_device_vdispl* list, int num)
|
||||
{
|
||||
libxl__device_list_free(&libxl__vdispl_devtype, list, num);
|
||||
}
|
||||
|
||||
static int libxl__device_vdispl_getconnectors(libxl_ctx *ctx,
|
||||
const char *path,
|
||||
libxl_vdisplinfo *info)
|
||||
{
|
||||
GC_INIT(ctx);
|
||||
char *connector = NULL;
|
||||
char *connector_path;
|
||||
int i, rc;
|
||||
|
||||
info->num_connectors = 0;
|
||||
|
||||
connector_path = GCSPRINTF("%s/%d", path, info->num_connectors);
|
||||
|
||||
while ((connector = xs_read(ctx->xsh, XBT_NULL, connector_path, NULL)) !=
|
||||
NULL) {
|
||||
free(connector);
|
||||
connector_path = GCSPRINTF("%s/%d", path, ++info->num_connectors);
|
||||
}
|
||||
|
||||
info->connectors = libxl__calloc(NOGC, info->num_connectors,
|
||||
sizeof(*info->connectors));
|
||||
|
||||
for (i = 0; i < info->num_connectors; i++) {
|
||||
char *value;
|
||||
char *value_path;
|
||||
|
||||
value_path = GCSPRINTF("%s/%d/id", path, i);
|
||||
info->connectors[i].id = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
||||
if (info->connectors[i].id == NULL) { rc = ERROR_FAIL; goto out; }
|
||||
|
||||
value_path = GCSPRINTF("%s/%d/resolution", path, i);
|
||||
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
||||
if (value == NULL) { rc = ERROR_FAIL; goto out; }
|
||||
|
||||
rc = sscanf(value, "%ux%u", &info->connectors[i].width,
|
||||
&info->connectors[i].height);
|
||||
free(value);
|
||||
|
||||
if (rc != 2) {
|
||||
rc = ERROR_FAIL; goto out;
|
||||
}
|
||||
|
||||
value_path = GCSPRINTF("%s/%d/req-ring-ref", path, i);
|
||||
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
||||
info->connectors[i].req_rref = value ? strtoul(value, NULL, 10) : -1;
|
||||
free(value);
|
||||
|
||||
value_path = GCSPRINTF("%s/%d/req-event-channel", path, i);
|
||||
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
||||
info->connectors[i].req_evtch = value ? strtoul(value, NULL, 10) : -1;
|
||||
free(value);
|
||||
|
||||
value_path = GCSPRINTF("%s/%d/evt-ring-ref", path, i);
|
||||
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
||||
info->connectors[i].evt_rref = value ? strtoul(value, NULL, 10) : -1;
|
||||
free(value);
|
||||
|
||||
value_path = GCSPRINTF("%s/%d/evt-event-channel", path, i);
|
||||
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
||||
info->connectors[i].evt_evtch = value ? strtoul(value, NULL, 10) : -1;
|
||||
free(value);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_device_vdispl_getinfo(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_vdispl *vdispl,
|
||||
libxl_vdisplinfo *info)
|
||||
{
|
||||
GC_INIT(ctx);
|
||||
char *libxl_path, *dompath, *devpath;
|
||||
char *val;
|
||||
int rc;
|
||||
|
||||
libxl_vdisplinfo_init(info);
|
||||
dompath = libxl__xs_get_dompath(gc, domid);
|
||||
info->devid = vdispl->devid;
|
||||
|
||||
devpath = GCSPRINTF("%s/device/vdispl/%d", dompath, info->devid);
|
||||
libxl_path = GCSPRINTF("%s/device/vdispl/%d",
|
||||
libxl__xs_libxl_path(gc, domid),
|
||||
info->devid);
|
||||
info->backend = xs_read(ctx->xsh, XBT_NULL,
|
||||
GCSPRINTF("%s/backend", libxl_path),
|
||||
NULL);
|
||||
if (!info->backend) { rc = ERROR_FAIL; goto out; }
|
||||
|
||||
rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id);
|
||||
if (rc) goto out;
|
||||
|
||||
val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", devpath));
|
||||
info->state = val ? strtoul(val, NULL, 10) : -1;
|
||||
|
||||
info->frontend = xs_read(ctx->xsh, XBT_NULL,
|
||||
GCSPRINTF("%s/frontend", libxl_path),
|
||||
NULL);
|
||||
info->frontend_id = domid;
|
||||
|
||||
val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/be-alloc", devpath));
|
||||
info->be_alloc = val ? strtoul(val, NULL, 10) : 0;
|
||||
|
||||
rc = libxl__device_vdispl_getconnectors(ctx, devpath, info);
|
||||
if (rc) goto out;
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
GC_FREE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int libxl_devid_to_device_vdispl(libxl_ctx *ctx, uint32_t domid,
|
||||
int devid, libxl_device_vdispl *vdispl)
|
||||
{
|
||||
GC_INIT(ctx);
|
||||
|
||||
libxl_device_vdispl *vdispls = NULL;
|
||||
int n, i;
|
||||
int rc;
|
||||
|
||||
libxl_device_vdispl_init(vdispl);
|
||||
|
||||
vdispls = libxl__device_list(gc, &libxl__vdispl_devtype,
|
||||
domid, "vdispl", &n);
|
||||
|
||||
if (!vdispls) { rc = ERROR_NOTFOUND; goto out; }
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (devid == vdispls[i].devid) {
|
||||
libxl_device_vdispl_copy(ctx, vdispl, &vdispls[i]);
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ERROR_NOTFOUND;
|
||||
|
||||
out:
|
||||
|
||||
if (vdispls)
|
||||
libxl__device_list_free(&libxl__vdispl_devtype, vdispls, n);
|
||||
|
||||
GC_FREE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
LIBXL_DEFINE_DEVICE_ADD(vdispl)
|
||||
static LIBXL_DEFINE_DEVICES_ADD(vdispl)
|
||||
LIBXL_DEFINE_DEVICE_REMOVE(vdispl)
|
||||
static LIBXL_DEFINE_UPDATE_DEVID(vdispl, "vdispl")
|
||||
|
||||
DEFINE_DEVICE_TYPE_STRUCT(vdispl,
|
||||
.update_config = (void (*)(libxl__gc *, void *, void *))
|
||||
libxl__update_config_vdispl,
|
||||
.from_xenstore = (int (*)(libxl__gc *, const char *, libxl_devid, void *))
|
||||
libxl__vdispl_from_xenstore,
|
||||
.set_xenstore_config = (int (*)(libxl__gc *, uint32_t, void *,
|
||||
flexarray_t *back, flexarray_t *front,
|
||||
flexarray_t *ro_front))
|
||||
libxl__set_xenstore_vdispl
|
||||
);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||