* [Qemu-devel] [PATCH V3 01/13] libxl_qmp: Fix return check of fcntl
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 02/13] libxl_json: Check the parser status before to call parse_complete Anthony PERARD
` (12 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_qmp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 618f20f..ef36348 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -296,7 +296,7 @@ static int qmp_open(libxl__qmp_handler *qmp, const char *qmp_socket_path,
if (qmp->qmp_fd < 0) {
return -1;
}
- if ((flags = fcntl(qmp->qmp_fd, F_GETFL)) == 1) {
+ if ((flags = fcntl(qmp->qmp_fd, F_GETFL)) == -1) {
flags = 0;
}
if (fcntl(qmp->qmp_fd, F_SETFL, flags | O_NONBLOCK) == -1) {
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 02/13] libxl_json: Check the parser status before to call parse_complete
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 01/13] libxl_qmp: Fix return check of fcntl Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 03/13] libxl_qmp: Better error message after a parse error Anthony PERARD
` (11 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Also, use goto to handle an error.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_json.c | 37 ++++++++++++++++++++-----------------
1 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index 11f65fc..389b697 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -730,6 +730,8 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s)
{
yajl_status status;
libxl__yajl_ctx yajl_ctx;
+ libxl__json_object *o = NULL;
+ unsigned char *str = NULL;
memset(&yajl_ctx, 0, sizeof (yajl_ctx));
yajl_ctx.gc = gc;
@@ -744,30 +746,31 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s)
yajl_ctx.hand = yajl_alloc(&callbacks, &cfg, NULL, &yajl_ctx);
}
status = yajl_parse(yajl_ctx.hand, (const unsigned char *)s, strlen(s));
+ if (status != yajl_status_ok)
+ goto out;
+
status = yajl_parse_complete(yajl_ctx.hand);
+ if (status != yajl_status_ok)
+ goto out;
- if (status == yajl_status_ok) {
- libxl__json_object *o = yajl_ctx.head;
+ o = yajl_ctx.head;
- DEBUG_GEN_REPORT(&yajl_ctx);
+ DEBUG_GEN_REPORT(&yajl_ctx);
- yajl_ctx.head = NULL;
+ yajl_ctx.head = NULL;
- yajl_ctx_free(&yajl_ctx);
- return o;
- } else {
- unsigned char *str = yajl_get_error(yajl_ctx.hand, 1,
- (const unsigned char *)s,
- strlen(s));
+ yajl_ctx_free(&yajl_ctx);
+ return o;
- LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
- "yajl error: %s", str);
- yajl_free_error(yajl_ctx.hand, str);
+out:
+ str = yajl_get_error(yajl_ctx.hand, 1, (const unsigned char*)s, strlen(s));
- libxl__json_object_free(gc, yajl_ctx.head);
- yajl_ctx_free(&yajl_ctx);
- return NULL;
- }
+ LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR, "yajl error: %s", str);
+ yajl_free_error(yajl_ctx.hand, str);
+
+ libxl__json_object_free(gc, yajl_ctx.head);
+ yajl_ctx_free(&yajl_ctx);
+ return NULL;
}
static const char *yajl_gen_status_to_string(yajl_gen_status s)
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 03/13] libxl_qmp: Better error message after a parse error.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 01/13] libxl_qmp: Fix return check of fcntl Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 02/13] libxl_json: Check the parser status before to call parse_complete Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 04/13] libxl: Introduce dm-version xenstore key Anthony PERARD
` (10 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
By setting the next string to parse after having printed any error messages.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_qmp.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index ef36348..f61a87a 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -403,7 +403,6 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
*end = '\0';
o = libxl__json_parse(gc, s);
- s = end + 2;
if (o) {
qmp_handle_response(qmp, o);
@@ -413,6 +412,8 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
"Parse error of : %s\n", s);
return -1;
}
+
+ s = end + 2;
} else {
break;
}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 04/13] libxl: Introduce dm-version xenstore key.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (2 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 03/13] libxl_qmp: Better error message after a parse error Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 05/13] libxl_qmp: Introduce an opaque argument to the callbacks Anthony PERARD
` (9 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
The all key is /libxl/$domid/dm-version.
The /libxl/$domid dir is created with the domain and should be only accessible
by the toolstack domain. The function libxl__xs_libxl_path() give this path.
This come with libxl__device_model_version_running() helper function.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl.c | 2 ++
tools/libxl/libxl_create.c | 29 ++++++++++++++++++++++++++++-
tools/libxl/libxl_internal.c | 23 +++++++++++++++++++++++
tools/libxl/libxl_internal.h | 7 +++++++
tools/libxl/libxl_xshelp.c | 9 +++++++++
5 files changed, 69 insertions(+), 1 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 064fbc4..22a7795 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -777,6 +777,8 @@ int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force)
if (!xs_rm(ctx->xsh, XBT_NULL, dom_path))
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xs_rm failed for %s", dom_path);
+ xs_rm(ctx->xsh, XBT_NULL, libxl__xs_libxl_path(&gc, domid));
+
libxl__userdata_destroyall(&gc, domid);
rc = xc_domain_destroy(ctx->xch, domid);
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 68d0fc3..9506aa4 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -316,12 +316,14 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
char *rw_paths[] = { "control/shutdown", "device", "device/suspend/event-channel" , "data"};
char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
"control", "attr", "messages" };
- char *dom_path, *vm_path;
+ char *dom_path, *vm_path, *libxl_path;
struct xs_permissions roperm[2];
struct xs_permissions rwperm[1];
+ struct xs_permissions noperm[1];
xs_transaction_t t = 0;
xen_domain_handle_t handle;
+
assert(!libxl_domid_valid_guest(*domid));
uuid_string = libxl__uuid2string(gc, info->uuid);
@@ -368,6 +370,14 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
goto out;
}
+ libxl_path = libxl__xs_libxl_path(gc, *domid);
+ if (!libxl_path) {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ noperm[0].id = 0;
+ noperm[0].perms = XS_PERM_NONE;
+
roperm[0].id = 0;
roperm[0].perms = XS_PERM_NONE;
roperm[1].id = *domid;
@@ -386,6 +396,10 @@ retry_transaction:
xs_mkdir(ctx->xsh, t, vm_path);
xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
+ xs_rm(ctx->xsh, t, libxl_path);
+ xs_mkdir(ctx->xsh, t, libxl_path);
+ xs_set_permissions(ctx->xsh, t, libxl_path, noperm, ARRAY_SIZE(noperm));
+
xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path), vm_path, strlen(vm_path));
rc = libxl__domain_rename(gc, *domid, 0, info->name, t);
if (rc)
@@ -429,6 +443,17 @@ retry_transaction:
return rc;
}
+static int store_libxl_entry(libxl__gc *gc, uint32_t domid,
+ libxl_device_model_info *dm_info)
+{
+ char *path = NULL;
+
+ path = libxl__xs_libxl_path(gc, domid);
+ path = libxl__sprintf(gc, "%s/dm-version", path);
+ return libxl__xs_write(gc, XBT_NULL, path, libxl__strdup(gc,
+ libxl_device_model_version_to_string(dm_info->device_model_version)));
+}
+
static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
libxl_console_ready cb, void *priv,
uint32_t *domid_out, int restore_fd)
@@ -485,6 +510,8 @@ static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
goto error_out;
}
+ store_libxl_entry(gc, domid, dm_info);
+
for (i = 0; i < d_config->num_disks; i++) {
ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]);
if (ret) {
diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index 3993d8e..34edaf3 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -319,6 +319,29 @@ int libxl__fd_set_cloexec(int fd)
return fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
+libxl_device_model_version libxl__device_model_version_running(libxl__gc *gc,
+ uint32_t domid)
+{
+ char *path = NULL;
+ char *dm_version = NULL;
+ libxl_device_model_version value;
+
+ path = libxl__xs_libxl_path(gc, domid);
+ path = libxl__sprintf(gc, "%s/dm-version", path);
+ dm_version = libxl__xs_read(gc, XBT_NULL, path);
+ if (!dm_version) {
+ return LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL;
+ }
+
+ if (libxl_device_model_version_from_string(dm_version, &value) < 0) {
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "fatal: %s contain a wrong value (%s)", path, dm_version);
+ return -1;
+ }
+ return value;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 2e26ac6..942d45b 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -195,6 +195,8 @@ _hidden char **libxl__xs_directory(libxl__gc *gc, xs_transaction_t t,
char *path, unsigned int *nb);
/* On error: returns NULL, sets errno (no logging) */
+_hidden char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid);
+
/* from xl_dom */
_hidden libxl_domain_type libxl__domain_type(libxl__gc *gc, uint32_t domid);
_hidden int libxl__domain_shutdown_reason(libxl__gc *gc, uint32_t domid);
@@ -554,6 +556,11 @@ _hidden void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj);
_hidden libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s);
+ /* Based on /local/domain/$domid/dm-version xenstore key
+ * default is qemu xen traditional */
+_hidden libxl_device_model_version
+libxl__device_model_version_running(libxl__gc *gc, uint32_t domid);
+
#endif
/*
diff --git a/tools/libxl/libxl_xshelp.c b/tools/libxl/libxl_xshelp.c
index e41f962..4b09be3 100644
--- a/tools/libxl/libxl_xshelp.c
+++ b/tools/libxl/libxl_xshelp.c
@@ -122,6 +122,15 @@ char **libxl__xs_directory(libxl__gc *gc, xs_transaction_t t, char *path, unsign
return ret;
}
+char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *s = libxl__sprintf(gc, "/libxl/%i", domid);
+ if (!s)
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
+ return s;
+}
+
/*
* Local variables:
* mode: C
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 05/13] libxl_qmp: Introduce an opaque argument to the callbacks.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (3 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 04/13] libxl: Introduce dm-version xenstore key Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 06/13] libxl_qmp: Introduce list of arguments to qmp_send Anthony PERARD
` (8 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_qmp.c | 30 +++++++++++++++++++-----------
1 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index f61a87a..ddc0a4d 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -43,11 +43,13 @@
#define QMP_RECEIVE_BUFFER_SIZE 4096
typedef int (*qmp_callback_t)(libxl__qmp_handler *qmp,
- const libxl__json_object *tree);
+ const libxl__json_object *tree,
+ void *opaque);
typedef struct callback_id_pair {
int id;
qmp_callback_t callback;
+ void *opaque;
SIMPLEQ_ENTRY(callback_id_pair) next;
} callback_id_pair;
@@ -70,7 +72,8 @@ struct libxl__qmp_handler {
};
static int qmp_send(libxl__qmp_handler *qmp,
- const char *cmd, qmp_callback_t callback);
+ const char *cmd,
+ qmp_callback_t callback, void *opaque);
static const int QMP_SOCKET_CONNECT_TIMEOUT = 5;
@@ -100,7 +103,8 @@ static int store_serial_port_info(libxl__qmp_handler *qmp,
}
static int register_serials_chardev_callback(libxl__qmp_handler *qmp,
- const libxl__json_object *o)
+ const libxl__json_object *o,
+ void *unused)
{
const libxl__json_object *obj = NULL;
const libxl__json_object *label = NULL;
@@ -144,7 +148,7 @@ static int register_serials_chardev_callback(libxl__qmp_handler *qmp,
}
static int qmp_capabilities_callback(libxl__qmp_handler *qmp,
- const libxl__json_object *o)
+ const libxl__json_object *o, void *unused)
{
qmp->connected = true;
@@ -157,7 +161,7 @@ static int qmp_capabilities_callback(libxl__qmp_handler *qmp,
static int enable_qmp_capabilities(libxl__qmp_handler *qmp)
{
- return qmp_send(qmp, "qmp_capabilities", qmp_capabilities_callback);
+ return qmp_send(qmp, "qmp_capabilities", qmp_capabilities_callback, NULL);
}
/*
@@ -208,7 +212,7 @@ static void qmp_handle_error_response(libxl__qmp_handler *qmp,
resp = libxl__json_map_get("desc", resp, JSON_STRING);
if (pp) {
- pp->callback(qmp, NULL);
+ pp->callback(qmp, NULL, pp->opaque);
if (pp->id == qmp->wait_for_id) {
/* tell that the id have been processed */
qmp->wait_for_id = 0;
@@ -241,7 +245,8 @@ static int qmp_handle_response(libxl__qmp_handler *qmp,
if (pp) {
pp->callback(qmp,
- libxl__json_map_get("return", resp, JSON_ANY));
+ libxl__json_map_get("return", resp, JSON_ANY),
+ pp->opaque);
if (pp->id == qmp->wait_for_id) {
/* tell that the id have been processed */
qmp->wait_for_id = 0;
@@ -424,7 +429,8 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
}
static int qmp_send(libxl__qmp_handler *qmp,
- const char *cmd, qmp_callback_t callback)
+ const char *cmd,
+ qmp_callback_t callback, void *opaque)
{
yajl_gen_config conf = { 0, NULL };
const unsigned char *buf;
@@ -462,6 +468,7 @@ static int qmp_send(libxl__qmp_handler *qmp,
}
elm->id = qmp->last_id_used;
elm->callback = callback;
+ elm->opaque = opaque;
SIMPLEQ_INSERT_TAIL(&qmp->callback_list, elm, next);
}
@@ -484,13 +491,14 @@ error:
}
static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
- qmp_callback_t callback, int ask_timeout)
+ qmp_callback_t callback, void *opaque,
+ int ask_timeout)
{
int id = 0;
int ret = 0;
libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
- id = qmp_send(qmp, cmd, callback);
+ id = qmp_send(qmp, cmd, callback, opaque);
if (id <= 0) {
return -1;
}
@@ -580,7 +588,7 @@ int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
{
return qmp_synchronous_send(qmp, "query-chardev",
register_serials_chardev_callback,
- qmp->timeout);
+ NULL, qmp->timeout);
}
int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid)
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 06/13] libxl_qmp: Introduce list of arguments to qmp_send
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (4 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 05/13] libxl_qmp: Introduce an opaque argument to the callbacks Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 07/13] libxl_qmp: Always insert a command id in the callback_list Anthony PERARD
` (7 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_qmp.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index ddc0a4d..43c7d04 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -72,7 +72,7 @@ struct libxl__qmp_handler {
};
static int qmp_send(libxl__qmp_handler *qmp,
- const char *cmd,
+ const char *cmd, libxl_key_value_list *args,
qmp_callback_t callback, void *opaque);
static const int QMP_SOCKET_CONNECT_TIMEOUT = 5;
@@ -161,7 +161,8 @@ static int qmp_capabilities_callback(libxl__qmp_handler *qmp,
static int enable_qmp_capabilities(libxl__qmp_handler *qmp)
{
- return qmp_send(qmp, "qmp_capabilities", qmp_capabilities_callback, NULL);
+ return qmp_send(qmp, "qmp_capabilities", NULL,
+ qmp_capabilities_callback, NULL);
}
/*
@@ -429,7 +430,7 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
}
static int qmp_send(libxl__qmp_handler *qmp,
- const char *cmd,
+ const char *cmd, libxl_key_value_list *args,
qmp_callback_t callback, void *opaque)
{
yajl_gen_config conf = { 0, NULL };
@@ -448,6 +449,10 @@ static int qmp_send(libxl__qmp_handler *qmp,
libxl__yajl_gen_asciiz(hand, cmd);
libxl__yajl_gen_asciiz(hand, "id");
yajl_gen_integer(hand, ++qmp->last_id_used);
+ if (args) {
+ libxl__yajl_gen_asciiz(hand, "arguments");
+ libxl_key_value_list_gen_json(hand, args);
+ }
yajl_gen_map_close(hand);
s = yajl_gen_get_buf(hand, &buf, &len);
@@ -491,6 +496,7 @@ error:
}
static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
+ libxl_key_value_list *args,
qmp_callback_t callback, void *opaque,
int ask_timeout)
{
@@ -498,7 +504,7 @@ static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
int ret = 0;
libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
- id = qmp_send(qmp, cmd, callback, opaque);
+ id = qmp_send(qmp, cmd, args, callback, opaque);
if (id <= 0) {
return -1;
}
@@ -586,7 +592,7 @@ void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid)
int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
{
- return qmp_synchronous_send(qmp, "query-chardev",
+ return qmp_synchronous_send(qmp, "query-chardev", NULL,
register_serials_chardev_callback,
NULL, qmp->timeout);
}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 07/13] libxl_qmp: Always insert a command id in the callback_list.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (5 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 06/13] libxl_qmp: Introduce list of arguments to qmp_send Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 08/13] libxl_qmp: Introduce qmp_request_context Anthony PERARD
` (6 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Because the function qmp_synchronous_send rely on the presence of the id
in the callback_list.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_qmp.c | 34 ++++++++++++++++++----------------
1 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 43c7d04..47129c3 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -213,7 +213,9 @@ static void qmp_handle_error_response(libxl__qmp_handler *qmp,
resp = libxl__json_map_get("desc", resp, JSON_STRING);
if (pp) {
- pp->callback(qmp, NULL, pp->opaque);
+ if (pp->callback) {
+ pp->callback(qmp, NULL, pp->opaque);
+ }
if (pp->id == qmp->wait_for_id) {
/* tell that the id have been processed */
qmp->wait_for_id = 0;
@@ -245,9 +247,11 @@ static int qmp_handle_response(libxl__qmp_handler *qmp,
callback_id_pair *pp = qmp_get_callback_from_id(qmp, resp);
if (pp) {
- pp->callback(qmp,
- libxl__json_map_get("return", resp, JSON_ANY),
- pp->opaque);
+ if (pp->callback) {
+ pp->callback(qmp,
+ libxl__json_map_get("return", resp, JSON_ANY),
+ pp->opaque);
+ }
if (pp->id == qmp->wait_for_id) {
/* tell that the id have been processed */
qmp->wait_for_id = 0;
@@ -438,6 +442,7 @@ static int qmp_send(libxl__qmp_handler *qmp,
unsigned int len = 0;
yajl_gen_status s;
yajl_gen hand;
+ callback_id_pair *elm = NULL;
hand = yajl_gen_alloc(&conf, NULL);
if (!hand) {
@@ -463,19 +468,16 @@ static int qmp_send(libxl__qmp_handler *qmp,
return -1;
}
- if (callback) {
- callback_id_pair *elm = malloc(sizeof (callback_id_pair));
- if (elm == NULL) {
- LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
- "Failed to allocate a QMP callback");
- yajl_gen_free(hand);
- return -1;
- }
- elm->id = qmp->last_id_used;
- elm->callback = callback;
- elm->opaque = opaque;
- SIMPLEQ_INSERT_TAIL(&qmp->callback_list, elm, next);
+ elm = malloc(sizeof (callback_id_pair));
+ if (elm == NULL) {
+ LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
+ "Failed to allocate a QMP callback");
+ goto error;
}
+ elm->id = qmp->last_id_used;
+ elm->callback = callback;
+ elm->opaque = opaque;
+ SIMPLEQ_INSERT_TAIL(&qmp->callback_list, elm, next);
LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG, "next qmp command: '%s'", buf);
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 08/13] libxl_qmp: Introduce qmp_request_context.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (6 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 07/13] libxl_qmp: Always insert a command id in the callback_list Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 09/13] libxl_json: Handle number abrove LONG_MAX Anthony PERARD
` (5 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
This structure helps to track the return code of a callback. It's only used
between qmp_synchronous_send and qmp_send.
Now, qmp_synchronous_send will return the rc of the callback if there is no
error.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_qmp.c | 49 ++++++++++++++++++++++++++++++++--------------
1 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 47129c3..6d80538 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -46,10 +46,15 @@ typedef int (*qmp_callback_t)(libxl__qmp_handler *qmp,
const libxl__json_object *tree,
void *opaque);
+typedef struct qmp_request_context {
+ int rc;
+} qmp_request_context;
+
typedef struct callback_id_pair {
int id;
qmp_callback_t callback;
void *opaque;
+ qmp_request_context *context;
SIMPLEQ_ENTRY(callback_id_pair) next;
} callback_id_pair;
@@ -73,7 +78,8 @@ struct libxl__qmp_handler {
static int qmp_send(libxl__qmp_handler *qmp,
const char *cmd, libxl_key_value_list *args,
- qmp_callback_t callback, void *opaque);
+ qmp_callback_t callback, void *opaque,
+ qmp_request_context *context);
static const int QMP_SOCKET_CONNECT_TIMEOUT = 5;
@@ -162,7 +168,7 @@ static int qmp_capabilities_callback(libxl__qmp_handler *qmp,
static int enable_qmp_capabilities(libxl__qmp_handler *qmp)
{
return qmp_send(qmp, "qmp_capabilities", NULL,
- qmp_capabilities_callback, NULL);
+ qmp_capabilities_callback, NULL, NULL);
}
/*
@@ -214,7 +220,10 @@ static void qmp_handle_error_response(libxl__qmp_handler *qmp,
if (pp) {
if (pp->callback) {
- pp->callback(qmp, NULL, pp->opaque);
+ int rc = pp->callback(qmp, NULL, pp->opaque);
+ if (pp->context) {
+ pp->context->rc = rc;
+ }
}
if (pp->id == qmp->wait_for_id) {
/* tell that the id have been processed */
@@ -241,16 +250,18 @@ static int qmp_handle_response(libxl__qmp_handler *qmp,
switch (type) {
case LIBXL__QMP_MESSAGE_TYPE_QMP:
/* On the greeting message from the server, enable QMP capabilities */
- enable_qmp_capabilities(qmp);
- break;
+ return enable_qmp_capabilities(qmp);
case LIBXL__QMP_MESSAGE_TYPE_RETURN: {
callback_id_pair *pp = qmp_get_callback_from_id(qmp, resp);
if (pp) {
if (pp->callback) {
- pp->callback(qmp,
+ int rc = pp->callback(qmp,
libxl__json_map_get("return", resp, JSON_ANY),
pp->opaque);
+ if (pp->context) {
+ pp->context->rc = rc;
+ }
}
if (pp->id == qmp->wait_for_id) {
/* tell that the id have been processed */
@@ -259,13 +270,13 @@ static int qmp_handle_response(libxl__qmp_handler *qmp,
SIMPLEQ_REMOVE(&qmp->callback_list, pp, callback_id_pair, next);
free(pp);
}
- break;
+ return 0;
}
case LIBXL__QMP_MESSAGE_TYPE_ERROR:
qmp_handle_error_response(qmp, resp);
- break;
+ return -1;
case LIBXL__QMP_MESSAGE_TYPE_EVENT:
- break;
+ return 0;
case LIBXL__QMP_MESSAGE_TYPE_INVALID:
return -1;
}
@@ -358,6 +369,7 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
char *incomplete = NULL;
size_t incomplete_size = 0;
+ int rc = 0;
do {
fd_set rfds;
@@ -415,7 +427,7 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
o = libxl__json_parse(gc, s);
if (o) {
- qmp_handle_response(qmp, o);
+ rc = qmp_handle_response(qmp, o);
libxl__json_object_free(gc, o);
} else {
LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR,
@@ -430,12 +442,13 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
} while (s < s_end);
} while (s < s_end);
- return 1;
+ return rc;
}
static int qmp_send(libxl__qmp_handler *qmp,
const char *cmd, libxl_key_value_list *args,
- qmp_callback_t callback, void *opaque)
+ qmp_callback_t callback, void *opaque,
+ qmp_request_context *context)
{
yajl_gen_config conf = { 0, NULL };
const unsigned char *buf;
@@ -477,6 +490,7 @@ static int qmp_send(libxl__qmp_handler *qmp,
elm->id = qmp->last_id_used;
elm->callback = callback;
elm->opaque = opaque;
+ elm->context = context;
SIMPLEQ_INSERT_TAIL(&qmp->callback_list, elm, next);
LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG, "next qmp command: '%s'", buf);
@@ -505,8 +519,9 @@ static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
int id = 0;
int ret = 0;
libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
+ qmp_request_context context = { .rc = 0 };
- id = qmp_send(qmp, cmd, args, callback, opaque);
+ id = qmp_send(qmp, cmd, args, callback, opaque, &context);
if (id <= 0) {
return -1;
}
@@ -514,13 +529,17 @@ static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
while (qmp->wait_for_id == id) {
if ((ret = qmp_next(&gc, qmp)) < 0) {
- return ret;
+ break;
}
}
+ if (qmp->wait_for_id != id && ret == 0) {
+ ret = context.rc;
+ }
+
libxl__free_all(&gc);
- return 0;
+ return ret;
}
static void qmp_free_handler(libxl__qmp_handler *qmp)
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 09/13] libxl_json: Handle number abrove LONG_MAX.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (7 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 08/13] libxl_qmp: Introduce qmp_request_context Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 10/13] libxl_qmp: Introduce libxl__qmp_pci_add Anthony PERARD
` (4 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
The integers are now "long long" in the json_object.
If a number (decimal or integer) is too big (or too low), it is stored as it in
a string. So for that, we introduce a new type JSON_NUMBER.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_internal.h | 6 ++-
tools/libxl/libxl_json.c | 74 ++++++++++++++++++++++++++++++------------
2 files changed, 57 insertions(+), 23 deletions(-)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 942d45b..09e0c51 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -468,6 +468,8 @@ typedef enum {
JSON_FALSE,
JSON_INTEGER,
JSON_DOUBLE,
+ /* number is store in string, it's too big to be a long long or a double */
+ JSON_NUMBER,
JSON_STRING,
JSON_MAP,
JSON_ARRAY,
@@ -477,7 +479,7 @@ typedef enum {
typedef struct libxl__json_object {
libxl__json_node_type type;
union {
- long i;
+ long long i;
double d;
char *string;
/* List of libxl__json_object */
@@ -536,7 +538,7 @@ flexarray_t *libxl__json_object_get_array(const libxl__json_object *o)
else
return NULL;
}
-static inline long libxl__json_object_get_integer(const libxl__json_object *o)
+static inline long long libxl__json_object_get_integer(const libxl__json_object *o)
{
if (libxl__json_object_is_integer(o))
return o->u.i;
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index 389b697..fd5e2aa 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -14,6 +14,7 @@
#include <assert.h>
#include <string.h>
+#include <math.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_gen.h>
@@ -44,6 +45,7 @@ struct libxl__yajl_ctx {
# define DEBUG_GEN(ctx, type) yajl_gen_##type(ctx->g)
# define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value)
# define DEBUG_GEN_STRING(ctx, str, n) yajl_gen_string(ctx->g, str, n)
+# define DEBUG_GEN_NUMBER(ctx, str, n) yajl_gen_number(ctx->g, str, n)
# define DEBUG_GEN_REPORT(yajl_ctx) \
do { \
const unsigned char *buf = NULL; \
@@ -60,6 +62,7 @@ struct libxl__yajl_ctx {
# define DEBUG_GEN(ctx, type) ((void)0)
# define DEBUG_GEN_VALUE(ctx, type, value) ((void)0)
# define DEBUG_GEN_STRING(ctx, value, lenght) ((void)0)
+# define DEBUG_GEN_NUMBER(ctx, value, lenght) ((void)0)
# define DEBUG_GEN_REPORT(ctx) ((void)0)
#endif
@@ -363,6 +366,7 @@ void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj)
return;
switch (obj->type) {
case JSON_STRING:
+ case JSON_NUMBER:
free(obj->u.string);
break;
case JSON_MAP: {
@@ -504,36 +508,64 @@ static int json_callback_boolean(void *opaque, int boolean)
return 1;
}
-static int json_callback_integer(void *opaque, long value)
+static bool is_decimal(const char *s, unsigned len)
+{
+ const char *end = s + len;
+ for (; s < end; s++) {
+ if (*s == '.')
+ return true;
+ }
+ return false;
+}
+
+static int json_callback_number(void *opaque, const char *s, unsigned int len)
{
libxl__yajl_ctx *ctx = opaque;
- libxl__json_object *obj;
+ libxl__json_object *obj = NULL;
+ char *t = NULL;
- DEBUG_GEN_VALUE(ctx, integer, value);
+ DEBUG_GEN_NUMBER(ctx, s, len);
- if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
- return 0;
- obj->u.i = value;
+ if (is_decimal(s, len)) {
+ double d = strtod(s, NULL);
- if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
- libxl__json_object_free(ctx->gc, obj);
- return 0;
- }
+ if ((d == HUGE_VAL || d == HUGE_VAL) && errno == ERANGE) {
+ goto error;
+ }
- return 1;
-}
+ if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
+ return 0;
+ obj->u.d = d;
+ } else {
+ long long i = strtoll(s, NULL, 10);
-static int json_callback_double(void *opaque, double value)
-{
- libxl__yajl_ctx *ctx = opaque;
- libxl__json_object *obj;
+ if ((i == LLONG_MIN || i == LLONG_MAX) && errno == ERANGE) {
+ goto error;
+ }
- DEBUG_GEN_VALUE(ctx, double, value);
+ if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
+ return 0;
+ obj->u.i = i;
+ }
+ goto out;
- if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
+error:
+ /* If the conversion fail, we just store the original string. */
+ if ((obj = json_object_alloc(ctx->gc, JSON_NUMBER)) == NULL)
return 0;
- obj->u.d = value;
+ t = malloc(len + 1);
+ if (t == NULL) {
+ LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+ "Failed to allocate");
+ return 0;
+ }
+ strncpy(t, s, len);
+ t[len] = 0;
+
+ obj->u.string = t;
+
+out:
if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
libxl__json_object_free(ctx->gc, obj);
return 0;
@@ -706,9 +738,9 @@ static int json_callback_end_array(void *opaque)
static yajl_callbacks callbacks = {
json_callback_null,
json_callback_boolean,
- json_callback_integer,
- json_callback_double,
NULL,
+ NULL,
+ json_callback_number,
json_callback_string,
json_callback_start_map,
json_callback_map_key,
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 10/13] libxl_qmp: Introduce libxl__qmp_pci_add.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (8 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 09/13] libxl_json: Handle number abrove LONG_MAX Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-04 12:44 ` [Qemu-devel] [Xen-devel] [PATCH V3 10/13] libxl: " Ian Jackson
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 11/13] libxl: Use QMP to insert a passthrough device when using upstream QEMU Anthony PERARD
` (3 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
This function insert a PCI passthrough device in qemu.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_internal.h | 4 ++
tools/libxl/libxl_qmp.c | 95 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 09e0c51..718a417 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -119,6 +119,9 @@ typedef struct {
} libxl__device;
#define XC_PCI_BDF "0x%x, 0x%x, 0x%x, 0x%x"
+#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn) ((devfn) & 0x07)
#define AUTO_PHP_SLOT 0x100
#define SYSFS_PCI_DEV "/sys/bus/pci/devices"
#define SYSFS_PCIBACK_DRIVER "/sys/bus/pci/drivers/pciback"
@@ -446,6 +449,7 @@ _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl_ctx *ctx,
uint32_t domid);
/* ask to QEMU the serial port information and store it in xenstore. */
_hidden int libxl__qmp_query_serial(libxl__qmp_handler *qmp);
+_hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
/* close and free the QMP handler */
_hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
/* remove the socket file, if the file has already been removed,
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 6d80538..07ccf7a 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -41,6 +41,7 @@
*/
#define QMP_RECEIVE_BUFFER_SIZE 4096
+#define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x"
typedef int (*qmp_callback_t)(libxl__qmp_handler *qmp,
const libxl__json_object *tree,
@@ -618,6 +619,100 @@ int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
NULL, qmp->timeout);
}
+static int pci_add_callback(libxl__qmp_handler *qmp,
+ const libxl__json_object *response, void *opaque)
+{
+ libxl_device_pci *pcidev = opaque;
+ const libxl__json_object *bus = NULL;
+ libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
+ int i, j, rc = -1;
+ char *asked_id = libxl__sprintf(&gc, PCI_PT_QDEV_ID,
+ pcidev->bus, pcidev->dev, pcidev->func);
+
+ for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
+ const libxl__json_object *devices = NULL;
+ const libxl__json_object *device = NULL;
+ const libxl__json_object *o = NULL;
+ const char *id = NULL;
+
+ devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
+
+ for (j = 0; (device = libxl__json_array_get(devices, j)); j++) {
+ o = libxl__json_map_get("qdev_id", device, JSON_STRING);
+ id = libxl__json_object_get_string(o);
+
+ if (id && strcmp(asked_id, id) == 0) {
+ int dev_slot, dev_func;
+
+ o = libxl__json_map_get("slot", device, JSON_INTEGER);
+ if (!o)
+ goto out;
+ dev_slot = libxl__json_object_get_integer(o);
+ o = libxl__json_map_get("function", device, JSON_INTEGER);
+ if (!o)
+ goto out;
+ dev_func = libxl__json_object_get_integer(o);
+
+ pcidev->vdevfn = PCI_DEVFN(dev_slot, dev_func);
+
+ rc = 0;
+ goto out;
+ }
+ }
+ }
+
+
+out:
+ libxl__free_all(&gc);
+ return rc;
+}
+
+int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
+{
+ libxl__qmp_handler *qmp = NULL;
+ flexarray_t *parameters = NULL;
+ libxl_key_value_list args = NULL;
+ char *hostaddr = NULL;
+ int rc = 0;
+
+ qmp = libxl__qmp_initialize(libxl__gc_owner(gc), domid);
+ if (!qmp)
+ return -1;
+
+ hostaddr = libxl__sprintf(gc, "%04x:%02x:%02x.%01x", pcidev->domain,
+ pcidev->bus, pcidev->dev, pcidev->func);
+ if (!hostaddr)
+ return -1;
+
+ parameters = flexarray_make(6, 1);
+ flexarray_append_pair(parameters, "driver", "xen-pci-passthrough");
+ flexarray_append_pair(parameters, "id",
+ libxl__sprintf(gc, PCI_PT_QDEV_ID,
+ pcidev->bus, pcidev->dev,
+ pcidev->func));
+ flexarray_append_pair(parameters, "hostaddr", hostaddr);
+ if (pcidev->vdevfn) {
+ flexarray_append_pair(parameters, "addr",
+ libxl__sprintf(gc, "%x.%x",
+ PCI_SLOT(pcidev->vdevfn),
+ PCI_FUNC(pcidev->vdevfn)));
+ }
+ args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count);
+ if (!args)
+ return -1;
+
+ rc = qmp_synchronous_send(qmp, "device_add", &args,
+ NULL, NULL, qmp->timeout);
+ if (rc == 0) {
+ rc = qmp_synchronous_send(qmp, "query-pci", NULL,
+ pci_add_callback, pcidev, qmp->timeout);
+ }
+
+ flexarray_free(parameters);
+ libxl__qmp_close(qmp);
+ return rc;
+}
+
int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid)
{
libxl__qmp_handler *qmp = NULL;
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 11/13] libxl: Use QMP to insert a passthrough device when using upstream QEMU
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (9 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 10/13] libxl_qmp: Introduce libxl__qmp_pci_add Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-04 14:51 ` [Qemu-devel] [Xen-devel] " Ian Jackson
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 12/13] libxl_qmp: Introduce libxl__qmp_pci_del Anthony PERARD
` (2 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Also move the xenstore specif code to a new function and add a message if
sscanf fail.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_pci.c | 74 +++++++++++++++++++++++++++++++++--------------
1 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 33dd060..207ee33 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -599,11 +599,52 @@ static int pci_ins_check(libxl__gc *gc, uint32_t domid, const char *state, void
return 1;
}
-static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting)
+static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
+ libxl_device_pci *pcidev)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
+ int rc = 0;
char *path;
char *state, *vdevfn;
+
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
+ state = libxl__xs_read(gc, XBT_NULL, path);
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter",
+ domid);
+ if (pcidev->vdevfn) {
+ libxl__xs_write(gc, XBT_NULL, path, PCI_BDF_VDEVFN,
+ pcidev->domain, pcidev->bus, pcidev->dev,
+ pcidev->func, pcidev->vdevfn);
+ } else {
+ libxl__xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
+ pcidev->bus, pcidev->dev, pcidev->func);
+ }
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/command",
+ domid);
+ xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
+ rc = libxl__wait_for_device_model(gc, domid, NULL, NULL,
+ pci_ins_check, state);
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter",
+ domid);
+ vdevfn = libxl__xs_read(gc, XBT_NULL, path);
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state",
+ domid);
+ if ( rc < 0 )
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "qemu refused to add device: %s", vdevfn);
+ else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 ) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "wrong format for the vdevfn: '%s'", vdevfn);
+ rc = -1;
+ }
+ xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
+
+ return rc;
+}
+
+static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
int rc, hvm = 0;
switch (libxl__domain_type(gc, domid)) {
@@ -613,27 +654,16 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, i
NULL, NULL, NULL) < 0) {
return ERROR_FAIL;
}
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
- state = libxl__xs_read(gc, XBT_NULL, path);
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid);
- if (pcidev->vdevfn)
- libxl__xs_write(gc, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain,
- pcidev->bus, pcidev->dev, pcidev->func, pcidev->vdevfn);
- else
- libxl__xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
- pcidev->bus, pcidev->dev, pcidev->func);
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/command", domid);
- xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
- rc = libxl__wait_for_device_model(gc, domid, NULL, NULL,
- pci_ins_check, state);
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid);
- vdevfn = libxl__xs_read(gc, XBT_NULL, path);
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
- if ( rc < 0 )
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "qemu refused to add device: %s", vdevfn);
- else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 )
- rc = -1;
- xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
+ switch (libxl__device_model_version_running(gc, domid)) {
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+ rc = qemu_pci_add_xenstore(gc, domid, pcidev);
+ break;
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+ rc = libxl__qmp_pci_add(gc, domid, pcidev);
+ break;
+ default:
+ return ERROR_INVAL;
+ }
if ( rc )
return ERROR_FAIL;
break;
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 12/13] libxl_qmp: Introduce libxl__qmp_pci_del
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (10 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 11/13] libxl: Use QMP to insert a passthrough device when using upstream QEMU Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 13/13] libxl: Remove a passthrough device through QMP Anthony PERARD
2011-11-01 16:26 ` [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert " Anthony PERARD
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
To remove a pci passthough device from QEMU (upstream).
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_internal.h | 2 ++
tools/libxl/libxl_qmp.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 718a417..5123578 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -450,6 +450,8 @@ _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl_ctx *ctx,
/* ask to QEMU the serial port information and store it in xenstore. */
_hidden int libxl__qmp_query_serial(libxl__qmp_handler *qmp);
_hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
+_hidden int libxl__qmp_pci_del(libxl__gc *gc, int domid,
+ libxl_device_pci *pcidev);
/* close and free the QMP handler */
_hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
/* remove the socket file, if the file has already been removed,
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 07ccf7a..e7eb8cc 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -713,6 +713,41 @@ int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
return rc;
}
+static int qmp_device_del(libxl__gc *gc, int domid, char *id)
+{
+ libxl__qmp_handler *qmp = NULL;
+ flexarray_t *parameters = NULL;
+ libxl_key_value_list args = NULL;
+ int rc = 0;
+
+ qmp = libxl__qmp_initialize(libxl__gc_owner(gc), domid);
+ if (!qmp)
+ return -1;
+
+ parameters = flexarray_make(2, 1);
+ flexarray_append_pair(parameters, "id", id);
+ args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count);
+ if (!args)
+ return -1;
+
+ rc = qmp_synchronous_send(qmp, "device_del", &args,
+ NULL, NULL, qmp->timeout);
+
+ flexarray_free(parameters);
+ libxl__qmp_close(qmp);
+ return rc;
+}
+
+int libxl__qmp_pci_del(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
+{
+ char *id = NULL;
+
+ id = libxl__sprintf(gc, PCI_PT_QDEV_ID,
+ pcidev->bus, pcidev->dev, pcidev->func);
+
+ return qmp_device_del(gc, domid, id);
+}
+
int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid)
{
libxl__qmp_handler *qmp = NULL;
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V3 13/13] libxl: Remove a passthrough device through QMP.
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (11 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 12/13] libxl_qmp: Introduce libxl__qmp_pci_del Anthony PERARD
@ 2011-11-01 16:07 ` Anthony PERARD
2011-11-01 16:26 ` [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert " Anthony PERARD
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:07 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini; +Cc: Anthony PERARD, Xen Devel
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
tools/libxl/libxl_pci.c | 69 ++++++++++++++++++++++++++++++----------------
1 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 207ee33..1f93e67 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -861,13 +861,45 @@ out:
return rc;
}
+static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
+ libxl_device_pci *pcidev, int force)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *state;
+ char *path;
+
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
+ state = libxl__xs_read(gc, XBT_NULL, path);
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid);
+ libxl__xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
+ pcidev->bus, pcidev->dev, pcidev->func);
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/command", domid);
+
+ /* Remove all functions at once atomically by only signalling
+ * device-model for function 0 */
+ if ( !force && (pcidev->vdevfn & 0x7) == 0 ) {
+ xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem"));
+ if (libxl__wait_for_device_model(gc, domid, "pci-removed",
+ NULL, NULL, NULL) < 0) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Device Model didn't respond in time");
+ /* This depends on guest operating system acknowledging the
+ * SCI, if it doesn't respond in time then we may wish to
+ * force the removal.
+ */
+ return ERROR_FAIL;
+ }
+ }
+ path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
+ xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
+
+ return 0;
+}
+
static int do_pci_remove(libxl__gc *gc, uint32_t domid,
libxl_device_pci *pcidev, int force)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
libxl_device_pci *assigned;
- char *path;
- char *state;
int hvm = 0, rc, num;
int stubdomid = 0;
@@ -886,29 +918,18 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
NULL, NULL, NULL) < 0) {
return ERROR_FAIL;
}
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
- state = libxl__xs_read(gc, XBT_NULL, path);
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid);
- libxl__xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
- pcidev->bus, pcidev->dev, pcidev->func);
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/command", domid);
-
- /* Remove all functions at once atomically by only signalling
- * device-model for function 0 */
- if ( !force && (pcidev->vdevfn & 0x7) == 0 ) {
- xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem"));
- if (libxl__wait_for_device_model(gc, domid, "pci-removed",
- NULL, NULL, NULL) < 0) {
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Device Model didn't respond in time");
- /* This depends on guest operating system acknowledging the
- * SCI, if it doesn't respond in time then we may wish to
- * force the removal.
- */
- return ERROR_FAIL;
- }
+ switch (libxl__device_model_version_running(gc, domid)) {
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+ rc = qemu_pci_remove_xenstore(gc, domid, pcidev, force);
+ break;
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+ rc = libxl__qmp_pci_del(gc, domid, pcidev);
+ break;
+ default:
+ return ERROR_INVAL;
}
- path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
- xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
+ if (rc)
+ return ERROR_FAIL;
break;
case LIBXL_DOMAIN_TYPE_PV:
{
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP
2011-11-01 16:07 [Qemu-devel] [PATCH V3 00/13] libxl: QMP client improvement + pci passthrougth insert through QMP Anthony PERARD
` (12 preceding siblings ...)
2011-11-01 16:07 ` [Qemu-devel] [PATCH V3 13/13] libxl: Remove a passthrough device through QMP Anthony PERARD
@ 2011-11-01 16:26 ` Anthony PERARD
13 siblings, 0 replies; 17+ messages in thread
From: Anthony PERARD @ 2011-11-01 16:26 UTC (permalink / raw)
To: QEMU-devel, Stefano Stabellini
Oops, I have sent this series to too many ml :-(
On Tue, Nov 1, 2011 at 16:07, Anthony PERARD <anthony.perard@citrix.com> wrote:
> This patch series improves the QMP client in lib XenLight to be able to insert
> a PCI passthrough device with the upstream QEMU. This require to apply a patch
> series for QEMU (named Xen PCI Passthrough).
--
Anthony PERARD
^ permalink raw reply [flat|nested] 17+ messages in thread