From 86741b1f4a2578df3fda7ff73cc208041d5e87b3 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Tue, 20 Sep 2016 16:18:08 +0200 Subject: [PATCH] libxl: add basic support for devices without backend With the planned support of HVM USB passthrough via the USB emulation capabilities of qemu libxl has to support guest devices which have no back- and frontend. Information about those devices will live in the libxl part of Xenstore only. Add some basic support to libxl to be able to cope with this scenario. Signed-off-by: Juergen Gross Acked-by: Wei Liu --- tools/libxl/libxl_device.c | 70 +++++++++++++++++++--------- tools/libxl/libxl_types_internal.idl | 1 + tools/libxl/libxl_xshelp.c | 6 ++- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index dbf157d469..1cc90985d0 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -114,15 +114,21 @@ int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t, libxl__device *device, char **bents, char **fents, char **ro_fents) { libxl_ctx *ctx = libxl__gc_owner(gc); - char *frontend_path, *backend_path, *libxl_path; + char *frontend_path = NULL, *backend_path = NULL, *libxl_path; struct xs_permissions frontend_perms[2]; struct xs_permissions ro_frontend_perms[2]; struct xs_permissions backend_perms[2]; int create_transaction = t == XBT_NULL; + int libxl_only = device->backend_kind == LIBXL__DEVICE_KIND_NONE; int rc; - frontend_path = libxl__device_frontend_path(gc, device); - backend_path = libxl__device_backend_path(gc, device); + if (libxl_only) { + /* bents should be set as this is used to setup libxl_path content. */ + assert(!fents && !ro_fents); + } else { + frontend_path = libxl__device_frontend_path(gc, device); + backend_path = libxl__device_backend_path(gc, device); + } libxl_path = libxl__device_libxl_path(gc, device); frontend_perms[0].id = device->domid; @@ -144,13 +150,15 @@ retry_transaction: rc = libxl__xs_rm_checked(gc, t, libxl_path); if (rc) goto out; - rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/frontend",libxl_path), - frontend_path); - if (rc) goto out; + if (!libxl_only) { + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/frontend",libxl_path), + frontend_path); + if (rc) goto out; - rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/backend",libxl_path), - backend_path); - if (rc) goto out; + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/backend",libxl_path), + backend_path); + if (rc) goto out; + } /* xxx much of this function lacks error checks! */ @@ -179,12 +187,15 @@ retry_transaction: } if (bents) { - xs_rm(ctx->xsh, t, backend_path); - xs_mkdir(ctx->xsh, t, backend_path); - xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, ARRAY_SIZE(backend_perms)); - xs_write(ctx->xsh, t, GCSPRINTF("%s/frontend", backend_path), - frontend_path, strlen(frontend_path)); - libxl__xs_writev(gc, t, backend_path, bents); + if (!libxl_only) { + xs_rm(ctx->xsh, t, backend_path); + xs_mkdir(ctx->xsh, t, backend_path); + xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, + ARRAY_SIZE(backend_perms)); + xs_write(ctx->xsh, t, GCSPRINTF("%s/frontend", backend_path), + frontend_path, strlen(frontend_path)); + libxl__xs_writev(gc, t, backend_path, bents); + } /* * We make a copy of everything for the backend in the libxl @@ -194,6 +205,9 @@ retry_transaction: * instead. But there are still places in libxl that try to * reconstruct a config from xenstore. * + * For devices without PV backend (e.g. USB devices emulated via qemu) + * only the libxl path is written. + * * This duplication will typically produces duplicate keys * which will go out of date, but that's OK because nothing * reads those. For example, there is usually @@ -679,14 +693,21 @@ void libxl__multidev_prepared(libxl__egc *egc, int libxl__device_destroy(libxl__gc *gc, libxl__device *dev) { - const char *be_path = libxl__device_backend_path(gc, dev); - const char *fe_path = libxl__device_frontend_path(gc, dev); + const char *be_path = NULL; + const char *fe_path = NULL; const char *libxl_path = libxl__device_libxl_path(gc, dev); - const char *tapdisk_path = GCSPRINTF("%s/%s", be_path, "tapdisk-params"); - const char *tapdisk_params; + const char *tapdisk_path = NULL; + const char *tapdisk_params = NULL; xs_transaction_t t = 0; int rc; uint32_t domid; + int libxl_only = dev->backend_kind == LIBXL__DEVICE_KIND_NONE; + + if (!libxl_only) { + be_path = libxl__device_backend_path(gc, dev); + fe_path = libxl__device_frontend_path(gc, dev); + tapdisk_path = GCSPRINTF("%s/%s", be_path, "tapdisk-params"); + } rc = libxl__get_domid(gc, &domid); if (rc) goto out; @@ -696,18 +717,21 @@ int libxl__device_destroy(libxl__gc *gc, libxl__device *dev) if (rc) goto out; /* May not exist if this is not a tap device */ - rc = libxl__xs_read_checked(gc, t, tapdisk_path, &tapdisk_params); - if (rc) goto out; + if (tapdisk_path) { + rc = libxl__xs_read_checked(gc, t, tapdisk_path, &tapdisk_params); + if (rc) goto out; + } if (domid == LIBXL_TOOLSTACK_DOMID) { /* * The toolstack domain is in charge of removing the * frontend and libxl paths. */ - libxl__xs_path_cleanup(gc, t, fe_path); + if (!libxl_only) + libxl__xs_path_cleanup(gc, t, fe_path); libxl__xs_path_cleanup(gc, t, libxl_path); } - if (dev->backend_domid == domid) { + if (dev->backend_domid == domid && !libxl_only) { /* * The driver domain is in charge of removing what it can * from the backend path. diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl index 177f9b7a73..82e5c0759a 100644 --- a/tools/libxl/libxl_types_internal.idl +++ b/tools/libxl/libxl_types_internal.idl @@ -14,6 +14,7 @@ libxl__qmp_message_type = Enumeration("qmp_message_type", [ ]) libxl__device_kind = Enumeration("device_kind", [ + (0, "NONE"), (1, "VIF"), (2, "VBD"), (3, "QDISK"), diff --git a/tools/libxl/libxl_xshelp.c b/tools/libxl/libxl_xshelp.c index 4982b52b57..b3bac6d270 100644 --- a/tools/libxl/libxl_xshelp.c +++ b/tools/libxl/libxl_xshelp.c @@ -20,8 +20,12 @@ char **libxl__xs_kvs_of_flexarray(libxl__gc *gc, flexarray_t *array) { char **kvs; - int i, length = array->count; + int i, length; + if (!array) + return NULL; + + length = array->count; if (!length) return NULL; -- 2.39.5