* [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization
@ 2014-05-13 21:53 Wei Liu
2014-05-13 21:53 ` [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function Wei Liu
` (32 more replies)
0 siblings, 33 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
This series contains all patches necessary to fully preserve domain
configurations across save / restore.
It's divided to several parts (see patch list):
1. first few patches are bugfixes, doc updates and prerequisite changes
2. JSON infrastructure to manipulate domain configuration
3. new "libxl-json" format
4. update stored domain configuration as we update runtime domain configs
I've run test-amd64-amd64-xl and test-amd64-amd64-xl-qemuu-debianhvm-amd64
in OSSTest standalone mode, this series passed both testcases.
I've marked patch list with different legends for ease of review.
A -- Acked
C -- Changed since last round
M -- Minor update, no functional change
No marker -- New in this round
Wei.
Changes in V5:
* fix bugs in JSON generator and parser
* push vcpu affinity pinning to libxl
* don't generate default values in JSON output
* change JSON output to generate "keyvar.discriminator"
* synchronization now done in libxl
Changes in V4:
* minor bug fixes to parser
* push option parsing down to libxl level
* introduce deep copy functions
* handle domain configuration changes when setting memory targets
* handle domain configuration changes when plug / unplug device
Changes in V3:
* remove libxl__integer_parse_json and add functions for specific
integer types
* relax some checkings on invalid inputs
* libxl__json_parse_callback now takes gc instead of ctx
* rewrite "allow basic JSON type objects generation"
* ... and address some other misc things mentioned by IanC
Changes in V2:
* address IanC's comments on JSON parser
* add "xl-json" format patch
Wei Liu (32):
PART 1:
libxl: make cpupool_qualifier_to_cpupoolid a library function
M xl / libxl: push parsing of SSID and CPU pool ID down to libxl
xl / libxl: push VCPU affinity pinning down to libxl
libxl: libxl_uuid_copy now taks a ctx argument
xl: remove parsing of "vncviewer" option in xl domain config file
A libxl: fix memory leak in libxl_cpuid_dispose
libxl.h: document the paradigm of using libxl types
libxl.h: document libxl_<type>_to_json
C libxl_internal.h: move / add some libxl defbool #define here
libxl: fix JSON generator for uint64_t
PART 2:
A libxl IDL: rename json_fn to json_gen_fn
A libxl_json: introduce libxl__object_from_json
A libxl_internal: make JSON_* types a bit-field
A libxl_internal.h: introduce
libxl__json_object_is_{null,number,double}
libxl_internal.h: introduce libxl__json_object_get_number
A libxl_json: introduce parser functions for builtin types
A libxl_json: allow basic JSON type objects generation
libxl/gentypes.py: special-case KeyedUnion map handle generation
libxl/gentypes.py: don't generate default values
C libxl IDL: generate code to parse libxl__json_object to libxl_FOO
struct
A libxl/gentest.py: test JSON parser
M libxl: introduce libxl_key_value_list_length
M libxl: introduce libxl_cpuid_policy_list_length
C libxl: copy function for builtin types
C libxl IDL: generate deep copy functions
A libxl/gentest.py: test deep copy functions
PART 3:
libxl: libxl-json format and load/store configuration functions
libxl: store up-to-date domain configuration as we create domain
xl: use "libxl-json" format
PART 4:
M libxl: consider force removal of device successful
libxl: update domain configuration when updating memory targets
libxl: synchronize configuration when we plug / unplug device
docs/man/xl.cfg.pod.5 | 4 -
tools/libxl/gentest.py | 64 +++++-
tools/libxl/gentypes.py | 259 ++++++++++++++++++++-
tools/libxl/idl.py | 40 +++-
tools/libxl/idl.txt | 21 +-
tools/libxl/libxl.c | 364 +++++++++++++++++++++++++++---
tools/libxl/libxl.h | 99 +++++++-
tools/libxl/libxl_cpuid.c | 135 +++++++++--
tools/libxl/libxl_create.c | 112 ++++++++-
tools/libxl/libxl_device.c | 12 +-
tools/libxl/libxl_dm.c | 4 +
tools/libxl/libxl_dom.c | 48 ++++
tools/libxl/libxl_internal.h | 62 ++++-
tools/libxl/libxl_json.c | 411 +++++++++++++++++++++++++++++-----
tools/libxl/libxl_json.h | 37 ++-
tools/libxl/libxl_nocpuid.c | 13 ++
tools/libxl/libxl_types.idl | 72 +++---
tools/libxl/libxl_types_internal.idl | 4 +-
tools/libxl/libxl_utils.c | 58 ++++-
tools/libxl/libxl_utils.h | 7 +
tools/libxl/libxl_uuid.c | 4 +-
tools/libxl/libxl_uuid.h | 6 +-
tools/libxl/xl_cmdimpl.c | 374 +++++++++++++------------------
tools/libxl/xl_sxp.c | 7 +-
24 files changed, 1810 insertions(+), 407 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 127+ messages in thread
* [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-15 16:28 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl Wei Liu
` (31 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_utils.c | 31 ++++++++++++++++++++++++++++
tools/libxl/libxl_utils.h | 3 +++
tools/libxl/xl_cmdimpl.c | 49 +++++++++------------------------------------
3 files changed, 43 insertions(+), 40 deletions(-)
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 1f334f2..476921e 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -108,6 +108,37 @@ int libxl_domain_qualifier_to_domid(libxl_ctx *ctx, const char *name,
return rv;
}
+static int qualifier_to_id(const char *p, uint32_t *id_r)
+{
+ int i, alldigit;
+
+ alldigit = 1;
+ for (i = 0; p[i]; i++) {
+ if (!isdigit((uint8_t)p[i])) {
+ alldigit = 0;
+ break;
+ }
+ }
+
+ if (i > 0 && alldigit) {
+ *id_r = strtoul(p, NULL, 10);
+ return 0;
+ } else {
+ /* check here if it's a uuid and do proper conversion */
+ }
+ return 1;
+}
+
+int libxl_cpupool_qualifier_to_cpupoolid(libxl_ctx *ctx, const char *p,
+ uint32_t *poolid_r,
+ int *was_name_r)
+{
+ int was_name;
+
+ was_name = qualifier_to_id(p, poolid_r);
+ if (was_name_r) *was_name_r = was_name;
+ return was_name ? libxl_name_to_cpupoolid(ctx, p, poolid_r) : 0;
+}
char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid)
{
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index e37fb89..8bfb81b 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -23,6 +23,9 @@ unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned
int libxl_name_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid);
int libxl_domain_qualifier_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid);
char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid);
+int libxl_cpupool_qualifier_to_cpupoolid(libxl_ctx *ctx, const char *p,
+ uint32_t *poolid_r,
+ int *was_name_r);
int libxl_name_to_cpupoolid(libxl_ctx *ctx, const char *name, uint32_t *poolid);
char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid);
int libxl_cpupoolid_is_valid(libxl_ctx *ctx, uint32_t poolid);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 5195914..ac3188e 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -158,38 +158,6 @@ struct domain_create {
};
-
-static int qualifier_to_id(const char *p, uint32_t *id_r)
-{
- int i, alldigit;
-
- alldigit = 1;
- for (i = 0; p[i]; i++) {
- if (!isdigit((uint8_t)p[i])) {
- alldigit = 0;
- break;
- }
- }
-
- if (i > 0 && alldigit) {
- *id_r = strtoul(p, NULL, 10);
- return 0;
- } else {
- /* check here if it's a uuid and do proper conversion */
- }
- return 1;
-}
-
-static int cpupool_qualifier_to_cpupoolid(const char *p, uint32_t *poolid_r,
- int *was_name_r)
-{
- int was_name;
-
- was_name = qualifier_to_id(p, poolid_r);
- if (was_name_r) *was_name_r = was_name;
- return was_name ? libxl_name_to_cpupoolid(ctx, p, poolid_r) : 0;
-}
-
static uint32_t find_domain(const char *p) __attribute__((warn_unused_result));
static uint32_t find_domain(const char *p)
{
@@ -817,7 +785,7 @@ static void parse_config_data(const char *config_source,
if (!xlu_cfg_get_string (config, "pool", &buf, 0)) {
c_info->poolid = -1;
- cpupool_qualifier_to_cpupoolid(buf, &c_info->poolid, NULL);
+ libxl_cpupool_qualifier_to_cpupoolid(ctx, buf, &c_info->poolid, NULL);
}
if (!libxl_cpupoolid_is_valid(ctx, c_info->poolid)) {
fprintf(stderr, "Illegal pool specified\n");
@@ -5223,7 +5191,7 @@ static int sched_domain_output(libxl_scheduler sched, int (*output)(int),
int rc = 0;
if (cpupool) {
- if (cpupool_qualifier_to_cpupoolid(cpupool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool, &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
return -ERROR_FAIL;
@@ -5343,7 +5311,8 @@ int main_sched_credit(int argc, char **argv)
uint32_t poolid = 0;
if (cpupool) {
- if (cpupool_qualifier_to_cpupoolid(cpupool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool,
+ &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
return -ERROR_FAIL;
@@ -6852,7 +6821,7 @@ int main_cpupooldestroy(int argc, char **argv)
pool = argv[optind];
- if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, pool, &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
return -ERROR_FAIL;
@@ -6874,7 +6843,7 @@ int main_cpupoolrename(int argc, char **argv)
pool = argv[optind++];
- if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, pool, &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
return -ERROR_FAIL;
@@ -6912,7 +6881,7 @@ int main_cpupoolcpuadd(int argc, char **argv)
cpu = atoi(argv[optind]);
}
- if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, pool, &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
return -ERROR_FAIL;
@@ -6957,7 +6926,7 @@ int main_cpupoolcpuremove(int argc, char **argv)
cpu = atoi(argv[optind]);
}
- if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, pool, &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
return -ERROR_FAIL;
@@ -7001,7 +6970,7 @@ int main_cpupoolmigrate(int argc, char **argv)
return -ERROR_FAIL;
}
- if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
+ if (libxl_cpupool_qualifier_to_cpupoolid(ctx, pool, &poolid, NULL) ||
!libxl_cpupoolid_is_valid(ctx, poolid)) {
fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
return -ERROR_FAIL;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
2014-05-13 21:53 ` [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-15 16:38 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning " Wei Liu
` (30 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel
Cc: Wei Liu, ian.campbell, Dario Faggioli, ian.jackson,
Daniel De Graaf, Juergen Gross
This patch pushes parsing of "init_seclabel", "seclabel",
"device_model_stubdomain_seclabel" and "pool" down to libxl level.
Originally the parsing is done in xl level, which is not ideal because
libxl won't have the truely relevant information. With this patch libxl
holds important information by itself. This is useful when we do
serialization and deserialization of domain configurations on libxl
level.
The libxl IDL is extended to hold the string of labels and pool name.
And if there those strings are present they take precedence over the
numeric representations.
As all relevant structures have a field called X_name / X_label now, a
string is also copied there so that we can use it directly. In order to
be compatible with users of older versions of libxl, this patch also
defines LIBXL_HAVE_SSID_LABEL and LIBXL_HAVE_CPUPOOL_NAME. If they are
defined, the respective strings are available. And if those strings are
not NULL, libxl will do the parsing and ignore the numeric values.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Juergen Gross <juergen.gross@ts.fujitsu.com>
Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
tools/libxl/libxl.c | 19 ++++++--
tools/libxl/libxl.h | 24 ++++++++++
tools/libxl/libxl_create.c | 57 +++++++++++++++++++++++
tools/libxl/libxl_dm.c | 4 ++
tools/libxl/libxl_types.idl | 6 +++
tools/libxl/xl_cmdimpl.c | 107 ++++++++++++-------------------------------
tools/libxl/xl_sxp.c | 7 +--
7 files changed, 138 insertions(+), 86 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index d59ce0c..a89f5fa 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -520,12 +520,18 @@ int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid,
return 0;
}
-static void xcinfo2xlinfo(const xc_domaininfo_t *xcinfo,
+static void xcinfo2xlinfo(libxl_ctx *ctx,
+ const xc_domaininfo_t *xcinfo,
libxl_dominfo *xlinfo)
{
+ size_t size;
+
memcpy(&(xlinfo->uuid), xcinfo->handle, sizeof(xen_domain_handle_t));
xlinfo->domid = xcinfo->domain;
xlinfo->ssidref = xcinfo->ssidref;
+ if (libxl_flask_sid_to_context(ctx, xlinfo->ssidref,
+ &xlinfo->ssid_label, &size) < 0)
+ xlinfo->ssid_label = NULL;
xlinfo->dying = !!(xcinfo->flags&XEN_DOMINF_dying);
xlinfo->shutdown = !!(xcinfo->flags&XEN_DOMINF_shutdown);
@@ -572,7 +578,7 @@ libxl_dominfo * libxl_list_domain(libxl_ctx *ctx, int *nb_domain_out)
}
for (i = 0; i < ret; i++) {
- xcinfo2xlinfo(&info[i], &ptr[i]);
+ xcinfo2xlinfo(ctx, &info[i], &ptr[i]);
}
*nb_domain_out = ret;
return ptr;
@@ -591,7 +597,7 @@ int libxl_domain_info(libxl_ctx *ctx, libxl_dominfo *info_r,
if (ret==0 || xcinfo.domain != domid) return ERROR_INVAL;
if (info_r)
- xcinfo2xlinfo(&xcinfo, info_r);
+ xcinfo2xlinfo(ctx, &xcinfo, info_r);
return 0;
}
@@ -619,6 +625,11 @@ static int cpupool_info(libxl__gc *gc,
}
info->poolid = xcinfo->cpupool_id;
+ info->pool_name = libxl_cpupoolid_to_name(CTX, info->poolid);
+ if (!info->pool_name) {
+ rc = ERROR_NOMEM;
+ goto out;
+ }
info->sched = xcinfo->sched_id;
info->n_dom = xcinfo->n_dom;
rc = libxl_cpu_bitmap_alloc(CTX, &info->cpumap, 0);
@@ -4160,7 +4171,7 @@ retry_transaction:
abort_transaction = 1;
goto out;
}
- xcinfo2xlinfo(&info, &ptr);
+ xcinfo2xlinfo(ctx, &info, &ptr);
uuid = libxl__uuid2string(gc, ptr.uuid);
libxl__xs_write(gc, t, libxl__sprintf(gc, "/vm/%s/memory", uuid),
"%"PRIu32, new_target_memkb / 1024);
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 84f9c0e..2b06094 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -469,6 +469,30 @@
#define LIBXL_EXTERNAL_CALLERS_ONLY /* disappears for callers outside libxl */
#endif
+/*
+ * LIBXL_HAVE_SSID_LABEL
+ *
+ * If this is defined, then libxl IDL contains string of XSM security
+ * label in all XSM related structures.
+ *
+ * If this string is not NULL, libxl will overwrite the numeric
+ * representation of this configuration regardless if it has been
+ * set by the caller, because libxl will do the parsing by itself.
+ */
+#define LIBXL_HAVE_SSID_LABEL 1
+
+/*
+ * LIBXL_HAVE_CPUPOOL_NAME
+ *
+ * If this is defined, then libxl IDL contains string of CPU pool
+ * name in all CPU pool related structures.
+ *
+ * If this string is not NULL, libxl will overwrite the numeric
+ * representation of this configuration regardless if it has been
+ * set by the caller, because libxl will do the parsing by itself.
+ */
+#define LIBXL_HAVE_CPUPOOL_NAME 1
+
typedef uint8_t libxl_mac[6];
#define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
#define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index d015cf4..fe3bdd2 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -724,6 +724,63 @@ static void initiate_domain_create(libxl__egc *egc,
domid = 0;
+ if (d_config->c_info.ssid_label) {
+ char *s = d_config->c_info.ssid_label;
+ ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
+ &d_config->c_info.ssidref);
+ if (ret) {
+ if (errno == ENOSYS) {
+ LOG(WARN, "XSM Disabled: init_seclabel not supported");
+ ret = 0;
+ } else {
+ LOG(ERROR, "Invalid init_seclabel: %s", s);
+ goto error_out;
+ }
+ }
+ }
+
+ if (d_config->b_info.exec_ssid_label) {
+ char *s = d_config->b_info.exec_ssid_label;
+ ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
+ &d_config->b_info.exec_ssidref);
+ if (ret) {
+ if (errno == ENOSYS) {
+ LOG(WARN, "XSM Disabled: seclabel not supported");
+ ret = 0;
+ } else {
+ LOG(ERROR, "Invalid seclabel: %s", s);
+ goto error_out;
+ }
+ }
+ }
+
+ if (d_config->b_info.device_model_ssid_label) {
+ char *s = d_config->b_info.device_model_ssid_label;
+ ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
+ &d_config->b_info.device_model_ssidref);
+ if (ret) {
+ if (errno == ENOSYS) {
+ LOG(WARN,"XSM Disabled: device_model_stubdomain_seclabel not supported");
+ ret = 0;
+ } else {
+ LOG(ERROR, "Invalid device_model_stubdomain_seclabel: %s", s);
+ goto error_out;
+ }
+ }
+ }
+
+ if (d_config->c_info.pool_name) {
+ d_config->c_info.poolid = -1;
+ libxl_cpupool_qualifier_to_cpupoolid(ctx, d_config->c_info.pool_name,
+ &d_config->c_info.poolid,
+ NULL);
+ }
+ if (!libxl_cpupoolid_is_valid(ctx, d_config->c_info.poolid)) {
+ LOG(ERROR, "Illegal pool specified: %s", d_config->c_info.pool_name);
+ ret = ERROR_INVAL;
+ goto error_out;
+ }
+
/* If target_memkb is smaller than max_memkb, the subsequent call
* to libxc when building HVM domain will enable PoD mode.
*/
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 8abed7b..ea1ce38 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -909,7 +909,11 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
dm_config->c_info.type = LIBXL_DOMAIN_TYPE_PV;
dm_config->c_info.name = libxl__stub_dm_name(gc,
libxl__domid_to_name(gc, guest_domid));
+ /* When we are here to launch stubdom, ssidref is a valid value
+ * already, no need to parse it again.
+ */
dm_config->c_info.ssidref = guest_config->b_info.device_model_ssidref;
+ dm_config->c_info.ssid_label = NULL;
libxl_uuid_generate(&dm_config->c_info.uuid);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 8944686..0dfafe7 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -215,6 +215,7 @@ libxl_dominfo = Struct("dominfo",[
("uuid", libxl_uuid),
("domid", libxl_domid),
("ssidref", uint32),
+ ("ssid_label", string),
("running", bool),
("blocked", bool),
("paused", bool),
@@ -240,6 +241,7 @@ libxl_dominfo = Struct("dominfo",[
libxl_cpupoolinfo = Struct("cpupoolinfo", [
("poolid", uint32),
+ ("pool_name", string),
("sched", libxl_scheduler),
("n_dom", uint32),
("cpumap", libxl_bitmap)
@@ -270,11 +272,13 @@ libxl_domain_create_info = Struct("domain_create_info",[
("hap", libxl_defbool),
("oos", libxl_defbool),
("ssidref", uint32),
+ ("ssid_label", string),
("name", string),
("uuid", libxl_uuid),
("xsdata", libxl_key_value_list),
("platformdata", libxl_key_value_list),
("poolid", uint32),
+ ("pool_name", string),
("run_hotplug_scripts",libxl_defbool),
("pvh", libxl_defbool),
("driver_domain",libxl_defbool),
@@ -309,6 +313,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
("shadow_memkb", MemKB),
("rtc_timeoffset", uint32),
("exec_ssidref", uint32),
+ ("exec_ssid_label", string),
("localtime", libxl_defbool),
("disable_migrate", libxl_defbool),
("cpuid", libxl_cpuid_policy_list),
@@ -319,6 +324,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
# if you set device_model you must set device_model_version too
("device_model", string),
("device_model_ssidref", uint32),
+ ("device_model_ssid_label", string),
# extra parameters pass directly to qemu, NULL terminated
("extra", libxl_string_list),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index ac3188e..a1cb5b8 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -727,35 +727,17 @@ static void parse_config_data(const char *config_source,
exit(1);
}
- if (!xlu_cfg_get_string (config, "init_seclabel", &buf, 0)) {
- e = libxl_flask_context_to_sid(ctx, (char *)buf, strlen(buf),
- &c_info->ssidref);
- if (e) {
- if (errno == ENOSYS) {
- fprintf(stderr, "XSM Disabled: init_seclabel not supported\n");
- } else {
- fprintf(stderr, "Invalid init_seclabel: %s\n", buf);
- exit(1);
- }
- }
- }
+ if (!xlu_cfg_get_string (config, "init_seclabel", &buf, 0))
+ xlu_cfg_replace_string(config, "init_seclabel",
+ &c_info->ssid_label, 0);
if (!xlu_cfg_get_string (config, "seclabel", &buf, 0)) {
- uint32_t ssidref;
- e = libxl_flask_context_to_sid(ctx, (char *)buf, strlen(buf),
- &ssidref);
- if (e) {
- if (errno == ENOSYS) {
- fprintf(stderr, "XSM Disabled: seclabel not supported\n");
- } else {
- fprintf(stderr, "Invalid seclabel: %s\n", buf);
- exit(1);
- }
- } else if (c_info->ssidref) {
- b_info->exec_ssidref = ssidref;
- } else {
- c_info->ssidref = ssidref;
- }
+ if (c_info->ssid_label)
+ xlu_cfg_replace_string(config, "seclabel",
+ &b_info->exec_ssid_label, 0);
+ else
+ xlu_cfg_replace_string(config, "seclabel",
+ &c_info->ssid_label, 0);
}
libxl_defbool_set(&c_info->run_hotplug_scripts, run_hotplug_scripts);
@@ -783,14 +765,8 @@ static void parse_config_data(const char *config_source,
xlu_cfg_get_defbool(config, "oos", &c_info->oos, 0);
- if (!xlu_cfg_get_string (config, "pool", &buf, 0)) {
- c_info->poolid = -1;
- libxl_cpupool_qualifier_to_cpupoolid(ctx, buf, &c_info->poolid, NULL);
- }
- if (!libxl_cpupoolid_is_valid(ctx, c_info->poolid)) {
- fprintf(stderr, "Illegal pool specified\n");
- exit(1);
- }
+ if (!xlu_cfg_get_string (config, "pool", &buf, 0))
+ xlu_cfg_replace_string(config, "pool", &c_info->pool_name, 0);
libxl_domain_build_info_init_type(b_info, c_info->type);
if (blkdev_start)
@@ -1582,20 +1558,10 @@ skip_vfb:
&b_info->device_model_stubdomain, 0);
if (!xlu_cfg_get_string (config, "device_model_stubdomain_seclabel",
- &buf, 0)) {
- e = libxl_flask_context_to_sid(ctx, (char *)buf, strlen(buf),
- &b_info->device_model_ssidref);
- if (e) {
- if (errno == ENOSYS) {
- fprintf(stderr, "XSM Disabled:"
- " device_model_stubdomain_seclabel not supported\n");
- } else {
- fprintf(stderr, "Invalid device_model_stubdomain_seclabel:"
- " %s\n", buf);
- exit(1);
- }
- }
- }
+ &buf, 0))
+ xlu_cfg_replace_string(config, "device_model_stubdomain_seclabel",
+ &b_info->device_model_ssid_label, 0);
+
#define parse_extra_args(type) \
e = xlu_cfg_get_list_as_string_list(config, "device_model_args"#type, \
&b_info->extra##type, 0); \
@@ -3307,15 +3273,8 @@ static void list_domains(int verbose, int context, int claim, int numa,
}
if (claim)
printf(" %5lu", (unsigned long)info[i].outstanding_memkb / 1024);
- if (verbose || context) {
- int rc;
- size_t size;
- char *buf = NULL;
- rc = libxl_flask_sid_to_context(ctx, info[i].ssidref, &buf,
- &size);
- printf(" %16s", rc < 0 ? "-" : buf);
- free(buf);
- }
+ if (verbose || context)
+ printf(" %16s", info[i].ssid_label ? : "-");
if (numa) {
libxl_domain_get_nodeaffinity(ctx, info[i].domid, &nodemap);
@@ -6780,27 +6739,21 @@ int main_cpupoollist(int argc, char **argv)
for (p = 0; p < n_pools; p++) {
if (!ret && (!pool || (poolinfo[p].poolid == poolid))) {
- name = libxl_cpupoolid_to_name(ctx, poolinfo[p].poolid);
- if (!name) {
- fprintf(stderr, "error getting cpupool info\n");
- ret = -ERROR_NOMEM;
- } else {
- printf("%-19s", name);
- free(name);
- n = 0;
- libxl_for_each_bit(c, poolinfo[p].cpumap)
- if (libxl_bitmap_test(&poolinfo[p].cpumap, c)) {
- if (n && opt_cpus) printf(",");
- if (opt_cpus) printf("%d", c);
- n++;
- }
- if (!opt_cpus) {
- printf("%3d %9s y %4d", n,
- libxl_scheduler_to_string(poolinfo[p].sched),
- poolinfo[p].n_dom);
+ name = poolinfo[p].pool_name;
+ printf("%-19s", name);
+ n = 0;
+ libxl_for_each_bit(c, poolinfo[p].cpumap)
+ if (libxl_bitmap_test(&poolinfo[p].cpumap, c)) {
+ if (n && opt_cpus) printf(",");
+ if (opt_cpus) printf("%d", c);
+ n++;
}
- printf("\n");
+ if (!opt_cpus) {
+ printf("%3d %9s y %4d", n,
+ libxl_scheduler_to_string(poolinfo[p].sched),
+ poolinfo[p].n_dom);
}
+ printf("\n");
}
}
diff --git a/tools/libxl/xl_sxp.c b/tools/libxl/xl_sxp.c
index a16a025..48eb608 100644
--- a/tools/libxl/xl_sxp.c
+++ b/tools/libxl/xl_sxp.c
@@ -37,7 +37,6 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config)
libxl_domain_create_info *c_info = &d_config->c_info;
libxl_domain_build_info *b_info = &d_config->b_info;
- char *pool;
printf("(domain\n\t(domid %d)\n", domid);
printf("\t(create_info)\n");
@@ -55,10 +54,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config)
} else {
printf("\t(uuid <unknown>)\n");
}
- pool = libxl_cpupoolid_to_name(ctx, c_info->poolid);
- if (pool)
- printf("\t(cpupool %s)\n", pool);
- free(pool);
+ if (c_info->pool_name)
+ printf("\t(cpupool %s)\n", c_info->pool_name);
if (c_info->xsdata)
printf("\t(xsdata contains data)\n");
else
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
2014-05-13 21:53 ` [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function Wei Liu
2014-05-13 21:53 ` [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-15 0:59 ` Dario Faggioli
2014-05-15 16:45 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument Wei Liu
` (29 subsequent siblings)
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, Dario Faggioli, ian.jackson, ian.campbell
This patch introduces a key value list called "vcpu_affinity" in libxl
IDL to preserve VCPU to PCPU mapping. This is necessary for libxl to
preserve all information to construct a domain.
Also define LIBXL_HAVE_AFFINITY_KEY_VALUE_LIST in libxl.h to mark the
change in API.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
---
tools/libxl/libxl.h | 12 +++++++
tools/libxl/libxl_dom.c | 48 ++++++++++++++++++++++++++++
tools/libxl/libxl_types.idl | 1 +
tools/libxl/xl_cmdimpl.c | 74 ++++++++++++++++---------------------------
4 files changed, 89 insertions(+), 46 deletions(-)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 2b06094..a5a5155 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -302,6 +302,18 @@
#endif
/*
+ * LIBXL_HAVE_VCPU_AFFINITY_KEY_VALUE_LIST
+ *
+ * If this is defined, then libxl_domain_build_info structure will
+ * contain vcpu_affinity, a libxl_key_value_list type that contains
+ * the necessary information to pin a VCPU to a PCPU. Libxl will try
+ * to pin VCPUs to PCPUs according to this list.
+ *
+ * The key is the ID of VCPU and the value is the ID of PCPU.
+ */
+#define LIBXL_HAVE_VCPU_AFFINITY_KEY_VALUE_LIST 1
+
+/*
* LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
*
* If this is defined, then the libxl_domain_build_info structure will
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 661999c..b818815 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
+ /* If we have vcpu affinity list, pin vcpu to pcpu. */
+ if (d_config->b_info.vcpu_affinity) {
+ int i;
+ libxl_bitmap vcpu_cpumap;
+ int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
+
+ vcpu_to_pcpu = libxl__zalloc(gc, sz);
+ memset(vcpu_to_pcpu, -1, sz);
+
+ for (i = 0; i < d_config->b_info.max_vcpus; i++) {
+ libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
+ const char *key, *val;
+ int k, v;
+
+ key = kvl[i * 2];
+ if (!key)
+ break;
+ val = kvl[i * 2 + 1];
+
+ k = atoi(key);
+ v = atoi(val);
+ vcpu_to_pcpu[k] = v;
+ }
+
+ rc = libxl_cpu_bitmap_alloc(ctx, &vcpu_cpumap, 0);
+ if (rc) {
+ libxl_bitmap_dispose(&vcpu_cpumap);
+ return ERROR_FAIL;
+ }
+
+ for (i = 0; i < d_config->b_info.max_vcpus; i++) {
+ if (vcpu_to_pcpu[i] != -1) {
+ libxl_bitmap_set_none(&vcpu_cpumap);
+ libxl_bitmap_set(&vcpu_cpumap, vcpu_to_pcpu[i]);
+ } else {
+ libxl_bitmap_set_any(&vcpu_cpumap);
+ }
+ if (libxl_set_vcpuaffinity(ctx, domid, i, &vcpu_cpumap)) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "setting affinity failed on vcpu `%d'.", i);
+ libxl_bitmap_dispose(&vcpu_cpumap);
+ return ERROR_FAIL;
+ }
+ }
+
+ libxl_bitmap_dispose(&vcpu_cpumap);
+ }
+
if (xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb +
LIBXL_MAXMEM_CONSTANT) < 0) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't set max memory");
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 0dfafe7..7b0901c 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -305,6 +305,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
("avail_vcpus", libxl_bitmap),
("cpumap", libxl_bitmap),
("nodemap", libxl_bitmap),
+ ("vcpu_affinity", libxl_key_value_list),
("numa_placement", libxl_defbool),
("tsc_mode", libxl_tsc_mode),
("max_memkb", MemKB),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index a1cb5b8..3200d40 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -88,9 +88,6 @@ xlchild children[child_max];
static const char *common_domname;
static int fd_lock = -1;
-/* Stash for specific vcpu to pcpu mappping */
-static int *vcpu_to_pcpu;
-
static const char savefileheader_magic[32]=
"Xen saved domain, xl format\n \0 \r";
@@ -804,26 +801,19 @@ static void parse_config_data(const char *config_source,
if (!xlu_cfg_get_list (config, "cpus", &cpus, 0, 1)) {
int n_cpus = 0;
+ libxl_key_value_list kvl = NULL;
+ int len = 0;
if (libxl_cpu_bitmap_alloc(ctx, &b_info->cpumap, 0)) {
fprintf(stderr, "Unable to allocate cpumap\n");
exit(1);
}
- /* Prepare the array for single vcpu to pcpu mappings */
- vcpu_to_pcpu = xmalloc(sizeof(int) * b_info->max_vcpus);
- memset(vcpu_to_pcpu, -1, sizeof(int) * b_info->max_vcpus);
-
- /*
- * Idea here is to let libxl think all the domain's vcpus
- * have cpu affinity with all the pcpus on the list.
- * It is then us, here in xl, that matches each single vcpu
- * to its pcpu (and that's why we need to stash such info in
- * the vcpu_to_pcpu array now) after the domain has been created.
- * Doing it like this saves the burden of passing to libxl
- * some big array hosting the single mappings. Also, using
- * the cpumap derived from the list ensures memory is being
- * allocated on the proper nodes anyway.
+ /* Construct key value list for vcpu affinity. The key is vcpu
+ * id, value is pcpu id.
+ *
+ * For example, for a list of ['2', '3'], we generate
+ * kvl = [ '0':'2', '1':'3' ]
*/
libxl_bitmap_set_none(&b_info->cpumap);
while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) {
@@ -833,11 +823,30 @@ static void parse_config_data(const char *config_source,
exit(1);
}
libxl_bitmap_set(&b_info->cpumap, i);
- if (n_cpus < b_info->max_vcpus)
- vcpu_to_pcpu[n_cpus] = i;
+ if (n_cpus < b_info->max_vcpus) {
+ kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 2));
+ /* key */
+ if (asprintf(&kvl[len*2], "%d", n_cpus) == -1) {
+ LOG("failed to allocate memory for vcpu affinity list: key");
+ exit(1);
+ }
+ /* value */
+ kvl[len*2+1] = strdup(buf);
+ if (!kvl[len*2+1]) {
+ LOG("failed to allocate memory for vcpu affinity list: value");
+ exit(1);
+ }
+ len++;
+ }
n_cpus++;
}
+ /* One extra slot for sentinel */
+ kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 1));
+ kvl[len * 2] = NULL;
+
+ b_info->vcpu_affinity = kvl;
+
/* We have a cpumap, disable automatic placement */
libxl_defbool_set(&b_info->numa_placement, false);
}
@@ -2188,33 +2197,6 @@ start:
if ( ret )
goto error_out;
- /* If single vcpu to pcpu mapping was requested, honour it */
- if (vcpu_to_pcpu) {
- libxl_bitmap vcpu_cpumap;
-
- ret = libxl_cpu_bitmap_alloc(ctx, &vcpu_cpumap, 0);
- if (ret)
- goto error_out;
- for (i = 0; i < d_config.b_info.max_vcpus; i++) {
-
- if (vcpu_to_pcpu[i] != -1) {
- libxl_bitmap_set_none(&vcpu_cpumap);
- libxl_bitmap_set(&vcpu_cpumap, vcpu_to_pcpu[i]);
- } else {
- libxl_bitmap_set_any(&vcpu_cpumap);
- }
- if (libxl_set_vcpuaffinity(ctx, domid, i, &vcpu_cpumap)) {
- fprintf(stderr, "setting affinity failed on vcpu `%d'.\n", i);
- libxl_bitmap_dispose(&vcpu_cpumap);
- free(vcpu_to_pcpu);
- ret = ERROR_FAIL;
- goto error_out;
- }
- }
- libxl_bitmap_dispose(&vcpu_cpumap);
- free(vcpu_to_pcpu); vcpu_to_pcpu = NULL;
- }
-
ret = libxl_userdata_store(ctx, domid, "xl",
config_data, config_len);
if (ret) {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (2 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning " Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-15 16:51 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file Wei Liu
` (28 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Make it consistent with existing libxl functions like libxl_bitmap_copy
etc.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 2 +-
tools/libxl/libxl.h | 8 ++++++++
tools/libxl/libxl_create.c | 2 +-
tools/libxl/libxl_utils.c | 2 +-
tools/libxl/libxl_uuid.c | 4 ++--
tools/libxl/libxl_uuid.h | 7 ++++++-
6 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index a89f5fa..70830fe 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2010,7 +2010,7 @@ int libxl_devid_to_device_vtpm(libxl_ctx *ctx,
if(devid == vtpms[i].devid) {
vtpm->backend_domid = vtpms[i].backend_domid;
vtpm->devid = vtpms[i].devid;
- libxl_uuid_copy(&vtpm->uuid, &vtpms[i].uuid);
+ libxl_uuid_copy(ctx, &vtpm->uuid, &vtpms[i].uuid);
rc = 0;
break;
}
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index a5a5155..31877da 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -482,6 +482,14 @@
#endif
/*
+ * LIBXL_HAVE_UUID_COPY_CTX_PARAM
+ *
+ * If this is defined, libxl_uuid_copy has changed to take a libxl_ctx
+ * structure.
+ */
+#define LIBXL_HAVE_UUID_COPY_CTX_PARAM 1
+
+/*
* LIBXL_HAVE_SSID_LABEL
*
* If this is defined, then libxl IDL contains string of XSM security
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index fe3bdd2..da1517c 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -479,7 +479,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
*domid = -1;
/* Ultimately, handle is an array of 16 uint8_t, same as uuid */
- libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
+ libxl_uuid_copy(ctx, (libxl_uuid *)handle, &info->uuid);
ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
if (ret < 0) {
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 476921e..16b734e 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -536,7 +536,7 @@ int libxl_uuid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
if(!libxl_uuid_compare(uuid, &vtpms[i].uuid)) {
vtpm->backend_domid = vtpms[i].backend_domid;
vtpm->devid = vtpms[i].devid;
- libxl_uuid_copy(&vtpm->uuid, &vtpms[i].uuid);
+ libxl_uuid_copy(ctx, &vtpm->uuid, &vtpms[i].uuid);
rc = 0;
break;
}
diff --git a/tools/libxl/libxl_uuid.c b/tools/libxl/libxl_uuid.c
index ecc29c7..523fe3e 100644
--- a/tools/libxl/libxl_uuid.c
+++ b/tools/libxl/libxl_uuid.c
@@ -35,7 +35,7 @@ int libxl_uuid_from_string(libxl_uuid *uuid, const char *in)
return uuid_parse(in, uuid->uuid);
}
-void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src)
+void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src)
{
uuid_copy(dst->uuid, src->uuid);
}
@@ -82,7 +82,7 @@ int libxl_uuid_from_string(libxl_uuid *uuid, const char *in)
}
#undef LIBXL__UUID_PTRS
-void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src)
+void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src)
{
memcpy(dst->uuid, src->uuid, sizeof(dst->uuid));
}
diff --git a/tools/libxl/libxl_uuid.h b/tools/libxl/libxl_uuid.h
index 93c65a7..37c4d5f 100644
--- a/tools/libxl/libxl_uuid.h
+++ b/tools/libxl/libxl_uuid.h
@@ -53,10 +53,15 @@ typedef struct {
#endif
+typedef struct libxl__ctx libxl_ctx;
int libxl_uuid_is_nil(libxl_uuid *uuid);
void libxl_uuid_generate(libxl_uuid *uuid);
int libxl_uuid_from_string(libxl_uuid *uuid, const char *in);
-void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src);
+void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src);
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x040500
+void libxl_uuid_copy(dst, src) libxl_uuid_copy(NULL, dst, src)
+#endif
+
void libxl_uuid_clear(libxl_uuid *uuid);
int libxl_uuid_compare(libxl_uuid *uuid1, libxl_uuid *uuid2);
uint8_t *libxl_uuid_bytearray(libxl_uuid *uuid);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (3 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-20 12:44 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 06/32] libxl: fix memory leak in libxl_cpuid_dispose Wei Liu
` (27 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Print out a warning and suggest user use "-V" option when invoking "xl
create". Also remove that option in manpage.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
docs/man/xl.cfg.pod.5 | 4 ----
tools/libxl/xl_cmdimpl.c | 21 ++++++++-------------
2 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 0ca37bc..8591821 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -1116,10 +1116,6 @@ The default is cirrus.
Allow access to the display via the VNC protocol. This enables the
other VNC-related settings. The default is to enable this.
-=item B<vncviewer=BOOLEAN>
-
-Automatically spawn a vncviewer when creating/restoring a guest.
-
=item B<vnclisten="ADDRESS[:DISPLAYNUM]">
Specifies the IP address, and optionally VNC display number, to use.
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 3200d40..a6dd437 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -693,9 +693,7 @@ static void parse_top_level_sdl_options(XLU_Config *config,
static void parse_config_data(const char *config_source,
const char *config_data,
int config_len,
- libxl_domain_config *d_config,
- struct domain_create *dom_info)
-
+ libxl_domain_config *d_config)
{
const char *buf;
long l;
@@ -941,12 +939,9 @@ static void parse_config_data(const char *config_source,
if (!xlu_cfg_get_long(config, "rtc_timeoffset", &l, 0))
b_info->rtc_timeoffset = l;
- if (dom_info && !xlu_cfg_get_long(config, "vncviewer", &l, 0)) {
- /* Command line arguments must take precedence over what's
- * specified in the configuration file. */
- if (!dom_info->vnc)
- dom_info->vnc = l;
- }
+ if (!xlu_cfg_get_long(config, "vncviewer", &l, 0))
+ fprintf(stderr, "WARNING: ignoring \"vncviewer\" option. "
+ "Use \"-V\" option of \"xl create\" to automatically spawn vncviewer.\n");
xlu_cfg_get_defbool(config, "localtime", &b_info->localtime, 0);
@@ -2129,7 +2124,7 @@ static uint32_t create_domain(struct domain_create *dom_info)
if (!dom_info->quiet)
printf("Parsing config from %s\n", config_source);
- parse_config_data(config_source, config_data, config_len, &d_config, dom_info);
+ parse_config_data(config_source, config_data, config_len, &d_config);
if (migrate_fd >= 0) {
if (d_config.c_info.name) {
@@ -2304,7 +2299,7 @@ start:
libxl_domain_config_dispose(&d_config);
libxl_domain_config_init(&d_config);
parse_config_data(config_source, config_data, config_len,
- &d_config, dom_info);
+ &d_config);
/*
* XXX FIXME: If this sleep is not there then domain
@@ -3115,7 +3110,7 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
continue;
CHK_SYSCALL(asprintf(&config_source, "<domid %d data>", info[i].domid));
libxl_domain_config_init(&d_config);
- parse_config_data(config_source, (char *)data, len, &d_config, NULL);
+ parse_config_data(config_source, (char *)data, len, &d_config);
if (default_output_format == OUTPUT_FORMAT_JSON)
s = printf_info_one_json(hand, info[i].domid, &d_config);
else
@@ -4416,7 +4411,7 @@ int main_config_update(int argc, char **argv)
libxl_domain_config_init(&d_config);
- parse_config_data(filename, config_data, config_len, &d_config, NULL);
+ parse_config_data(filename, config_data, config_len, &d_config);
if (debug || dryrun_only)
printf_info(default_output_format, -1, &d_config);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 06/32] libxl: fix memory leak in libxl_cpuid_dispose
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (4 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types Wei Liu
` (26 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
libxl_cpuid_policy_list is not allocated with GC-aware allocation so it
needs to be freed manually, just like what libxl_string_list_dispose and
libxl_key_value_list_dispose do.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_cpuid.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index d1ea50d..3787213 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -26,6 +26,7 @@ void libxl_cpuid_dispose(libxl_cpuid_policy_list *p_cpuid_list)
if (cpuid_list[i].policy[j] != NULL)
free(cpuid_list[i].policy[j]);
}
+ free(cpuid_list);
return;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (5 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 06/32] libxl: fix memory leak in libxl_cpuid_dispose Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-20 12:49 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json Wei Liu
` (25 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 31877da..303bd71 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -240,6 +240,16 @@
* libxl_types.idl). The library provides a common set of methods for
* initialising and freeing these types.
*
+ * IDL-generated libxl types should be used as follows: the user must
+ * always call the "init" function before using a type, even if the
+ * variable is simply being passed by reference as an out parameter
+ * to a libxl function. The user must always calls "dispose" exactly
+ * once afterwards, to clean up, regardless of whether operations on
+ * this object succeeded or failed. See the xl code for examples.
+ *
+ * "init" is idempotent. We intend that "dispose" will become
+ * idempotent, but this is not currently the case.
+ *
* void libxl_<type>_init(<type> *p):
*
* Initialises the members of "p" to all defaults. These may either
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (6 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-20 12:50 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here Wei Liu
` (24 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 303bd71..5b0de1c 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -286,6 +286,11 @@
* Frees any dynamically allocated memory used by the members of
* "p" but not the storage used by "p" itself (this allows for the
* allocation of arrays of types and for the composition of types).
+ *
+ * char *libxl_<type>_to_json(instance *p)
+ *
+ * Generates a JSON object from "p" in the form of a NULL terminated
+ * string.
*/
#ifndef LIBXL_H
#define LIBXL_H
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (7 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-20 12:51 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 10/32] libxl: fix JSON generator for uint64_t Wei Liu
` (23 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
They will be used by both JSON generator and parser so they should be in
header file.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 10 +++-------
tools/libxl/libxl_internal.h | 8 ++++++++
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 70830fe..0589d4e 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -232,10 +232,6 @@ void libxl_key_value_list_dispose(libxl_key_value_list *pkvl)
free(kvl);
}
-#define LIBXL__DEFBOOL_DEFAULT (0)
-#define LIBXL__DEFBOOL_FALSE (-1)
-#define LIBXL__DEFBOOL_TRUE (1)
-
void libxl_defbool_set(libxl_defbool *db, bool b)
{
db->val = b ? LIBXL__DEFBOOL_TRUE : LIBXL__DEFBOOL_FALSE;
@@ -266,11 +262,11 @@ bool libxl_defbool_val(libxl_defbool db)
const char *libxl_defbool_to_string(libxl_defbool b)
{
if (b.val < 0)
- return "False";
+ return LIBXL__DEFBOOL_STR_FALSE;
else if (b.val > 0)
- return "True";
+ return LIBXL__DEFBOOL_STR_TRUE;
else
- return "<default>";
+ return LIBXL__DEFBOOL_STR_DEFAULT;
}
/******************************************************************************/
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index c2b73c4..294c595 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3036,6 +3036,14 @@ void libxl__numa_candidate_put_nodemap(libxl__gc *gc,
libxl_bitmap_copy(CTX, &cndt->nodemap, nodemap);
}
+/* Som handy macros for defbool type. */
+#define LIBXL__DEFBOOL_DEFAULT (0)
+#define LIBXL__DEFBOOL_FALSE (-1)
+#define LIBXL__DEFBOOL_TRUE (1)
+#define LIBXL__DEFBOOL_STR_DEFAULT "<default>"
+#define LIBXL__DEFBOOL_STR_FALSE "False"
+#define LIBXL__DEFBOOL_STR_TRUE "True"
+
/*
* Inserts "elm_new" into the sorted list "head".
*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 10/32] libxl: fix JSON generator for uint64_t
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (8 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-20 12:55 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 11/32] libxl IDL: rename json_fn to json_gen_fn Wei Liu
` (22 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
yajl_gen_integer cannot cope with uint64_t. A new function called
libxl__uint64_gen_json is introduced to handle uint64_t.
Also removed a duplicated definition of MemKB while I was there.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/idl.py | 2 +-
tools/libxl/libxl_json.c | 21 +++++++++++++++++++++
tools/libxl/libxl_json.h | 1 +
tools/libxl/libxl_types.idl | 4 +---
4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index e4dc79b..69e08e1 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -266,7 +266,7 @@ integer = Number("int", namespace = None, signed = True)
uint8 = UInt(8)
uint16 = UInt(16)
uint32 = UInt(32)
-uint64 = UInt(64)
+uint64 = UInt(64, json_fn = "libxl__uint64_gen_json")
string = Builtin("char *", namespace = None, dispose_fn = "free",
json_fn = "libxl__string_gen_json",
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index 3ea56a4..ff23376 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -794,6 +794,27 @@ out:
return ret;
}
+yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val)
+{
+ char *num;
+ unsigned int len;
+ yajl_gen_status s;
+
+ if (asprintf(&num, "%"PRIu64, val) == -1) {
+ s = yajl_gen_in_error_state;
+ goto out;
+ }
+
+ len = strlen(num);
+
+ s = yajl_gen_number(hand, num, len);
+
+ free(num);
+
+out:
+ return s;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_json.h b/tools/libxl/libxl_json.h
index a4dd8fc..a45d429 100644
--- a/tools/libxl/libxl_json.h
+++ b/tools/libxl/libxl_json.h
@@ -22,6 +22,7 @@
# include <yajl/yajl_version.h>
#endif
+yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val);
yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p);
yajl_gen_status libxl_domid_gen_json(yajl_gen hand, libxl_domid *p);
yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *p);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 7b0901c..30a4f7a 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -22,7 +22,7 @@ libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE)
# Specific integer types
#
-MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT")
+MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT", json_fn = "libxl__uint64_gen_json")
#
# Constants / Enumerations
@@ -288,8 +288,6 @@ libxl_domain_restore_params = Struct("domain_restore_params", [
("checkpointed_stream", integer),
])
-MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT")
-
libxl_domain_sched_params = Struct("domain_sched_params",[
("sched", libxl_scheduler),
("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 11/32] libxl IDL: rename json_fn to json_gen_fn
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (9 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 10/32] libxl: fix JSON generator for uint64_t Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 12/32] libxl_json: introduce libxl__object_from_json Wei Liu
` (21 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
This json_fn is in fact used to generate string representation of a json
data structure. We will introduce another json function to parse json
data structure in later changeset, so rename json_fn to json_gen_fn to
clarify.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/gentest.py | 4 ++--
tools/libxl/gentypes.py | 12 ++++++------
tools/libxl/idl.py | 12 ++++++------
tools/libxl/idl.txt | 4 ++--
tools/libxl/libxl_types.idl | 6 +++---
tools/libxl/libxl_types_internal.idl | 2 +-
6 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py
index 722b7f4..eb9a21b 100644
--- a/tools/libxl/gentest.py
+++ b/tools/libxl/gentest.py
@@ -52,7 +52,7 @@ def gen_rand_init(ty, v, indent = " ", parent = None):
s += " break;\n"
s += "}\n"
elif isinstance(ty, idl.Struct) \
- and (parent is None or ty.json_fn is None):
+ and (parent is None or ty.json_gen_fn is None):
for f in [f for f in ty.fields if not f.const]:
(nparent,fexpr) = ty.member(v, f, parent is None)
s += gen_rand_init(f.type, fexpr, "", nparent)
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
f.write(" printf(\"Testing TYPE_to_json()\\n\");\n")
f.write(" printf(\"----------------------\\n\");\n")
f.write(" printf(\"\\n\");\n")
- for ty in [t for t in types if t.json_fn is not None]:
+ for ty in [t for t in types if t.json_gen_fn is not None]:
arg = ty.typename + "_val"
f.write(" %s_rand_init(%s);\n" % (ty.typename, \
ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 917e2c2..61a2b3d 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -229,7 +229,7 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
s += " goto out;\n"
s += " break;\n"
s += "}\n"
- elif isinstance(ty, idl.Struct) and (parent is None or ty.json_fn is None):
+ elif isinstance(ty, idl.Struct) and (parent is None or ty.json_gen_fn is None):
s += "s = yajl_gen_map_open(hand);\n"
s += "if (s != yajl_gen_status_ok)\n"
s += " goto out;\n"
@@ -243,8 +243,8 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
s += "if (s != yajl_gen_status_ok)\n"
s += " goto out;\n"
else:
- if ty.json_fn is not None:
- s += "s = %s(hand, %s);\n" % (ty.json_fn, ty.pass_arg(v, parent is None))
+ if ty.json_gen_fn is not None:
+ s += "s = %s(hand, %s);\n" % (ty.json_gen_fn, ty.pass_arg(v, parent is None))
s += "if (s != yajl_gen_status_ok)\n"
s += " goto out;\n"
@@ -341,7 +341,7 @@ if __name__ == '__main__':
f.write("%svoid %s(%s, %s);\n" % (ty.hidden(), ty.init_fn + "_" + ku.keyvar.name,
ty.make_arg("p"),
ku.keyvar.type.make_arg(ku.keyvar.name)))
- if ty.json_fn is not None:
+ if ty.json_gen_fn is not None:
f.write("%schar *%s_to_json(libxl_ctx *ctx, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p")))
if isinstance(ty, idl.Enumeration):
f.write("%sconst char *%s_to_string(%s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p")))
@@ -369,7 +369,7 @@ if __name__ == '__main__':
""" % (header_json_define, header_json_define, " ".join(sys.argv)))
- for ty in [ty for ty in types if ty.json_fn is not None]:
+ for ty in [ty for ty in types if ty.json_gen_fn is not None]:
f.write("%syajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
f.write("\n")
@@ -426,7 +426,7 @@ if __name__ == '__main__':
f.write("}\n")
f.write("\n")
- for ty in [t for t in types if t.json_fn is not None]:
+ for ty in [t for t in types if t.json_gen_fn is not None]:
f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
f.write("{\n")
f.write(libxl_C_type_gen_json(ty, "p"))
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index 69e08e1..8b118dd 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -65,9 +65,9 @@ class Type(object):
self.autogenerate_init_fn = kwargs.setdefault('autogenerate_init_fn', False)
if self.typename is not None and not self.private:
- self.json_fn = kwargs.setdefault('json_fn', self.typename + "_gen_json")
+ self.json_gen_fn = kwargs.setdefault('json_gen_fn', self.typename + "_gen_json")
else:
- self.json_fn = kwargs.setdefault('json_fn', None)
+ self.json_gen_fn = kwargs.setdefault('json_gen_fn', None)
self.autogenerate_json = kwargs.setdefault('autogenerate_json', True)
@@ -118,7 +118,7 @@ class Number(Builtin):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
kwargs.setdefault('signed', False)
- kwargs.setdefault('json_fn', "yajl_gen_integer")
+ kwargs.setdefault('json_gen_fn', "yajl_gen_integer")
self.signed = kwargs['signed']
Builtin.__init__(self, ctype, **kwargs)
@@ -256,7 +256,7 @@ class KeyedUnion(Aggregate):
void = Builtin("void *", namespace = None)
bool = Builtin("bool", namespace = None,
- json_fn = "yajl_gen_bool",
+ json_gen_fn = "yajl_gen_bool",
autogenerate_json = False)
size_t = Number("size_t", namespace = None)
@@ -266,10 +266,10 @@ integer = Number("int", namespace = None, signed = True)
uint8 = UInt(8)
uint16 = UInt(16)
uint32 = UInt(32)
-uint64 = UInt(64, json_fn = "libxl__uint64_gen_json")
+uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json")
string = Builtin("char *", namespace = None, dispose_fn = "free",
- json_fn = "libxl__string_gen_json",
+ json_gen_fn = "libxl__string_gen_json",
autogenerate_json = False)
class Array(Type):
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index 439aede..6a53dd8 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -60,14 +60,14 @@ Type.autogenerate_init_fn: (default: True if dir in [IN, BOTH])
Indicates if the above named Type.init_fn should be
autogenerated.
-Type.json_fn: (default: typename + "_gen_json" or None if type == None)
+Type.json_gen_fn: (default: typename + "_gen_json" or None if type == None)
The name of the C function which will generate a YAJL data structure
representing this type.
Type.autogenerate_json: (default: True)
- Indicates if the above named Type.json_fn should be autogenerated.
+ Indicates if the above named Type.json_gen_fn should be autogenerated.
Other simple type-Classes
-------------------------
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 30a4f7a..2162c37 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -7,8 +7,8 @@ namespace("libxl_")
libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE)
-libxl_domid = Builtin("domid", json_fn = "yajl_gen_integer", autogenerate_json = False)
-libxl_devid = Builtin("devid", json_fn = "yajl_gen_integer", autogenerate_json = False, signed = True, init_val="-1")
+libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False)
+libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False, signed = True, init_val="-1")
libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE)
libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE)
libxl_bitmap = Builtin("bitmap", dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE)
@@ -22,7 +22,7 @@ libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE)
# Specific integer types
#
-MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT", json_fn = "libxl__uint64_gen_json")
+MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT", json_gen_fn = "libxl__uint64_gen_json")
#
# Constants / Enumerations
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index cb9444f..a964851 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -1,7 +1,7 @@
namespace("libxl__")
hidden(True)
-libxl_domid = Builtin("domid", namespace="libxl_", json_fn = "yajl_gen_integer")
+libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer")
libxl__qmp_message_type = Enumeration("qmp_message_type", [
(1, "QMP"),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 12/32] libxl_json: introduce libxl__object_from_json
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (10 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 11/32] libxl IDL: rename json_fn to json_gen_fn Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 13/32] libxl_internal: make JSON_* types a bit-field Wei Liu
` (20 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Given a JSON string, we need to convert it to libxl_FOO struct.
The approach is:
JSON string -> libxl__json_object -> libxl_FOO struct
With this approach we can make use of libxl's infrastructure to do the
first half (JSON string -> libxl__json_object).
Second half is done by auto-generated code by libxl's IDL
infrastructure. IDL patch(es) will come later.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_internal.h | 8 ++++++++
tools/libxl/libxl_json.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 294c595..b2111a0 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1640,6 +1640,14 @@ typedef struct libxl__json_object {
struct libxl__json_object *parent;
} libxl__json_object;
+typedef int (*libxl__json_parse_callback)(libxl__gc *gc,
+ libxl__json_object *o,
+ void *p);
+_hidden int libxl__object_from_json(libxl_ctx *ctx, const char *type,
+ libxl__json_parse_callback parse,
+ void *p,
+ const char *s);
+
typedef struct {
char *map_key;
libxl__json_object *obj;
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index ff23376..d2b4cfc 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -815,6 +815,36 @@ out:
return s;
}
+int libxl__object_from_json(libxl_ctx *ctx, const char *type,
+ libxl__json_parse_callback parse,
+ void *p, const char *s)
+{
+ GC_INIT(ctx);
+ libxl__json_object *o;
+ int rc;
+
+ o = libxl__json_parse(gc, s);
+ if (!o) {
+ LOG(ERROR,
+ "unable to generate libxl__json_object from JSON representation of %s.",
+ type);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = parse(gc, o, p);
+ if (rc) {
+ LOG(ERROR, "unable to convert libxl__json_object to %s. (rc=%d)", type, rc);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = 0;
+out:
+ GC_FREE;
+ return rc;
+}
+
/*
* Local variables:
* mode: C
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 13/32] libxl_internal: make JSON_* types a bit-field
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (11 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 12/32] libxl_json: introduce libxl__object_from_json Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 14/32] libxl_internal.h: introduce libxl__json_object_is_{null, number, double} Wei Liu
` (19 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Libxl can generate number as type JSON_INTEGER, JSON_DOUBLE or
JSON_NUMBER, string as type JSON_STRING or JSON_NULL (if string is
null).
So make JSON_* type a bit-field and use it in libxl__json_map_get. This is
useful when parsing a libxl__json_object to libxl_FOO struct. We can
enforce type checking on libxl__json_object in an easy way.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_internal.h | 18 +++++++++---------
tools/libxl/libxl_json.c | 2 +-
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index b2111a0..98bb2a5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1613,16 +1613,16 @@ _hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str);
_hidden yajl_gen_status libxl__yajl_gen_enum(yajl_gen hand, const char *str);
typedef enum {
- JSON_NULL,
- JSON_BOOL,
- JSON_INTEGER,
- JSON_DOUBLE,
+ JSON_NULL = (1 << 0),
+ JSON_BOOL = (1 << 1),
+ JSON_INTEGER = (1 << 2),
+ JSON_DOUBLE = (1 << 3),
/* 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,
- JSON_ANY
+ JSON_NUMBER = (1 << 4),
+ JSON_STRING = (1 << 5),
+ JSON_MAP = (1 << 6),
+ JSON_ARRAY = (1 << 7),
+ JSON_ANY = 255 /* this is a mask of all values above, adjust as needed */
} libxl__json_node_type;
typedef struct libxl__json_object {
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index d2b4cfc..178db45 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -363,7 +363,7 @@ const libxl__json_object *libxl__json_map_get(const char *key,
return NULL;
if (strcmp(key, node->map_key) == 0) {
if (expected_type == JSON_ANY
- || (node->obj && node->obj->type == expected_type)) {
+ || (node->obj && (node->obj->type & expected_type))) {
return node->obj;
} else {
return NULL;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 14/32] libxl_internal.h: introduce libxl__json_object_is_{null, number, double}
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (12 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 13/32] libxl_internal: make JSON_* types a bit-field Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number Wei Liu
` (18 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
... which return true if json object is valid and of type
JSON_{NULL,NUMBER,DOUBLE}.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_internal.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 98bb2a5..b2966d9 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1655,6 +1655,10 @@ typedef struct {
typedef struct libxl__yajl_ctx libxl__yajl_ctx;
+static inline bool libxl__json_object_is_null(const libxl__json_object *o)
+{
+ return o != NULL && o->type == JSON_NULL;
+}
static inline bool libxl__json_object_is_bool(const libxl__json_object *o)
{
return o != NULL && o->type == JSON_BOOL;
@@ -1667,6 +1671,14 @@ static inline bool libxl__json_object_is_integer(const libxl__json_object *o)
{
return o != NULL && o->type == JSON_INTEGER;
}
+static inline bool libxl__json_object_is_double(const libxl__json_object *o)
+{
+ return o != NULL && o->type == JSON_DOUBLE;
+}
+static inline bool libxl__json_object_is_number(const libxl__json_object *o)
+{
+ return o != NULL && o->type == JSON_NUMBER;
+}
static inline bool libxl__json_object_is_map(const libxl__json_object *o)
{
return o != NULL && o->type == JSON_MAP;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (13 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 14/32] libxl_internal.h: introduce libxl__json_object_is_{null, number, double} Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-20 12:56 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 16/32] libxl_json: introduce parser functions for builtin types Wei Liu
` (17 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_internal.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index b2966d9..97d6b24 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1704,6 +1704,14 @@ const char *libxl__json_object_get_string(const libxl__json_object *o)
return NULL;
}
static inline
+const char *libxl__json_object_get_number(const libxl__json_object *o)
+{
+ if (libxl__json_object_is_number(o))
+ return o->u.string;
+ else
+ return NULL;
+}
+static inline
flexarray_t *libxl__json_object_get_map(const libxl__json_object *o)
{
if (libxl__json_object_is_map(o))
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 16/32] libxl_json: introduce parser functions for builtin types
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (14 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 17/32] libxl_json: allow basic JSON type objects generation Wei Liu
` (16 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
This changeset introduces following functions:
* libxl_defbool_parse_json
* libxl__bool_parse_json
* libxl_uuid_parse_json
* libxl_mac_parse_json
* libxl_bitmap_parse_json
* libxl_cpuid_policy_list_parse_json
* libxl_string_list_parse_json
* libxl_key_value_list_parse_json
* libxl_hwcap_parse_json
* libxl__int_parse_json
* libxl__uint{8,16,32,64}_parse_json
* libxl__string_parse_json
They will be used in later patch to convert the libxl__json_object
tree of a builtin type to libxl_FOO struct.
Also remove declaration of libxl_domid_gen_json as libxl_domid uses
yajl_gen_integer to generate JSON object.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Anthony Perard <anthony.perard@citrix.com>
---
tools/libxl/libxl_cpuid.c | 89 +++++++++++---
tools/libxl/libxl_json.c | 271 +++++++++++++++++++++++++++++++++++++++++++
tools/libxl/libxl_json.h | 36 +++++-
tools/libxl/libxl_nocpuid.c | 7 ++
4 files changed, 386 insertions(+), 17 deletions(-)
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index 3787213..d9007b2 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -338,29 +338,29 @@ void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid,
(const char**)(cpuid[i].policy), cpuid_res);
}
+static const char *input_names[2] = { "leaf", "subleaf" };
+static const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
+/*
+ * Aiming for:
+ * [
+ * { 'leaf': 'val-eax',
+ * 'subleaf': 'val-ecx',
+ * 'eax': 'filter',
+ * 'ebx': 'filter',
+ * 'ecx': 'filter',
+ * 'edx': 'filter' },
+ * { 'leaf': 'val-eax', ..., 'eax': 'filter', ... },
+ * ... etc ...
+ * ]
+ */
+
yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
libxl_cpuid_policy_list *pcpuid)
{
libxl_cpuid_policy_list cpuid = *pcpuid;
yajl_gen_status s;
- const char *input_names[2] = { "leaf", "subleaf" };
- const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
int i, j;
- /*
- * Aiming for:
- * [
- * { 'leaf': 'val-eax',
- * 'subleaf': 'val-ecx',
- * 'eax': 'filter',
- * 'ebx': 'filter',
- * 'ecx': 'filter',
- * 'edx': 'filter' },
- * { 'leaf': 'val-eax', ..., 'eax': 'filter', ... },
- * ... etc ...
- * ]
- */
-
s = yajl_gen_array_open(hand);
if (s != yajl_gen_status_ok) goto out;
@@ -398,6 +398,63 @@ out:
return s;
}
+int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_cpuid_policy_list *p)
+{
+ int i, size;
+ libxl_cpuid_policy_list l;
+ flexarray_t *array;
+
+ if (!libxl__json_object_is_array(o))
+ return ERROR_FAIL;
+
+ array = libxl__json_object_get_array(o);
+ if (!array->count)
+ return 0;
+
+ size = array->count;
+ /* need one extra slot as sentinel */
+ l = *p = libxl__calloc(NOGC, size + 1, sizeof(libxl_cpuid_policy));
+
+ l[size].input[0] = XEN_CPUID_INPUT_UNUSED;
+ l[size].input[1] = XEN_CPUID_INPUT_UNUSED;
+
+ for (i = 0; i < size; i++) {
+ const libxl__json_object *t;
+ int j;
+
+ if (flexarray_get(array, i, (void**)&t) != 0)
+ return ERROR_FAIL;
+
+ if (!libxl__json_object_is_map(t))
+ return ERROR_FAIL;
+
+ for (j = 0; j < ARRAY_SIZE(l[0].input); j++) {
+ const libxl__json_object *r;
+
+ r = libxl__json_map_get(input_names[j], t, JSON_INTEGER);
+ if (!r)
+ l[i].input[j] = XEN_CPUID_INPUT_UNUSED;
+ else
+ l[i].input[j] = libxl__json_object_get_integer(r);
+ }
+
+ for (j = 0; j < ARRAY_SIZE(l[0].policy); j++) {
+ const libxl__json_object *r;
+
+ r = libxl__json_map_get(policy_names[j], t, JSON_STRING);
+ if (!r)
+ l[i].policy[j] = NULL;
+ else
+ l[i].policy[j] =
+ libxl__strdup(NOGC, libxl__json_object_get_string(r));
+ }
+ }
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index 178db45..bbc1618 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -100,6 +100,42 @@ yajl_gen_status libxl_defbool_gen_json(yajl_gen hand,
return libxl__yajl_gen_asciiz(hand, libxl_defbool_to_string(*db));
}
+int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_defbool *p)
+{
+ const char *s;
+
+ if (!libxl__json_object_is_string(o))
+ return ERROR_FAIL;
+
+ s = libxl__json_object_get_string(o);
+
+ if (!strncmp(s, LIBXL__DEFBOOL_STR_DEFAULT,
+ strlen(LIBXL__DEFBOOL_STR_DEFAULT)))
+ p->val = LIBXL__DEFBOOL_DEFAULT;
+ else if (!strncmp(s, LIBXL__DEFBOOL_STR_TRUE,
+ strlen(LIBXL__DEFBOOL_STR_TRUE)))
+ p->val = LIBXL__DEFBOOL_TRUE;
+ else if (!strncmp(s, LIBXL__DEFBOOL_STR_FALSE,
+ strlen(LIBXL__DEFBOOL_STR_FALSE)))
+ p->val = LIBXL__DEFBOOL_FALSE;
+ else
+ return ERROR_FAIL;
+
+ return 0;
+}
+
+int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ bool *p)
+{
+ if (!libxl__json_object_is_bool(o))
+ return ERROR_FAIL;
+
+ *p = libxl__json_object_get_bool(o);
+
+ return 0;
+}
+
yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
libxl_uuid *uuid)
{
@@ -108,6 +144,15 @@ yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_UUID_FMTLEN);
}
+int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_uuid *p)
+{
+ if (!libxl__json_object_is_string(o))
+ return ERROR_FAIL;
+
+ return libxl_uuid_from_string(p, o->u.string);
+}
+
yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand,
libxl_bitmap *bitmap)
{
@@ -128,6 +173,40 @@ out:
return s;
}
+int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_bitmap *p)
+{
+ int i;
+ int size;
+ const libxl__json_object *t;
+ flexarray_t *array;
+
+ if (!libxl__json_object_is_array(o))
+ return ERROR_FAIL;
+
+ array = libxl__json_object_get_array(o);
+ if (!array->count) {
+ libxl_bitmap_init(p);
+ return 0;
+ }
+
+ t = libxl__json_array_get(o, array->count - 1);
+ if (!libxl__json_object_is_integer(t))
+ return ERROR_FAIL;
+ size = libxl__json_object_get_integer(t) + 1;
+
+ libxl_bitmap_alloc(CTX, p, size);
+
+ for (i = 0; (t = libxl__json_array_get(o, i)); i++) {
+ if (!libxl__json_object_is_integer(t))
+ return ERROR_FAIL;
+
+ libxl_bitmap_set(p, libxl__json_object_get_integer(t));
+ }
+
+ return 0;
+}
+
yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand,
libxl_key_value_list *pkvl)
{
@@ -155,6 +234,41 @@ out:
return s;
}
+int libxl_key_value_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_key_value_list *p)
+{
+ libxl__json_map_node *node = NULL;
+ flexarray_t *maps = NULL;
+ int i, size;
+ libxl_key_value_list kvl;
+
+ if (!libxl__json_object_is_map(o))
+ return ERROR_FAIL;
+
+ maps = libxl__json_object_get_map(o);
+ size = maps->count * 2;
+ kvl = *p = libxl__calloc(NOGC, size, sizeof(char *));
+
+ for (i = 0; i < maps->count; i++) {
+ int idx = i * 2;
+ if (flexarray_get(maps, i, (void**)&node) != 0)
+ return ERROR_FAIL;
+
+ if (!libxl__json_object_is_string(node->obj) &&
+ !libxl__json_object_is_null(node->obj))
+ return ERROR_FAIL;
+
+ kvl[idx] = libxl__strdup(NOGC, node->map_key);
+ if (libxl__json_object_is_string(node->obj))
+ kvl[idx+1] =
+ libxl__strdup(NOGC, libxl__json_object_get_string(node->obj));
+ else
+ kvl[idx+1] = NULL;
+ }
+
+ return 0;
+}
+
yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list *pl)
{
libxl_string_list l = *pl;
@@ -176,6 +290,38 @@ out:
return s;
}
+int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_string_list *p)
+{
+ const libxl__json_object *t;
+ libxl_string_list l;
+ flexarray_t *array = NULL;
+ int i, size;
+
+ if (!libxl__json_object_is_array(o))
+ return ERROR_FAIL;
+
+ array = libxl__json_object_get_array(o);
+ size = array->count;
+
+ if (size == 0) {
+ *p = NULL;
+ return 0;
+ }
+
+ /* need one extra slot as sentinel */
+ l = *p = libxl__calloc(NOGC, size + 1, sizeof(char *));
+
+ for (i = 0; (t = libxl__json_array_get(o, i)); i++) {
+ if (!libxl__json_object_is_string(t))
+ return ERROR_FAIL;
+
+ l[i] = libxl__strdup(NOGC, libxl__json_object_get_string(t));
+ }
+
+ return 0;
+}
+
yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac)
{
char buf[LIBXL_MAC_FMTLEN+1];
@@ -183,6 +329,15 @@ yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac)
return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_MAC_FMTLEN);
}
+int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_mac *p)
+{
+ if (!libxl__json_object_is_string(o))
+ return ERROR_FAIL;
+
+ return libxl__parse_mac(libxl__json_object_get_string(o), *p);
+}
+
yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand,
libxl_hwcap *p)
{
@@ -201,6 +356,27 @@ out:
return s;
}
+int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_hwcap *p)
+{
+ int i;
+
+ if (!libxl__json_object_is_array(o))
+ return ERROR_FAIL;
+
+ for (i = 0; i<4; i++) {
+ const libxl__json_object *t;
+
+ t = libxl__json_array_get(o, i);
+ if (!t || !libxl__json_object_is_integer(t))
+ return ERROR_FAIL;
+
+ (*p)[i] = libxl__json_object_get_integer(t);
+ }
+
+ return 0;
+}
+
yajl_gen_status libxl__string_gen_json(yajl_gen hand,
const char *p)
{
@@ -210,6 +386,20 @@ yajl_gen_status libxl__string_gen_json(yajl_gen hand,
return yajl_gen_null(hand);
}
+int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ char **p)
+{
+ if (!libxl__json_object_is_string(o) && !libxl__json_object_is_null(o))
+ return ERROR_FAIL;
+
+ if (libxl__json_object_is_null(o))
+ *p = NULL;
+ else
+ *p = libxl__strdup(NOGC, libxl__json_object_get_string(o));
+
+ return 0;
+}
+
/*
* libxl__json_object helper functions
*/
@@ -845,6 +1035,87 @@ out:
return rc;
}
+int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p)
+{
+ long long i;
+
+ if (!libxl__json_object_is_integer(o))
+ return ERROR_FAIL;
+
+ i = libxl__json_object_get_integer(o);
+
+ if (i > INT_MAX || i < INT_MIN)
+ return ERROR_FAIL;
+
+ *((int *)p) = i;
+
+ return 0;
+}
+
+/* Macro to generate:
+ * libxl__uint8_parse_json
+ * libxl__uint16_parse_json
+ * libxl__uint32_parse_json
+ */
+#define PARSE_UINT(width) \
+ int libxl__uint ## width ## _parse_json(libxl__gc *gc, \
+ const libxl__json_object *o,\
+ void *p) \
+ { \
+ long long i; \
+ \
+ if (!libxl__json_object_is_integer(o)) \
+ return ERROR_FAIL; \
+ \
+ i = libxl__json_object_get_integer(o); \
+ \
+ if (i < 0 || i > UINT ## width ## _MAX) \
+ return ERROR_FAIL; \
+ \
+ *((uint ## width ## _t *)p) = i; \
+ \
+ return 0; \
+ }
+
+PARSE_UINT(8);
+PARSE_UINT(16);
+PARSE_UINT(32);
+
+int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p)
+{
+ if (!libxl__json_object_is_integer(o) &&
+ !libxl__json_object_is_number(o))
+ return ERROR_FAIL;
+
+ if (libxl__json_object_is_integer(o)) {
+ long long i = libxl__json_object_get_integer(o);
+
+ if (i < 0)
+ return ERROR_FAIL;
+
+ *((uint64_t *)p) = i;
+ } else {
+ const char *s;
+ unsigned long long i;
+ int saved_errno = errno;
+
+ s = libxl__json_object_get_number(o);
+
+ errno = 0;
+ i = strtoull(s, NULL, 10);
+
+ if (i == ULLONG_MAX && errno == ERANGE)
+ return ERROR_FAIL;
+
+ errno = saved_errno;
+ *((uint64_t *)p) = i;
+ }
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_json.h b/tools/libxl/libxl_json.h
index a45d429..b196c1c 100644
--- a/tools/libxl/libxl_json.h
+++ b/tools/libxl/libxl_json.h
@@ -22,18 +22,52 @@
# include <yajl/yajl_version.h>
#endif
+typedef struct libxl__gc libxl__gc;
+typedef struct libxl__json_object libxl__json_object;
+
yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val);
yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p);
-yajl_gen_status libxl_domid_gen_json(yajl_gen hand, libxl_domid *p);
+int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_defbool *p);
+int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ bool *p);
yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *p);
+int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_uuid *p);
yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *p);
+int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_mac *p);
yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand, libxl_bitmap *p);
+int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_bitmap *p);
yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
libxl_cpuid_policy_list *p);
+int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_cpuid_policy_list *p);
yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list *p);
+int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_string_list *p);
yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand,
libxl_key_value_list *p);
+int libxl_key_value_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_key_value_list *p);
yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, libxl_hwcap *p);
+int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_hwcap *p);
+int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p);
+int libxl__uint8_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p);
+int libxl__uint16_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p);
+int libxl__uint32_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p);
+int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ void *p);
+int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ char **p);
#include <_libxl_types_json.h>
diff --git a/tools/libxl/libxl_nocpuid.c b/tools/libxl/libxl_nocpuid.c
index 5f7cb6a..eb525fc 100644
--- a/tools/libxl/libxl_nocpuid.c
+++ b/tools/libxl/libxl_nocpuid.c
@@ -44,6 +44,13 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
return 0;
}
+int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_cpuid_policy_list *p)
+{
+ return 0;
+}
+
/*
* Local variables:
* mode: C
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 17/32] libxl_json: allow basic JSON type objects generation
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (15 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 16/32] libxl_json: introduce parser functions for builtin types Wei Liu
@ 2014-05-13 21:53 ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation Wei Liu
` (15 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:53 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
The original logic is that basic JSON types (number, string and null)
must be an element of JSON map or array. This assumption doesn't hold
true anymore when we need to return basic JSON types.
Returning basic JSON types is required for parsing number, string and
null objects back into libxl__json_object.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl_internal.h | 2 +-
tools/libxl/libxl_json.c | 87 ++++++++++++++++++------------------------
2 files changed, 38 insertions(+), 51 deletions(-)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 97d6b24..89bbf7d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1743,7 +1743,7 @@ _hidden libxl__json_object *libxl__json_object_alloc(libxl__gc *gc_opt,
libxl__json_node_type type);
_hidden int libxl__json_object_append_to(libxl__gc *gc_opt,
libxl__json_object *obj,
- libxl__json_object *dst);
+ libxl__yajl_ctx *ctx);
_hidden libxl__json_object *libxl__json_array_get(const libxl__json_object *o,
int i);
_hidden
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index bbc1618..8a27d95 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -424,36 +424,43 @@ libxl__json_object *libxl__json_object_alloc(libxl__gc *gc,
return obj;
}
-int libxl__json_object_append_to(libxl__gc *gc,
- libxl__json_object *obj,
- libxl__json_object *dst)
+int libxl__json_object_append_to(libxl__gc *gc, libxl__json_object *obj,
+ libxl__yajl_ctx *ctx)
{
- assert(dst != NULL);
+ libxl__json_object *dst = ctx->current;
- switch (dst->type) {
- case JSON_MAP: {
- libxl__json_map_node *last;
+ if (dst) {
+ switch (dst->type) {
+ case JSON_MAP: {
+ libxl__json_map_node *last;
- if (dst->u.map->count == 0) {
+ if (dst->u.map->count == 0) {
+ LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+ "Try to add a value to an empty map (with no key)");
+ return ERROR_FAIL;
+ }
+ flexarray_get(dst->u.map, dst->u.map->count - 1, (void**)&last);
+ last->obj = obj;
+ break;
+ }
+ case JSON_ARRAY:
+ flexarray_append(dst->u.array, obj);
+ break;
+ default:
LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
- "Try to add a value to an empty map (with no key)");
- return -1;
+ "Try append an object is not a map/array (%i)\n",
+ dst->type);
+ return ERROR_FAIL;
}
- flexarray_get(dst->u.map, dst->u.map->count - 1, (void**)&last);
- last->obj = obj;
- break;
- }
- case JSON_ARRAY:
- flexarray_append(dst->u.array, obj);
- break;
- default:
- LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
- "Try append an object is not a map/array (%i)\n",
- dst->type);
- return -1;
}
obj->parent = dst;
+
+ if (libxl__json_object_is_map(obj) || libxl__json_object_is_array(obj))
+ ctx->current = obj;
+ if (ctx->head == NULL)
+ ctx->head = obj;
+
return 0;
}
@@ -639,9 +646,8 @@ static int json_callback_null(void *opaque)
obj = libxl__json_object_alloc(ctx->gc, JSON_NULL);
- if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+ if (libxl__json_object_append_to(ctx->gc, obj, ctx))
return 0;
- }
return 1;
}
@@ -656,9 +662,8 @@ static int json_callback_boolean(void *opaque, int boolean)
obj = libxl__json_object_alloc(ctx->gc, JSON_BOOL);
obj->u.b = boolean;
- if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+ if (libxl__json_object_append_to(ctx->gc, obj, ctx))
return 0;
- }
return 1;
}
@@ -713,9 +718,8 @@ error:
obj->u.string = t;
out:
- if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+ if (libxl__json_object_append_to(ctx->gc, obj, ctx))
return 0;
- }
return 1;
}
@@ -737,9 +741,8 @@ static int json_callback_string(void *opaque, const unsigned char *str,
obj = libxl__json_object_alloc(ctx->gc, JSON_STRING);
obj->u.string = t;
- if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+ if (libxl__json_object_append_to(ctx->gc, obj, ctx))
return 0;
- }
return 1;
}
@@ -785,16 +788,8 @@ static int json_callback_start_map(void *opaque)
obj = libxl__json_object_alloc(ctx->gc, JSON_MAP);
- if (ctx->current) {
- if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
- return 0;
- }
- }
-
- ctx->current = obj;
- if (ctx->head == NULL) {
- ctx->head = obj;
- }
+ if (libxl__json_object_append_to(ctx->gc, obj, ctx))
+ return 0;
return 1;
}
@@ -825,16 +820,8 @@ static int json_callback_start_array(void *opaque)
obj = libxl__json_object_alloc(ctx->gc, JSON_ARRAY);
- if (ctx->current) {
- if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
- return 0;
- }
- }
-
- ctx->current = obj;
- if (ctx->head == NULL) {
- ctx->head = obj;
- }
+ if (libxl__json_object_append_to(ctx->gc, obj, ctx))
+ return 0;
return 1;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (16 preceding siblings ...)
2014-05-13 21:53 ` [PATCH V5 17/32] libxl_json: allow basic JSON type objects generation Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:26 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 19/32] libxl/gentypes.py: don't generate default values Wei Liu
` (14 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Generate JSON map handle according to KeyedUnion discriminator.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/gentypes.py | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 61a2b3d..01416e7 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -186,6 +186,26 @@ def libxl_C_type_member_init(ty, field):
s += "\n"
return s
+def libxl_C_type_gen_map_key(f, parent, indent = ""):
+ s = ""
+ if isinstance(f.type, idl.KeyedUnion):
+ s += "switch (%s) {\n" % (parent + f.type.keyvar.name)
+ for x in f.type.fields:
+ v = f.type.keyvar.name + "." + x.name
+ s += "case %s:\n" % x.enumname
+ s += " s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (v, v)
+ s += " if (s != yajl_gen_status_ok)\n"
+ s += " goto out;\n"
+ s += " break;\n"
+ s += "}\n"
+ else:
+ s += "s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (f.name, f.name)
+ s += "if (s != yajl_gen_status_ok)\n"
+ s += " goto out;\n"
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
s = ""
if parent is None:
@@ -235,9 +255,7 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
s += " goto out;\n"
for f in [f for f in ty.fields if not f.const and not f.type.private]:
(nparent,fexpr) = ty.member(v, f, parent is None)
- s += "s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (f.name, f.name)
- s += "if (s != yajl_gen_status_ok)\n"
- s += " goto out;\n"
+ s += libxl_C_type_gen_map_key(f, nparent)
s += libxl_C_type_gen_json(f.type, fexpr, "", nparent)
s += "s = yajl_gen_map_close(hand);\n"
s += "if (s != yajl_gen_status_ok)\n"
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 19/32] libxl/gentypes.py: don't generate default values
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (17 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:29 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
` (13 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
If a type has init_val defined and a field of the type has the value of
init_val, there's no need to generate output for that field.
Also define a bunch of init_vals for enumeration types.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/gentypes.py | 27 ++++++++++++++++++++++++---
tools/libxl/libxl_types.idl | 27 ++++++++++++++-------------
2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 01416e7..d2ed12a 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -135,7 +135,7 @@ def _libxl_C_type_init(ty, v, indent = " ", parent = None, subinit=False):
else:
s += _libxl_C_type_init(f.type, fexpr, "", nparent)
else:
- if ty.init_val is not None:
+ if ty.init_val is not None and ty.typename != "libxl_defbool":
s += "%s = %s;\n" % (ty.pass_arg(v, parent is None), ty.init_val)
elif ty.init_fn is not None:
s += "%s(%s);\n" % (ty.init_fn, ty.pass_arg(v, parent is None))
@@ -206,6 +206,13 @@ def libxl_C_type_gen_map_key(f, parent, indent = ""):
s = indent + s
return s.replace("\n", "\n%s" % indent).rstrip(indent)
+def get_init_val(f):
+ if f.init_val is not None:
+ return f.init_val
+ elif f.type.init_val is not None:
+ return f.type.init_val
+ return None
+
def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
s = ""
if parent is None:
@@ -255,8 +262,22 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
s += " goto out;\n"
for f in [f for f in ty.fields if not f.const and not f.type.private]:
(nparent,fexpr) = ty.member(v, f, parent is None)
- s += libxl_C_type_gen_map_key(f, nparent)
- s += libxl_C_type_gen_json(f.type, fexpr, "", nparent)
+ init_val = get_init_val(f)
+ if init_val:
+ if f.type.typename != "libxl_defbool":
+ s += "if (%s != %s) {\n" % (fexpr, init_val)
+ else:
+ s += "if (%s.val != %s) {\n" % (fexpr, init_val)
+ indent1 = " "
+ else:
+ indent1 = ""
+
+ s += libxl_C_type_gen_map_key(f, nparent, indent1)
+ s += libxl_C_type_gen_json(f.type, fexpr, indent, nparent)
+
+ if init_val:
+ s += "}\n"
+
s += "s = yajl_gen_map_close(hand);\n"
s += "if (s != yajl_gen_status_ok)\n"
s += " goto out;\n"
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 2162c37..35da8ba 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,7 +5,8 @@
namespace("libxl_")
-libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE)
+libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE,
+ init_val="LIBXL__DEFBOOL_DEFAULT")
libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False)
libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False, signed = True, init_val="-1")
@@ -55,13 +56,13 @@ libxl_device_model_version = Enumeration("device_model_version", [
(0, "UNKNOWN"),
(1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm)
(2, "QEMU_XEN"), # Upstream based qemu-xen device model
- ])
+ ], init_val = "LIBXL_DEVICE_MODEL_VERSION_UNKNOWN")
libxl_console_type = Enumeration("console_type", [
(0, "UNKNOWN"),
(1, "SERIAL"),
(2, "PV"),
- ])
+ ], init_val = "LIBXL_CONSOLE_TYPE_UNKNOWN")
libxl_disk_format = Enumeration("disk_format", [
(0, "UNKNOWN"),
@@ -70,20 +71,20 @@ libxl_disk_format = Enumeration("disk_format", [
(3, "VHD"),
(4, "RAW"),
(5, "EMPTY"),
- ])
+ ], init_val = "LIBXL_DISK_FORMAT_UNKNOWN")
libxl_disk_backend = Enumeration("disk_backend", [
(0, "UNKNOWN"),
(1, "PHY"),
(2, "TAP"),
(3, "QDISK"),
- ])
+ ], init_val = "LIBXL_DISK_BACKEND_UNKNOWN")
libxl_nic_type = Enumeration("nic_type", [
(0, "UNKNOWN"),
(1, "VIF_IOEMU"),
(2, "VIF"),
- ])
+ ], init_val = "LIBXL_NIC_TYPE_UNKNOWN")
libxl_action_on_shutdown = Enumeration("action_on_shutdown", [
(1, "DESTROY"),
@@ -95,7 +96,7 @@ libxl_action_on_shutdown = Enumeration("action_on_shutdown", [
(5, "COREDUMP_DESTROY"),
(6, "COREDUMP_RESTART"),
- ], init_val = 1)
+ ], init_val = "LIBXL_ACTION_ON_SHUTDOWN_DESTROY")
libxl_trigger = Enumeration("trigger", [
(0, "UNKNOWN"),
@@ -105,14 +106,14 @@ libxl_trigger = Enumeration("trigger", [
(4, "INIT"),
(5, "RESET"),
(6, "S3RESUME"),
- ])
+ ], init_val = "LIBXL_TRIGGER_UNKNOWN")
libxl_tsc_mode = Enumeration("tsc_mode", [
(0, "default"),
(1, "always_emulate"),
(2, "native"),
(3, "native_paravirt"),
- ])
+ ], init_val = "LIBXL_TSC_MODE_DEFAULT")
# Consistent with the values defined for HVM_PARAM_TIMER_MODE.
libxl_timer_mode = Enumeration("timer_mode", [
@@ -128,7 +129,7 @@ libxl_bios_type = Enumeration("bios_type", [
(1, "rombios"),
(2, "seabios"),
(3, "ovmf"),
- ])
+ ], init_val = "LIBXL_BIOS_TYPE_UNKNOWN")
# Consistent with values defined in domctl.h
# Except unknown which we have made up
@@ -138,7 +139,7 @@ libxl_scheduler = Enumeration("scheduler", [
(5, "credit"),
(6, "credit2"),
(7, "arinc653"),
- ])
+ ], init_val = "LIBXL_SCHEDULER_UNKNOWN")
# Consistent with SHUTDOWN_* in sched.h (apart from UNKNOWN)
libxl_shutdown_reason = Enumeration("shutdown_reason", [
@@ -154,12 +155,12 @@ libxl_vga_interface_type = Enumeration("vga_interface_type", [
(1, "CIRRUS"),
(2, "STD"),
(3, "NONE"),
- ], init_val = 1)
+ ], init_val = "LIBXL_VGA_INTERFACE_TYPE_CIRRUS")
libxl_vendor_device = Enumeration("vendor_device", [
(0, "NONE"),
(1, "XENSERVER"),
- ])
+ ], init_val = "LIBXL_VENDOR_DEVICE_NONE")
#
# Complex libxl types
#
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (18 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 19/32] libxl/gentypes.py: don't generate default values Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:35 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 21/32] libxl/gentest.py: test JSON parser Wei Liu
` (12 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
libxl_FOO_parse_json functions are generated.
Note that these functions are used to parse libxl__json_object to
libxl__FOO struct. They don't consume JSON string.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/gentypes.py | 131 ++++++++++++++++++++++++++++++++++
tools/libxl/idl.py | 15 ++++
tools/libxl/idl.txt | 7 +-
tools/libxl/libxl.h | 14 ++++
tools/libxl/libxl_types.idl | 29 ++++----
tools/libxl/libxl_types_internal.idl | 4 +-
6 files changed, 186 insertions(+), 14 deletions(-)
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index d2ed12a..c51e96a 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -304,6 +304,116 @@ def libxl_C_type_to_json(ty, v, indent = " "):
s = indent + s
return s.replace("\n", "\n%s" % indent).rstrip(indent)
+def libxl_C_type_parse_json(ty, w, v, indent = " ", parent = None, discriminator = None):
+ s = ""
+ if parent is None:
+ s += "int rc = 0;\n"
+ s += "const libxl__json_object *x = o;\n"
+
+ if isinstance(ty, idl.Array):
+ if parent is None:
+ raise Exception("Array type must have a parent")
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ lenvar = parent + ty.lenvar.name
+ s += "{\n"
+ s += " libxl__json_object *t;\n"
+ s += " int i;\n"
+ s += " if (!libxl__json_object_is_array(x)) {\n"
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += " %s = x->u.array->count;\n" % lenvar
+ s += " %s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (v, lenvar, v)
+ s += " if (!%s && %s != 0) {\n" % (v, lenvar)
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += " for (i=0; (t=libxl__json_array_get(x,i)); i++) {\n"
+ s += libxl_C_type_parse_json(ty.elem_type, "t", v+"[i]",
+ indent + " ", parent)
+ s += " }\n"
+ s += " if (i != %s) {\n" % lenvar
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += "}\n"
+ elif isinstance(ty, idl.Enumeration):
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ s += "{\n"
+ s += " const char *enum_str;\n"
+ s += " if (!libxl__json_object_is_string(x)) {\n"
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += " enum_str = libxl__json_object_get_string(x);\n"
+ s += " rc = %s_from_string(enum_str, %s);\n" % (ty.typename, ty.pass_arg(v, parent is None, idl.PASS_BY_REFERENCE))
+ s += " if (rc)\n"
+ s += " goto out;\n"
+ s += "}\n"
+ elif isinstance(ty, idl.KeyedUnion):
+ if parent is None:
+ raise Exception("KeyedUnion type must have a parent")
+ if discriminator is None:
+ raise Excpetion("KeyedUnion type must have a discriminator")
+ for f in ty.fields:
+ if f.enumname != discriminator:
+ continue
+ (nparent,fexpr) = ty.member(v, f, parent is None)
+ if f.type is not None:
+ s += libxl_C_type_parse_json(f.type, w, fexpr, indent + " ", nparent)
+ elif isinstance(ty, idl.Struct) and (parent is None or ty.json_parse_fn is None):
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ for f in [f for f in ty.fields if not f.const and not f.type.private]:
+ if isinstance(f.type, idl.KeyedUnion):
+ for x in f.type.fields:
+ s += "if (libxl__json_map_get(\"%s\", %s, JSON_MAP)) {\n" % \
+ (f.type.keyvar.name + "." + x.name, w)
+ s += " x = libxl__json_map_get(\"%s\", %s, JSON_MAP);\n" % \
+ (f.type.keyvar.name + "." + x.name, w)
+
+ (nparent, fexpr) = ty.member(v, f.type.keyvar, parent is None)
+ s += " %s = %s;\n" % (fexpr, x.enumname)
+
+ (nparent,fexpr) = ty.member(v, f, parent is None)
+ #s += "XXX %s %s %s\n" % (nparent, fexpr, f.name)
+ s += libxl_C_type_parse_json(f.type, "x", fexpr, "", nparent, x.enumname)
+ #s += "YYY\n"
+ s += "}\n"
+ else:
+ s += "if (libxl__json_map_get(\"%s\", %s, %s)) {\n" % (f.name, w, f.type.json_parse_type)
+ s += " x = libxl__json_map_get(\"%s\", %s, %s);\n" % (f.name, w, f.type.json_parse_type)
+ (nparent,fexpr) = ty.member(v, f, parent is None)
+ s += libxl_C_type_parse_json(f.type, "x", fexpr, " ", nparent)
+ s += " x = x->parent;\n"
+ s += "}\n"
+ else:
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ if ty.json_parse_fn is not None:
+ s += "rc = %s(gc, %s, &%s);\n" % (ty.json_parse_fn, w, v)
+ s += "if (rc)\n"
+ s += " goto out;\n"
+
+ if parent is None:
+ s += "out:\n"
+ s += "return rc;\n"
+
+ if s != "":
+ s = indent +s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
+def libxl_C_type_from_json(ty, v, w, indent = " "):
+ s = ""
+ parse = "(libxl__json_parse_callback)&%s_parse_json" % ty.typename
+ s += "return libxl__object_from_json(ctx, \"%s\", %s, %s, %s);\n" % (ty.typename, parse, v, w)
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
def libxl_C_enum_to_string(ty, e, indent = " "):
s = ""
s += "switch(%s) {\n" % e
@@ -382,6 +492,8 @@ if __name__ == '__main__':
ku.keyvar.type.make_arg(ku.keyvar.name)))
if ty.json_gen_fn is not None:
f.write("%schar *%s_to_json(libxl_ctx *ctx, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p")))
+ if ty.json_parse_fn is not None:
+ f.write("%sint %s_from_json(libxl_ctx *ctx, %s, const char *s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
if isinstance(ty, idl.Enumeration):
f.write("%sconst char *%s_to_string(%s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p")))
f.write("%sint %s_from_string(const char *s, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("e", passby=idl.PASS_BY_REFERENCE)))
@@ -411,6 +523,10 @@ if __name__ == '__main__':
for ty in [ty for ty in types if ty.json_gen_fn is not None]:
f.write("%syajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+ for ty in [ty for ty in types if ty.json_parse_fn is not None]:
+ f.write("%sint %s_parse_json(libxl__gc *gc, const libxl__json_object *o, %s);\n" % \
+ (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+
f.write("\n")
f.write("""#endif /* %s */\n""" % header_json_define)
f.close()
@@ -478,4 +594,19 @@ if __name__ == '__main__':
f.write("}\n")
f.write("\n")
+ for ty in [t for t in types if t.json_parse_fn is not None]:
+ f.write("int %s_parse_json(libxl__gc *gc, const libxl__json_object *%s, %s)\n" % (ty.typename,"o",ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+ f.write("{\n")
+ f.write(libxl_C_type_parse_json(ty, "o", "p"))
+ f.write("}\n")
+ f.write("\n")
+
+ f.write("int %s_from_json(libxl_ctx *ctx, %s, const char *s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+ f.write("{\n")
+ if not isinstance(ty, idl.Enumeration):
+ f.write(" %s_init(p);\n" % ty.typename)
+ f.write(libxl_C_type_from_json(ty, "p", "s"))
+ f.write("}\n")
+ f.write("\n")
+
f.close()
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index 8b118dd..747e3ee 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -66,8 +66,12 @@ class Type(object):
if self.typename is not None and not self.private:
self.json_gen_fn = kwargs.setdefault('json_gen_fn', self.typename + "_gen_json")
+ self.json_parse_type = kwargs.setdefault('json_parse_type', "JSON_ANY")
+ self.json_parse_fn = kwargs.setdefault('json_parse_fn', self.typename + "_parse_json")
else:
self.json_gen_fn = kwargs.setdefault('json_gen_fn', None)
+ self.json_parse_type = kwargs.setdefault('json_parse_type', None)
+ self.json_parse_fn = kwargs.setdefault('json_parse_fn', None)
self.autogenerate_json = kwargs.setdefault('autogenerate_json', True)
@@ -119,6 +123,9 @@ class Number(Builtin):
kwargs.setdefault('dispose_fn', None)
kwargs.setdefault('signed', False)
kwargs.setdefault('json_gen_fn', "yajl_gen_integer")
+ kwargs.setdefault('json_parse_type', "JSON_INTEGER")
+ # json_parse_fn might be overriden on specific type
+ kwargs.setdefault('json_parse_fn', "libxl__int_parse_json")
self.signed = kwargs['signed']
Builtin.__init__(self, ctype, **kwargs)
@@ -126,6 +133,7 @@ class UInt(Number):
def __init__(self, w, **kwargs):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('json_parse_fn', "libxl__uint%d_parse_json" % w)
Number.__init__(self, "uint%d_t" % w, **kwargs)
self.width = w
@@ -142,6 +150,7 @@ class EnumerationValue(object):
class Enumeration(Type):
def __init__(self, typename, values, **kwargs):
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('json_parse_type', "JSON_STRING")
Type.__init__(self, typename, **kwargs)
self.value_namespace = kwargs.setdefault('value_namespace',
@@ -171,6 +180,7 @@ class Field(object):
class Aggregate(Type):
"""A type containing a collection of other types"""
def __init__(self, kind, typename, fields, **kwargs):
+ kwargs.setdefault('json_parse_type', "JSON_MAP")
Type.__init__(self, typename, **kwargs)
if self.typename is not None:
@@ -257,6 +267,8 @@ class KeyedUnion(Aggregate):
void = Builtin("void *", namespace = None)
bool = Builtin("bool", namespace = None,
json_gen_fn = "yajl_gen_bool",
+ json_parse_type = "JSON_BOOL",
+ json_parse_fn = "libxl__bool_parse_json",
autogenerate_json = False)
size_t = Number("size_t", namespace = None)
@@ -270,12 +282,15 @@ uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json")
string = Builtin("char *", namespace = None, dispose_fn = "free",
json_gen_fn = "libxl__string_gen_json",
+ json_parse_type = "JSON_STRING | JSON_NULL",
+ json_parse_fn = "libxl__string_parse_json",
autogenerate_json = False)
class Array(Type):
"""An array of the same type"""
def __init__(self, elem_type, lenvar_name, **kwargs):
kwargs.setdefault('dispose_fn', 'free')
+ kwargs.setdefault('json_parse_type', 'JSON_ARRAY')
Type.__init__(self, namespace=elem_type.namespace, typename=elem_type.rawname + " *", **kwargs)
lv_kwargs = dict([(x.lstrip('lenvar_'),y) for (x,y) in kwargs.items() if x.startswith('lenvar_')])
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index 6a53dd8..484d5d7 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -65,9 +65,14 @@ Type.json_gen_fn: (default: typename + "_gen_json" or None if type == None)
The name of the C function which will generate a YAJL data structure
representing this type.
+Type.json_parse_fn: (default: typename + "_parse_json" or None if type == None)
+
+ The name of the C function which will parse a libxl JSON structure
+ representing this type to C type.
+
Type.autogenerate_json: (default: True)
- Indicates if the above named Type.json_gen_fn should be autogenerated.
+ Indicates if the above named Type.json_*_fn should be autogenerated.
Other simple type-Classes
-------------------------
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 5b0de1c..88f3b02 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -291,6 +291,20 @@
*
* Generates a JSON object from "p" in the form of a NULL terminated
* string.
+ *
+ * <type *> libxl_<type>_from_json(const char *json)
+ * int libxl_<type>_from_json(const char *json)
+ *
+ * Parses "json" and returns:
+ *
+ * an int value, if <type> is enumeration type. The value is the enum value
+ * representing the respective string in "json".
+ *
+ * an instance of <type>, if <type> is aggregate type. The returned
+ * instance has its fields filled in by the parser according to "json".
+ *
+ * If the parsing fails, caller cannot rely on the value / instance
+ * returned.
*/
#ifndef LIBXL_H
#define LIBXL_H
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 35da8ba..ff175f4 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,19 +5,24 @@
namespace("libxl_")
-libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE,
+libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE,
init_val="LIBXL__DEFBOOL_DEFAULT")
-libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False)
-libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False, signed = True, init_val="-1")
-libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE)
-libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE)
-libxl_bitmap = Builtin("bitmap", dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE)
-libxl_cpuid_policy_list = Builtin("cpuid_policy_list", dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE)
-
-libxl_string_list = Builtin("string_list", dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE)
-libxl_key_value_list = Builtin("key_value_list", dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE)
-libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE)
+libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json",
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False)
+libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__int_parse_json",
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1")
+libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE)
+libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE)
+libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE)
+libxl_cpuid_policy_list = Builtin("cpuid_policy_list", json_parse_type="JSON_ARRAY",
+ dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE)
+
+libxl_string_list = Builtin("string_list", json_parse_type="JSON_ARRAY",
+ dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE)
+libxl_key_value_list = Builtin("key_value_list", json_parse_type="JSON_MAP",
+ dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE)
+libxl_hwcap = Builtin("hwcap", json_parse_type="JSON_ARRAY", passby=PASS_BY_REFERENCE)
#
# Specific integer types
@@ -582,7 +587,7 @@ libxl_event_type = Enumeration("event_type", [
libxl_ev_user = UInt(64)
-libxl_ev_link = Builtin("ev_link", passby=PASS_BY_REFERENCE, private=True)
+libxl_ev_link = Builtin("ev_link", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, private=True)
libxl_event = Struct("event",[
("link", libxl_ev_link),
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index a964851..17533f1 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -1,7 +1,9 @@
namespace("libxl__")
hidden(True)
-libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer")
+libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer",
+ json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER",
+ autogenerate_json = False)
libxl__qmp_message_type = Enumeration("qmp_message_type", [
(1, "QMP"),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 21/32] libxl/gentest.py: test JSON parser
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (19 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length Wei Liu
` (11 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
The test is done in following steps:
1. initialise libxl_FOO struct
2. generate JSON string A for libxl_FOO struct FOO1
3. convert JSON string A to libxl_FOO struct FOO2
4. generate JSON string B for libxl_FOO struct FOO2
5. compare A and B
If A and B are identical then we are good.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/gentest.py | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py
index eb9a21b..b92d092 100644
--- a/tools/libxl/gentest.py
+++ b/tools/libxl/gentest.py
@@ -225,10 +225,11 @@ int main(int argc, char **argv)
""")
for ty in types:
- f.write(" %s %s_val;\n" % (ty.typename, ty.typename))
+ f.write(" %s %s_val, %s_val_new;\n" % \
+ (ty.typename, ty.typename, ty.typename))
f.write("""
int rc;
- char *s;
+ char *s, *new_s;
xentoollog_logger_stdiostream *logger;
libxl_ctx *ctx;
@@ -240,20 +241,36 @@ int main(int argc, char **argv)
exit(1);
}
""")
- f.write(" printf(\"Testing TYPE_to_json()\\n\");\n")
+ f.write(" printf(\"Testing TYPE_to/from_json()\\n\");\n")
f.write(" printf(\"----------------------\\n\");\n")
f.write(" printf(\"\\n\");\n")
for ty in [t for t in types if t.json_gen_fn is not None]:
arg = ty.typename + "_val"
f.write(" %s_rand_init(%s);\n" % (ty.typename, \
ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ if not isinstance(ty, idl.Enumeration):
+ f.write(" %s_init(%s_new);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
f.write(" s = %s_to_json(ctx, %s);\n" % \
(ty.typename, ty.pass_arg(arg, isref=False)))
f.write(" printf(\"%%s: %%s\\n\", \"%s\", s);\n" % ty.typename)
f.write(" if (s == NULL) abort();\n")
+ f.write(" rc = %s_from_json(ctx, &%s_val_new, s);\n" % \
+ (ty.typename, ty.typename))
+ f.write(" if (rc) abort();\n")
+ f.write(" new_s = %s_to_json(ctx, %s_new);\n" % \
+ (ty.typename, ty.pass_arg(arg, isref=False)))
+ f.write(" if (new_s == NULL) abort();\n")
+ f.write(" if (strcmp(s, new_s)) {\n")
+ f.write(" printf(\"Huh? Regenerated string different from original string.\\n\");\n")
+ f.write(" printf(\"Regenerated string: %s\\n\", new_s);\n")
+ f.write(" abort();\n")
+ f.write(" }\n")
f.write(" free(s);\n")
+ f.write(" free(new_s);\n")
if ty.dispose_fn is not None:
f.write(" %s(&%s_val);\n" % (ty.dispose_fn, ty.typename))
+ f.write(" %s(&%s_val_new);\n" % (ty.dispose_fn, ty.typename))
f.write("\n")
f.write(" printf(\"Testing Enumerations\\n\");\n")
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (20 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 21/32] libxl/gentest.py: test JSON parser Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:36 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length Wei Liu
` (10 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 12 ++++++++++++
tools/libxl/libxl.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 0589d4e..0a73a98 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -216,6 +216,18 @@ int libxl_string_list_length(const libxl_string_list *psl)
return i;
}
+int libxl_key_value_list_length(libxl_key_value_list *pkvl)
+{
+ int i = 0;
+ libxl_key_value_list kvl = *pkvl;
+
+ if (kvl)
+ while (kvl[2 * i]) /* Only checks keys */
+ i++;
+
+ return i;
+}
+
void libxl_key_value_list_dispose(libxl_key_value_list *pkvl)
{
int i;
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 88f3b02..3886b9e 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -553,6 +553,7 @@ int libxl_string_list_length(const libxl_string_list *sl);
typedef char **libxl_key_value_list;
void libxl_key_value_list_dispose(libxl_key_value_list *kvl);
+int libxl_key_value_list_length(libxl_key_value_list *kvl);
typedef uint32_t libxl_hwcap[8];
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (21 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:36 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 24/32] libxl: copy function for builtin types Wei Liu
` (9 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.h | 1 +
tools/libxl/libxl_cpuid.c | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 3886b9e..4b75802 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -573,6 +573,7 @@ void libxl_bitmap_dispose(libxl_bitmap *map);
typedef struct libxl__cpuid_policy libxl_cpuid_policy;
typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list);
+int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *l);
#define LIBXL_PCI_FUNC_ALL (~0U)
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index d9007b2..fe14b87 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -455,6 +455,18 @@ int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
return 0;
}
+int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *pl)
+{
+ int i = 0;
+ libxl_cpuid_policy_list l = *pl;
+
+ if (l)
+ while (l[i].input[0] != XEN_CPUID_INPUT_UNUSED)
+ i++;
+
+ return i;
+}
+
/*
* Local variables:
* mode: C
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 24/32] libxl: copy function for builtin types
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (22 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:39 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 25/32] libxl IDL: generate deep copy functions Wei Liu
` (8 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
These functions will be used in later patch to deep-copy a structure.
Functions introduced:
* libxl_string_list_copy
* libxl_key_value_list_copy
* libxl_hwcap_copy
* libxl_mac_copy
* libxl_cpuid_policy_list_copy
* libxl_string_copy
* libxl_bitmap_copy_alloc
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 67 +++++++++++++++++++++++++++++++++++++++++++
tools/libxl/libxl.h | 14 +++++++--
tools/libxl/libxl_cpuid.c | 33 +++++++++++++++++++++
tools/libxl/libxl_nocpuid.c | 6 ++++
tools/libxl/libxl_utils.c | 25 ++++++++++++++++
tools/libxl/libxl_utils.h | 4 +++
tools/libxl/libxl_uuid.h | 1 -
7 files changed, 147 insertions(+), 3 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 0a73a98..c9475d7 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -205,6 +205,29 @@ void libxl_string_list_dispose(libxl_string_list *psl)
free(sl);
}
+void libxl_string_list_copy(libxl_ctx *ctx,
+ libxl_string_list *dst,
+ libxl_string_list *src)
+{
+ GC_INIT(ctx);
+ int i, len;
+
+ if (!*src) {
+ *dst = NULL;
+ goto out;
+ }
+
+ len = libxl_string_list_length(src);
+ /* one extra slot for sentinel */
+ *dst = libxl__calloc(NOGC, len + 1, sizeof(char *));
+
+ for (i = 0; i < len; i++)
+ (*dst)[i] = libxl__strdup(NOGC, (*src)[i]);
+
+out:
+ GC_FREE;
+}
+
int libxl_string_list_length(const libxl_string_list *psl)
{
int i = 0;
@@ -244,6 +267,34 @@ void libxl_key_value_list_dispose(libxl_key_value_list *pkvl)
free(kvl);
}
+void libxl_key_value_list_copy(libxl_ctx *ctx,
+ libxl_key_value_list *dst,
+ libxl_key_value_list *src)
+{
+ GC_INIT(ctx);
+ int i, len;
+
+ if (*src == NULL) {
+ *dst = NULL;
+ goto out;
+ }
+
+ len = libxl_key_value_list_length(src);
+ /* one extra slot for sentinel */
+ *dst = libxl__calloc(NOGC, len * 2 + 1, sizeof(char *));
+
+ for (i = 0; i < len * 2; i += 2) {
+ (*dst)[i] = libxl__strdup(NOGC, (*src)[i]);
+ if ((*src)[i+1])
+ (*dst)[i+1] = libxl__strdup(NOGC, (*src)[i+1]);
+ else
+ (*dst)[i+1] = NULL;
+ }
+
+out:
+ GC_FREE;
+}
+
void libxl_defbool_set(libxl_defbool *db, bool b)
{
db->val = b ? LIBXL__DEFBOOL_TRUE : LIBXL__DEFBOOL_FALSE;
@@ -5684,6 +5735,22 @@ int libxl_fd_set_cloexec(libxl_ctx *ctx, int fd, int cloexec)
int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock)
{ return fd_set_flags(ctx,fd, F_GETFL,F_SETFL,"FL", O_NONBLOCK, nonblock); }
+
+void libxl_hwcap_copy(libxl_ctx *ctx,libxl_hwcap *dst, libxl_hwcap *src)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ (*dst)[i] = (*src)[i];
+}
+
+void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src)
+{
+ int i;
+
+ for (i = 0; i < 6; i++)
+ (*dst)[i] = (*src)[i];
+}
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 4b75802..d5dfe2e 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -542,20 +542,29 @@
*/
#define LIBXL_HAVE_CPUPOOL_NAME 1
+typedef struct libxl__ctx libxl_ctx;
+
typedef uint8_t libxl_mac[6];
#define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
#define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
#define LIBXL_MAC_BYTES(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
+void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src);
typedef char **libxl_string_list;
void libxl_string_list_dispose(libxl_string_list *sl);
int libxl_string_list_length(const libxl_string_list *sl);
+void libxl_string_list_copy(libxl_ctx *ctx, libxl_string_list *dst,
+ libxl_string_list *src);
typedef char **libxl_key_value_list;
void libxl_key_value_list_dispose(libxl_key_value_list *kvl);
int libxl_key_value_list_length(libxl_key_value_list *kvl);
+void libxl_key_value_list_copy(libxl_ctx *ctx,
+ libxl_key_value_list *dst,
+ libxl_key_value_list *src);
typedef uint32_t libxl_hwcap[8];
+void libxl_hwcap_copy(libxl_ctx *ctx, libxl_hwcap *dst, libxl_hwcap *src);
typedef uint64_t libxl_ev_user;
@@ -574,6 +583,9 @@ typedef struct libxl__cpuid_policy libxl_cpuid_policy;
typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list);
int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *l);
+void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
+ libxl_cpuid_policy_list *dst,
+ libxl_cpuid_policy_list *src);
#define LIBXL_PCI_FUNC_ALL (~0U)
@@ -618,8 +630,6 @@ bool libxl_defbool_val(libxl_defbool db);
const char *libxl_defbool_to_string(libxl_defbool b);
-typedef struct libxl__ctx libxl_ctx;
-
#define LIBXL_TIMER_MODE_DEFAULT -1
#define LIBXL_MEMKB_DEFAULT ~0ULL
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index fe14b87..ee16663 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -467,6 +467,39 @@ int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *pl)
return i;
}
+void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
+ libxl_cpuid_policy_list *dst,
+ libxl_cpuid_policy_list *src)
+{
+ GC_INIT(ctx);
+ int i, j, len;
+
+ if (*src == NULL) {
+ *dst = NULL;
+ goto out;
+ }
+
+ len = libxl_cpuid_policy_list_length(src);
+ /* one extra slot for sentinel */
+ *dst = libxl__calloc(NOGC, len + 1, sizeof(libxl_cpuid_policy));
+ (*dst)[len].input[0] = XEN_CPUID_INPUT_UNUSED;
+ (*dst)[len].input[1] = XEN_CPUID_INPUT_UNUSED;
+
+ for (i = 0; i < len; i++) {
+ for (j = 0; j < 2; j++)
+ (*dst)[i].input[j] = (*src)[i].input[j];
+ for (j = 0; j < 4; j++)
+ if ((*src)[i].policy[j])
+ (*dst)[i].policy[j] =
+ libxl__strdup(NOGC, (*src)[i].policy[j]);
+ else
+ (*dst)[i].policy[j] = NULL;
+ }
+
+out:
+ GC_FREE;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_nocpuid.c b/tools/libxl/libxl_nocpuid.c
index eb525fc..698d252 100644
--- a/tools/libxl/libxl_nocpuid.c
+++ b/tools/libxl/libxl_nocpuid.c
@@ -51,6 +51,12 @@ int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
return 0;
}
+void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
+ libxl_cpuid_policy_list *dst,
+ libxl_cpuid_policy_list *src)
+{
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 16b734e..6053017 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -614,6 +614,19 @@ void libxl_bitmap_copy(libxl_ctx *ctx, libxl_bitmap *dptr,
memcpy(dptr->map, sptr->map, sz * sizeof(*dptr->map));
}
+void libxl_bitmap_copy_alloc(libxl_ctx *ctx,
+ libxl_bitmap *dptr,
+ const libxl_bitmap *sptr)
+{
+ GC_INIT(ctx);
+
+ dptr->map = libxl__calloc(NOGC, sptr->size, sizeof(*sptr->map));
+ dptr->size = sptr->size;
+ memcpy(dptr->map, sptr->map, sptr->size * sizeof(*sptr->map));
+
+ GC_FREE;
+}
+
int libxl_bitmap_is_full(const libxl_bitmap *bitmap)
{
int i;
@@ -1013,6 +1026,18 @@ int libxl_domid_valid_guest(uint32_t domid)
return domid > 0 && domid < DOMID_FIRST_RESERVED;
}
+void libxl_string_copy(libxl_ctx *ctx, char **dst, char **src)
+{
+ GC_INIT(ctx);
+
+ if (*src)
+ *dst = libxl__strdup(NOGC, *src);
+ else
+ *dst = NULL;
+
+ GC_FREE;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 8bfb81b..cc528d2 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -76,6 +76,8 @@ int libxl_devid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
int libxl_bitmap_alloc(libxl_ctx *ctx, libxl_bitmap *bitmap, int n_bits);
/* Allocated bimap is from malloc, libxl_bitmap_dispose() to be
* called by the application when done. */
+void libxl_bitmap_copy_alloc(libxl_ctx *ctx, libxl_bitmap *dptr,
+ const libxl_bitmap *sptr);
void libxl_bitmap_copy(libxl_ctx *ctx, libxl_bitmap *dptr,
const libxl_bitmap *sptr);
int libxl_bitmap_is_full(const libxl_bitmap *bitmap);
@@ -121,6 +123,8 @@ int libxl_cpumap_to_nodemap(libxl_ctx *ctx,
return (s + 1023) / 1024;
}
+void libxl_string_copy(libxl_ctx *ctx, char **dst, char **src);
+
#endif
/*
diff --git a/tools/libxl/libxl_uuid.h b/tools/libxl/libxl_uuid.h
index 37c4d5f..041b927 100644
--- a/tools/libxl/libxl_uuid.h
+++ b/tools/libxl/libxl_uuid.h
@@ -61,7 +61,6 @@ void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src);
#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x040500
void libxl_uuid_copy(dst, src) libxl_uuid_copy(NULL, dst, src)
#endif
-
void libxl_uuid_clear(libxl_uuid *uuid);
int libxl_uuid_compare(libxl_uuid *uuid1, libxl_uuid *uuid2);
uint8_t *libxl_uuid_bytearray(libxl_uuid *uuid);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 25/32] libxl IDL: generate deep copy functions
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (23 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 24/32] libxl: copy function for builtin types Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 13:42 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 26/32] libxl/gentest.py: test " Wei Liu
` (7 subsequent siblings)
32 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Introduces copy_fn for a type.
For most builtin types we can use direct assignment. For those builtin
types which cannot use direct assignment we use the copy functions in
previous patch.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/gentypes.py | 67 ++++++++++++++++++++++++++++++++++
tools/libxl/idl.py | 13 ++++++-
tools/libxl/idl.txt | 12 ++++++
tools/libxl/libxl_types.idl | 27 ++++++++------
tools/libxl/libxl_types_internal.idl | 2 +-
5 files changed, 108 insertions(+), 13 deletions(-)
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index c51e96a..d7a3447 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -100,6 +100,61 @@ def libxl_C_type_dispose(ty, v, indent = " ", parent = None):
s = indent + s
return s.replace("\n", "\n%s" % indent).rstrip(indent)
+def libxl_C_type_copy(ty, v, w, indent = " ", vparent = None, wparent = None):
+ s = ""
+
+ if vparent is None:
+ s += "GC_INIT(ctx);\n";
+
+ if isinstance(ty, idl.KeyedUnion):
+ if vparent is None or wparent is None:
+ raise Exception("KeyedUnion type must have a parent")
+ s += "%s = %s;\n" % ((vparent + ty.keyvar.name), (wparent + ty.keyvar.name))
+ s += "switch (%s) {\n" % (wparent + ty.keyvar.name)
+ for f in ty.fields:
+ (vnparent,vfexpr) = ty.member(v, f, vparent is None)
+ (wnparent,wfexpr) = ty.member(w, f, wparent is None)
+ s += "case %s:\n" % f.enumname
+ if f.type is not None:
+ s += libxl_C_type_copy(f.type, vfexpr, wfexpr, indent + " ",
+ vnparent, wnparent)
+ s += " break;\n"
+ s += "}\n"
+ elif isinstance(ty, idl.Array):
+ if vparent is None or wparent is None:
+ raise Exception("Array type must have a parent")
+ s += "%s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (ty.pass_arg(v, vparent is None),
+ (wparent + ty.lenvar.name),
+ ty.pass_arg(w, wparent is None))
+ s += "%s = %s;\n" % ((vparent + ty.lenvar.name), (wparent + ty.lenvar.name))
+ s += "{\n"
+ s += " int i;\n"
+ s += " for (i=0; i<%s; i++)\n" % (wparent + ty.lenvar.name)
+ s += libxl_C_type_copy(ty.elem_type, v+"[i]", w+"[i]",
+ indent + " ", vparent, wparent)
+ s += "}\n"
+ elif isinstance(ty, idl.Struct) and ((vparent is None and wparent is None) or ty.copy_fn is None):
+ for f in [f for f in ty.fields if not f.const and not f.type.private]:
+ (vnparent,vfexpr) = ty.member(v, f, vparent is None)
+ (wnparent,wfexpr) = ty.member(w, f, wparent is None)
+ s += libxl_C_type_copy(f.type, vfexpr, wfexpr, "", vnparent, wnparent)
+ else:
+ if ty.copy_fn is not None:
+ s += "%s(ctx, %s, %s);\n" % (ty.copy_fn,
+ ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_REFERENCE),
+ ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_REFERENCE))
+
+ else:
+ s += "%s = %s;\n" % (ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_VALUE),
+ ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_VALUE))
+
+ if vparent is None:
+ s += "GC_FREE;\n"
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
def libxl_init_members(ty, nesting = 0):
"""Returns a list of members of ty which require a separate init"""
@@ -481,6 +536,9 @@ if __name__ == '__main__':
f.write(libxl_C_type_define(ty) + ";\n")
if ty.dispose_fn is not None:
f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.dispose_fn, ty.make_arg("p")))
+ if ty.copy_fn is not None:
+ f.write("%svoid %s(libxl_ctx *ctx, %s, %s);\n" % (ty.hidden(), ty.copy_fn,
+ ty.make_arg("dst"), ty.make_arg("src")))
if ty.init_fn is not None:
f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.init_fn, ty.make_arg("p")))
for field in libxl_init_members(ty):
@@ -560,6 +618,15 @@ if __name__ == '__main__':
f.write(" memset(p, LIBXL_DTOR_POISON, sizeof(*p));\n")
f.write("}\n")
f.write("\n")
+
+ for ty in [t for t in types if t.copy_fn and t.autogenerate_copy_fn]:
+ f.write("void %s(libxl_ctx *ctx, %s, %s)\n" % (ty.copy_fn,
+ ty.make_arg("dst", passby=idl.PASS_BY_REFERENCE),
+ ty.make_arg("src", passby=idl.PASS_BY_REFERENCE)))
+ f.write("{\n")
+ f.write(libxl_C_type_copy(ty, "dst", "src"))
+ f.write("}\n")
+ f.write("\n")
for ty in [t for t in types if t.init_fn is not None and t.autogenerate_init_fn]:
f.write(libxl_C_type_init(ty))
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index 747e3ee..5f8f8df 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -60,6 +60,13 @@ class Type(object):
self.autogenerate_dispose_fn = kwargs.setdefault('autogenerate_dispose_fn', True)
+ if self.typename is not None:
+ self.copy_fn = kwargs.setdefault('copy_fn', self.typename + "_copy")
+ else:
+ self.copy_fn = kwargs.setdefault('copy_fn', None)
+
+ self.autogenerate_copy_fn = kwargs.setdefault('autogenerate_copy_fn', True)
+
self.init_fn = kwargs.setdefault('init_fn', None)
self.init_val = kwargs.setdefault('init_val', None)
self.autogenerate_init_fn = kwargs.setdefault('autogenerate_init_fn', False)
@@ -121,6 +128,7 @@ class Number(Builtin):
def __init__(self, ctype, **kwargs):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('copy_fn', None)
kwargs.setdefault('signed', False)
kwargs.setdefault('json_gen_fn', "yajl_gen_integer")
kwargs.setdefault('json_parse_type', "JSON_INTEGER")
@@ -134,6 +142,7 @@ class UInt(Number):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
kwargs.setdefault('json_parse_fn', "libxl__uint%d_parse_json" % w)
+ kwargs.setdefault('copy_fn', None)
Number.__init__(self, "uint%d_t" % w, **kwargs)
self.width = w
@@ -150,6 +159,7 @@ class EnumerationValue(object):
class Enumeration(Type):
def __init__(self, typename, values, **kwargs):
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('copy_fn', None)
kwargs.setdefault('json_parse_type', "JSON_STRING")
Type.__init__(self, typename, **kwargs)
@@ -266,6 +276,7 @@ class KeyedUnion(Aggregate):
void = Builtin("void *", namespace = None)
bool = Builtin("bool", namespace = None,
+ copy_fn=None,
json_gen_fn = "yajl_gen_bool",
json_parse_type = "JSON_BOOL",
json_parse_fn = "libxl__bool_parse_json",
@@ -280,7 +291,7 @@ uint16 = UInt(16)
uint32 = UInt(32)
uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json")
-string = Builtin("char *", namespace = None, dispose_fn = "free",
+string = Builtin("char *", namespace = None, copy_fn = "libxl_string_copy", dispose_fn = "free",
json_gen_fn = "libxl__string_gen_json",
json_parse_type = "JSON_STRING | JSON_NULL",
json_parse_fn = "libxl__string_parse_json",
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index 484d5d7..8b54aeb 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -44,6 +44,18 @@ Type.autogenerate_dispose_fn: (default: True)
Indicates if the above named Type.dispose_fn should be
autogenerated.
+Type.copy_fn: (default: typename + "_copy" or None if type == None)
+
+ The name of the C function which will deep copy all fields within
+ this type.
+
+Type.autogenerate_copy_fn: (default: True)
+
+ Indicates if the above named Type.copy_fn should be
+ autogenerated.
+
+Type.autogenerate_copy_fn
+
Type.init_val: (default: None)
C expression for the value to initialise instances of this type to.
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index ff175f4..fbbd295 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,24 +5,29 @@
namespace("libxl_")
-libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE,
+libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, copy_fn=None,
init_val="LIBXL__DEFBOOL_DEFAULT")
-
libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json",
- json_parse_type = "JSON_INTEGER", autogenerate_json = False)
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False, copy_fn=None)
libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__int_parse_json",
- json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1")
-libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE)
-libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE)
-libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE)
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1",
+ copy_fn=None)
+libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, copy_fn="libxl_uuid_copy")
+libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, copy_fn="libxl_mac_copy")
+libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", dispose_fn="libxl_bitmap_dispose",
+ copy_fn='libxl_bitmap_copy_alloc', passby=PASS_BY_REFERENCE)
libxl_cpuid_policy_list = Builtin("cpuid_policy_list", json_parse_type="JSON_ARRAY",
- dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE)
+ dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE,
+ copy_fn="libxl_cpuid_policy_list_copy")
libxl_string_list = Builtin("string_list", json_parse_type="JSON_ARRAY",
- dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE)
+ dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE,
+ copy_fn="libxl_string_list_copy")
libxl_key_value_list = Builtin("key_value_list", json_parse_type="JSON_MAP",
- dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE)
-libxl_hwcap = Builtin("hwcap", json_parse_type="JSON_ARRAY", passby=PASS_BY_REFERENCE)
+ dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE,
+ copy_fn="libxl_key_value_list_copy")
+libxl_hwcap = Builtin("hwcap", json_parse_type="JSON_ARRAY", passby=PASS_BY_REFERENCE,
+ copy_fn="libxl_hwcap_copy")
#
# Specific integer types
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index 17533f1..800361b 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -3,7 +3,7 @@ hidden(True)
libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer",
json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER",
- autogenerate_json = False)
+ autogenerate_json = False, copy_fn = None)
libxl__qmp_message_type = Enumeration("qmp_message_type", [
(1, "QMP"),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 26/32] libxl/gentest.py: test deep copy functions
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (24 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 25/32] libxl IDL: generate deep copy functions Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions Wei Liu
` (6 subsequent siblings)
32 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
The test is done as followed:
1. initialise libxl_FOO struct A
2. deep-copy A to B
3. generate JSON string for A and B
4. compare two JSON strings
If two strings are identical then we're good.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/gentest.py | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py
index b92d092..07ffd31 100644
--- a/tools/libxl/gentest.py
+++ b/tools/libxl/gentest.py
@@ -273,6 +273,43 @@ int main(int argc, char **argv)
f.write(" %s(&%s_val_new);\n" % (ty.dispose_fn, ty.typename))
f.write("\n")
+ f.write(" printf(\"Testing TYPE_copy()\\n\");\n")
+ f.write(" printf(\"----------------------\\n\");\n")
+ f.write(" printf(\"\\n\");\n")
+ for ty in [t for t in types if t.copy_fn is not None]:
+ f.write(" printf(\"Testing %s_copy, \");\n" % ty.typename)
+ arg = ty.typename + "_val"
+ f.write(" %s_init(%s);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" %s_rand_init(%s);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" %s_init(%s_new);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" %s_copy(ctx, %s_new, %s);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE), \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" s = %s_to_json(ctx, %s);\n" % \
+ (ty.typename, ty.pass_arg(arg, isref=False)))
+ f.write(" if (s == NULL) abort();\n")
+ f.write(" new_s = %s_to_json(ctx, %s_new);\n" % \
+ (ty.typename, ty.pass_arg(arg, isref=False)))
+ f.write(" if (new_s == NULL) abort();\n")
+ f.write(" if (strcmp(s, new_s)) {\n")
+ f.write(" printf(\"Huh? Deep copy for %s failed. Regenerated string different from original string.\\n\");\n" \
+ % ty.typename)
+ f.write(" printf(\"Original string: %s\\n\", s);\n")
+ f.write(" printf(\"Regenerated string: %s\\n\", new_s);\n")
+ f.write(" abort();\n")
+ f.write(" }\n")
+ f.write(" free(s);\n")
+ f.write(" free(new_s);\n")
+ if ty.dispose_fn is not None:
+ f.write(" %s(&%s_val);\n" % (ty.dispose_fn, ty.typename))
+ f.write(" %s(&%s_val_new);\n" % (ty.dispose_fn, ty.typename))
+ f.write(" printf(\"done\\n\");\n")
+ f.write("\n")
+
+ f.write(" printf(\"\\n\");\n")
f.write(" printf(\"Testing Enumerations\\n\");\n")
f.write(" printf(\"--------------------\\n\");\n")
f.write(" printf(\"\\n\");\n")
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (25 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 26/32] libxl/gentest.py: test " Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 14:03 ` Ian Campbell
2014-05-20 15:01 ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain Wei Liu
` (5 subsequent siblings)
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Introduce a new format in libxl userdata store called "libxl-json". This
format contains the deserialized version of domain configuration of a
domain.
Two libxl functions to load and store domain configuration are also
introduced. They use the new "libxl-json" format.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
tools/libxl/libxl.h | 10 ++++++++
2 files changed, 78 insertions(+)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index c9475d7..b578a5c 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -5751,6 +5751,74 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src)
for (i = 0; i < 6; i++)
(*dst)[i] = (*src)[i];
}
+
+int libxl_load_domain_configuration(libxl_ctx *ctx, uint32_t domid,
+ libxl_domain_config *d_config)
+{
+ GC_INIT(ctx);
+ uint8_t *data;
+ int rc, len;
+
+ rc = libxl_userdata_retrieve(ctx, domid, "libxl-json", &data, &len);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Failed to retrieve domain configuration for domain %d",
+ domid);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ if (len == 0) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+ "Configuration data stream empty for domain %d",
+ domid);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ /* Make sure this string ends with \0 -- the parser expects a NULL
+ * terminated string.
+ */
+ if (data[len-1] != '\0') {
+ data = libxl__realloc(gc, data, len + 1);
+ data[len] = '\0';
+ }
+
+ rc = libxl_domain_config_from_json(ctx, d_config, (const char *)data);
+
+out:
+ free(data);
+ GC_FREE;
+ return rc;
+}
+
+int libxl_store_domain_configuration(libxl_ctx *ctx, uint32_t domid,
+ libxl_domain_config *d_config)
+{
+ GC_INIT(ctx);
+ char *d_config_json;
+ int rc;
+
+ d_config_json = libxl_domain_config_to_json(ctx, d_config);
+
+ rc = libxl_userdata_store(ctx, domid, "libxl-json",
+ (const uint8_t *)d_config_json,
+ strlen(d_config_json));
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Failed to store domain configuration for domain %d",
+ domid);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ free(d_config_json);
+
+out:
+ GC_FREE;
+ return rc;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index d5dfe2e..be722b6 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1140,6 +1140,8 @@ void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid,
* "xl" domain config file in xl format, Unix line endings
* "libvirt-xml" domain config file in libvirt XML format. See
* http://libvirt.org/formatdomain.html
+ * "libxl-json" domain config file in JSON format, generated by
+ * libxl
*
* libxl does not enforce the registration of userdata userids or the
* semantics of the data. For specifications of the data formats
@@ -1251,6 +1253,14 @@ int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size);
int libxl_fd_set_cloexec(libxl_ctx *ctx, int fd, int cloexec);
int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock);
+/* Load / save domain configuration. The domain configuration is
+ * stored in libxl userdata store.
+ */
+int libxl_load_domain_configuration(libxl_ctx *ctx, uint32_t domid,
+ libxl_domain_config *d_config);
+int libxl_store_domain_configuration(libxl_ctx *ctx, uint32_t domid,
+ libxl_domain_config *d_config);
+
#include <libxl_event.h>
#endif /* LIBXL_H */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (26 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 14:12 ` Ian Campbell
2014-05-20 15:04 ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 29/32] xl: use "libxl-json" format Wei Liu
` (4 subsequent siblings)
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
This patch utilizes "libxl-json" format and helper functions introduced
in previous patch to store up-to-do domain configuration when creating a
domain.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_create.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index da1517c..47859e0 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -716,6 +716,7 @@ static void initiate_domain_create(libxl__egc *egc,
int i, ret;
size_t last_devid = -1;
bool pod_enabled = false;
+ libxl_domain_config d_config_saved;
/* convenience aliases */
libxl_domain_config *const d_config = dcs->guest_config;
@@ -724,6 +725,8 @@ static void initiate_domain_create(libxl__egc *egc,
domid = 0;
+ libxl_domain_config_init(&d_config_saved);
+
if (d_config->c_info.ssid_label) {
char *s = d_config->c_info.ssid_label;
ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
@@ -800,6 +803,8 @@ static void initiate_domain_create(libxl__egc *egc,
goto error_out;
}
+ libxl_domain_config_copy(ctx, &d_config_saved, d_config);
+
ret = libxl__domain_create_info_setdefault(gc, &d_config->c_info);
if (ret) goto error_out;
@@ -814,6 +819,16 @@ static void initiate_domain_create(libxl__egc *egc,
dcs->guest_domid = domid;
dcs->dmss.dm.guest_domid = 0; /* means we haven't spawned */
+ /* At this point we've got domid and UUID, store configuration */
+ ret = libxl_store_domain_configuration(ctx, domid, &d_config_saved);
+ if (ret) {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot store domain configuration: %d",
+ ret);
+ ret = ERROR_FAIL;
+ goto error_out;
+ }
+ libxl_domain_config_dispose(&d_config_saved);
+
ret = libxl__domain_build_info_setdefault(gc, &d_config->b_info);
if (ret) goto error_out;
@@ -874,6 +889,7 @@ static void initiate_domain_create(libxl__egc *egc,
return;
error_out:
+ libxl_domain_config_dispose(&d_config_saved);
assert(ret);
domcreate_complete(egc, dcs, ret);
}
@@ -1356,6 +1372,24 @@ error_out:
domcreate_complete(egc, dcs, ret);
}
+static void update_domain_config(libxl_ctx *ctx,
+ libxl_domain_config *dst,
+ const libxl_domain_config *src)
+{
+ int i;
+
+ /* update network interface information */
+ for (i = 0; i < src->num_nics; i++)
+ libxl_mac_copy(ctx, &dst->nics[i].mac, &src->nics[i].mac);
+
+ /* update vtpm information */
+ for (i = 0; i < src->num_vtpms; i++)
+ libxl_uuid_copy(ctx, &dst->vtpms[i].uuid, &src->vtpms[i].uuid);
+
+ /* update guest UUID */
+ libxl_uuid_copy(ctx, &dst->c_info.uuid, &src->c_info.uuid);
+}
+
static void domcreate_complete(libxl__egc *egc,
libxl__domain_create_state *dcs,
int rc)
@@ -1366,6 +1400,25 @@ static void domcreate_complete(libxl__egc *egc,
if (!rc && d_config->b_info.exec_ssidref)
rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref);
+ if (!rc) {
+ libxl_domain_config d_config_saved;
+
+ libxl_domain_config_init(&d_config_saved);
+ rc = libxl_load_domain_configuration(CTX, dcs->guest_domid,
+ &d_config_saved);
+ if (rc) {
+ LOG(ERROR, "cannot load domain configuration: %d", rc);
+ goto out;
+ }
+ update_domain_config(CTX, &d_config_saved, d_config);
+ rc = libxl_store_domain_configuration(CTX, dcs->guest_domid,
+ &d_config_saved);
+ if (rc)
+ LOG(ERROR, "cannot store domain configuration: %d", rc);
+ libxl_domain_config_dispose(&d_config_saved);
+ }
+
+out:
if (rc) {
if (dcs->guest_domid) {
dcs->dds.ao = ao;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (27 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 14:23 ` Ian Campbell
2014-05-20 15:11 ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 30/32] libxl: consider force removal of device successful Wei Liu
` (3 subsequent siblings)
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Before this change, xl stores domain configuration in "xl" format, which
is in fact a verbatim copy of user supplied domain config.
As now libxl is able to handle domain configuration with "libxl-json"
format, use that wherever possible.
Tests done so far (xl.{new,old} denotes xl with{,out} "xl_json"
support):
1. xl.new create then xl.new save, hexdump saved file: domain config
saved in JSON format
2. xl.new create, xl.new save then xl.old restore: failed on
mandatory flag check
3. xl.new create, xl.new save then xl.new restore: succeeded
4. xl.old create, xl.old save then xl.new restore: succeeded
5. xl.new create then local migrate, receiving end xl.new: succeeded
6. xl.old create then local migrate, receiving end xl.new: succeeded
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/xl_cmdimpl.c | 141 ++++++++++++++++++++++++++++------------------
1 file changed, 87 insertions(+), 54 deletions(-)
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index a6dd437..db1ba18 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -107,6 +107,8 @@ static const char migrate_report[]=
* from target to source
*/
+#define XL_MANDATORY_FLAG_JSON (1U << 0) /* config data is in JSON format */
+#define XL_MANDATORY_FLAG_ALL (XL_MANDATORY_FLAG_JSON)
struct save_file_header {
char magic[32]; /* savefileheader_magic */
/* All uint32_ts are in domain's byte order. */
@@ -1706,30 +1708,11 @@ skip_vfb:
xlu_cfg_destroy(config);
}
-static void reload_domain_config(uint32_t domid,
- uint8_t **config_data, int *config_len)
-{
- uint8_t *t_data;
- int ret, t_len;
-
- ret = libxl_userdata_retrieve(ctx, domid, "xl", &t_data, &t_len);
- if (ret) {
- LOG("failed to retrieve guest configuration (rc=%d). "
- "reusing old configuration", ret);
- return;
- }
-
- free(*config_data);
- *config_data = t_data;
- *config_len = t_len;
-}
-
/* Returns 1 if domain should be restarted,
* 2 if domain should be renamed then restarted, or 0
* Can update r_domid if domain is destroyed etc */
static int handle_domain_death(uint32_t *r_domid,
libxl_event *event,
- uint8_t **config_data, int *config_len,
libxl_domain_config *d_config)
{
@@ -1787,13 +1770,10 @@ static int handle_domain_death(uint32_t *r_domid,
break;
case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
- reload_domain_config(*r_domid, config_data, config_len);
restart = 2;
break;
case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
- reload_domain_config(*r_domid, config_data, config_len);
-
restart = 1;
/* fall-through */
case LIBXL_ACTION_ON_SHUTDOWN_DESTROY:
@@ -1990,6 +1970,7 @@ static uint32_t create_domain(struct domain_create *dom_info)
const char *config_source = NULL;
const char *restore_source = NULL;
int migrate_fd = dom_info->migrate_fd;
+ bool config_in_json;
int i;
int need_daemon = daemonize;
@@ -2044,7 +2025,7 @@ static uint32_t create_domain(struct domain_create *dom_info)
restore_source, hdr.mandatory_flags, hdr.optional_flags,
hdr.optional_data_len);
- badflags = hdr.mandatory_flags & ~( 0 /* none understood yet */ );
+ badflags = hdr.mandatory_flags & ~XL_MANDATORY_FLAG_ALL;
if (badflags) {
fprintf(stderr, "Savefile has mandatory flag(s) 0x%"PRIx32" "
"which are not supported; need newer xl\n",
@@ -2072,7 +2053,9 @@ static uint32_t create_domain(struct domain_create *dom_info)
optdata_here = optdata_begin;
if (OPTDATA_LEFT) {
- fprintf(stderr, " Savefile contains xl domain config\n");
+ fprintf(stderr, " Savefile contains xl domain config%s\n",
+ !!(hdr.mandatory_flags & XL_MANDATORY_FLAG_JSON)
+ ? " in JSON format" : "");
WITH_OPTDATA(4, {
memcpy(u32buf.b, optdata_here, 4);
config_len = u32buf.u32;
@@ -2112,6 +2095,7 @@ static uint32_t create_domain(struct domain_create *dom_info)
extra_config);
}
config_source=config_file;
+ config_in_json = false;
} else {
if (!config_data) {
fprintf(stderr, "Config file not specified and"
@@ -2119,12 +2103,23 @@ static uint32_t create_domain(struct domain_create *dom_info)
return ERROR_INVAL;
}
config_source = "<saved>";
+ config_in_json = !!(hdr.mandatory_flags & XL_MANDATORY_FLAG_JSON);
}
if (!dom_info->quiet)
printf("Parsing config from %s\n", config_source);
- parse_config_data(config_source, config_data, config_len, &d_config);
+ if (config_in_json) {
+ char *config_c = config_data;
+ if (config_c[config_len-1] != '\0') {
+ config_c = xrealloc(config_c, config_len + 1);
+ config_c[config_len] = '\0';
+ }
+ libxl_domain_config_from_json(ctx, &d_config,
+ (const char *)config_data);
+ } else {
+ parse_config_data(config_source, config_data, config_len, &d_config);
+ }
if (migrate_fd >= 0) {
if (d_config.c_info.name) {
@@ -2192,12 +2187,35 @@ start:
if ( ret )
goto error_out;
- ret = libxl_userdata_store(ctx, domid, "xl",
- config_data, config_len);
- if (ret) {
- perror("cannot save config file");
- ret = ERROR_FAIL;
- goto error_out;
+ /* If we're doing migration, the domain name was appended with
+ * "--incoming" a few lines above. So we need to remove that
+ * suffix in the stored configuration.
+ */
+ if (migrate_fd >= 0) {
+ libxl_domain_config d;
+ int xlen = strlen("--incoming");
+ int orig_len;
+
+ ret = libxl_load_domain_configuration(ctx, domid, &d);
+ if (ret) {
+ perror("cannot load config data");
+ ret = ERROR_FAIL;
+ goto error_out;
+ }
+
+ orig_len = strlen(d.c_info.name);
+ d.c_info.name = xrealloc(d.c_info.name, orig_len - xlen);
+ d.c_info.name[orig_len - xlen] = 0;
+
+ ret = libxl_store_domain_configuration(ctx, domid, &d);
+ if (ret) {
+ perror("cannot store config data");
+ libxl_domain_config_dispose(&d);
+ ret = ERROR_FAIL;
+ goto error_out;
+ }
+
+ libxl_domain_config_dispose(&d);
}
release_lock();
@@ -2256,9 +2274,7 @@ start:
LOG("Domain %d has shut down, reason code %d 0x%x", domid,
event->u.domain_shutdown.shutdown_reason,
event->u.domain_shutdown.shutdown_reason);
- switch (handle_domain_death(&domid, event,
- (uint8_t **)&config_data, &config_len,
- &d_config)) {
+ switch (handle_domain_death(&domid, event, &d_config)) {
case 2:
if (!preserve_domain(&domid, event, &d_config)) {
/* If we fail then exit leaving the old domain in place. */
@@ -2295,11 +2311,14 @@ start:
d_config.c_info.name = strdup(common_domname);
}
- /* Reparse the configuration in case it has changed */
+ /* Load latest domain configuration */
libxl_domain_config_dispose(&d_config);
- libxl_domain_config_init(&d_config);
- parse_config_data(config_source, config_data, config_len,
- &d_config);
+ ret = libxl_load_domain_configuration(ctx, domid, &d_config);
+ if (ret) {
+ LOG("Failed to load domain configuration (rc=%d)", ret);
+ ret = -1;
+ goto out;
+ }
/*
* XXX FIXME: If this sleep is not there then domain
@@ -3079,9 +3098,7 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
{
libxl_domain_config d_config;
- char *config_source;
- uint8_t *data;
- int i, len, rc;
+ int i, rc;
yajl_gen hand = NULL;
yajl_gen_status s;
@@ -3102,22 +3119,18 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
s = yajl_gen_status_ok;
for (i = 0; i < nb_domain; i++) {
+ libxl_domain_config_init(&d_config);
/* no detailed info available on dom0 */
if (info[i].domid == 0)
continue;
- rc = libxl_userdata_retrieve(ctx, info[i].domid, "xl", &data, &len);
+ rc = libxl_load_domain_configuration(ctx, info[i].domid, &d_config);
if (rc)
continue;
- CHK_SYSCALL(asprintf(&config_source, "<domid %d data>", info[i].domid));
- libxl_domain_config_init(&d_config);
- parse_config_data(config_source, (char *)data, len, &d_config);
if (default_output_format == OUTPUT_FORMAT_JSON)
s = printf_info_one_json(hand, info[i].domid, &d_config);
else
printf_info_sexp(info[i].domid, &d_config);
libxl_domain_config_dispose(&d_config);
- free(data);
- free(config_source);
if (s != yajl_gen_status_ok)
goto out;
}
@@ -3302,22 +3315,41 @@ static void save_domain_core_begin(uint32_t domid,
int *config_len_r)
{
int rc;
+ libxl_domain_config d_config;
+ char *config_c = 0;
/* configuration file in optional data: */
+ libxl_domain_config_init(&d_config);
+
if (override_config_file) {
void *config_v = 0;
rc = libxl_read_file_contents(ctx, override_config_file,
&config_v, config_len_r);
- *config_data_r = config_v;
+ if (rc) {
+ fprintf(stderr, "unable to read overridden config file\n");
+ exit(2);
+ }
+ parse_config_data(override_config_file, config_v, *config_len_r,
+ &d_config);
+ free(config_v);
} else {
- rc = libxl_userdata_retrieve(ctx, domid, "xl",
- config_data_r, config_len_r);
+ rc = libxl_load_domain_configuration(ctx, domid, &d_config);
+ if (rc) {
+ fprintf(stderr, "unable to load domain configuration\n");
+ exit(2);
+ }
}
- if (rc) {
- fputs("Unable to get config file\n",stderr);
+
+ config_c = libxl_domain_config_to_json(ctx, &d_config);
+ if (!config_c) {
+ fprintf(stderr, "unable to parse overridden config file\n");
exit(2);
}
+ *config_data_r = (uint8_t *)config_c;
+ *config_len_r = strlen(config_c);
+
+ libxl_domain_config_dispose(&d_config);
}
static void save_domain_core_writeconfig(int fd, const char *source,
@@ -3345,6 +3377,8 @@ static void save_domain_core_writeconfig(int fd, const char *source,
u32buf.u32 = config_len;
ADD_OPTDATA(u32buf.b, 4);
ADD_OPTDATA(config_data, config_len);
+ if (config_len)
+ hdr.mandatory_flags |= XL_MANDATORY_FLAG_JSON;
/* that's the optional data */
@@ -4418,8 +4452,7 @@ int main_config_update(int argc, char **argv)
if (!dryrun_only) {
fprintf(stderr, "setting dom%d configuration\n", domid);
- rc = libxl_userdata_store(ctx, domid, "xl",
- config_data, config_len);
+ rc = libxl_store_domain_configuration(ctx, domid, &d_config);
if (rc) {
fprintf(stderr, "failed to update configuration\n");
exit(1);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 30/32] libxl: consider force removal of device successful
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (28 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 29/32] xl: use "libxl-json" format Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 14:26 ` Ian Campbell
2014-05-20 15:15 ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 31/32] libxl: update domain configuration when updating memory targets Wei Liu
` (2 subsequent siblings)
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
The current behavior of libxl to remove a device is, if the backend
times out, libxl will initiate a force removal (destroy) of that device.
However, libxl still returns failure in that case, even if the force
removal was successful.
If a device is force removed and the force removal succeeds, from
guest's PoV this device is gone. Libxl should consider this a
successful case as well.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_device.c | 12 ++++++++++--
tools/libxl/libxl_internal.h | 4 ++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index fa99f77..ce0b358 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -845,6 +845,11 @@ void libxl__initiate_device_remove(libxl__egc *egc,
if (rc < 0) goto out;
}
+ /* At this point the XS transaction is committed. So check if we were
+ * force removing the device.
+ */
+ aodev->force_removed = aodev->force;
+
rc = libxl__ev_devstate_wait(gc, &aodev->backend_ds,
device_backend_callback,
state_path, XenbusStateClosed,
@@ -928,7 +933,7 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
return;
}
- if (rc) {
+ if (rc && !aodev->force_removed) {
LOG(ERROR, "unable to %s device with path %s",
libxl__device_action_to_string(aodev->action),
libxl__device_backend_path(gc, aodev->dev));
@@ -939,7 +944,10 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
return;
out:
- aodev->rc = rc;
+ /* If force removal is successful, the device is gone from guest's
+ * PoV. Libxl should return success, too.
+ */
+ aodev->rc = aodev->force_removed ? 0 : rc;
device_hotplug_done(egc, aodev);
return;
}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 89bbf7d..21bb774 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2086,6 +2086,10 @@ struct libxl__ao_device {
libxl__device_action action;
libxl__device *dev;
int force;
+ /* If force removal is successful, force_removed=1. The device is
+ * gone from guest's PoV
+ */
+ int force_removed;
libxl__device_callback *callback;
/* return value, zeroed by user on entry, is valid on callback */
int rc;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (29 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 30/32] libxl: consider force removal of device successful Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 14:32 ` Ian Campbell
2014-05-20 15:21 ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device Wei Liu
2014-05-21 10:18 ` [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Ian Campbell
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index b578a5c..f93096b 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -3529,6 +3529,25 @@ out:
/******************************************************************************/
+/* Macro to load / store domain configuration. They must use in pair.
+ * Load macro defines d_config that can be used by other code. Store
+ * macro will dispose d_config.
+ */
+#define LOAD_DOMAIN_CONFIG(domid) \
+ libxl_domain_config d_config; \
+ libxl_domain_config_init(&d_config); \
+ rc = libxl_load_domain_configuration(CTX, (domid), &d_config); \
+ if (rc) \
+ goto out; \
+
+#define STORE_DOMAIN_CONFIG(domid) \
+ rc = libxl_store_domain_configuration(CTX, (domid), &d_config); \
+ if (rc) { \
+ libxl_domain_config_dispose(&d_config); \
+ goto out; \
+ } \
+ libxl_domain_config_dispose(&d_config); \
+
/* Macro for defining device remove/destroy functions in a compact way */
/* The following functions are defined:
* libxl_device_disk_remove
@@ -4005,6 +4024,14 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
goto out;
}
+ {
+ LOAD_DOMAIN_CONFIG(domid);
+
+ d_config.b_info.max_memkb = max_memkb;
+
+ STORE_DOMAIN_CONFIG(domid);
+ }
+
rc = 0;
out:
GC_FREE;
@@ -4241,6 +4268,15 @@ out:
if (errno == EAGAIN)
goto retry_transaction;
+ /* Currently Dom0 information is not yet managed by libxl */
+ if (!rc && domid) {
+ LOAD_DOMAIN_CONFIG(domid);
+
+ d_config.b_info.target_memkb = new_target_memkb;
+
+ STORE_DOMAIN_CONFIG(domid);
+ }
+
out_no_transaction:
GC_FREE;
return rc;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (30 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 31/32] libxl: update domain configuration when updating memory targets Wei Liu
@ 2014-05-13 21:54 ` Wei Liu
2014-05-20 14:35 ` Ian Campbell
2014-05-20 15:33 ` Ian Jackson
2014-05-21 10:18 ` [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Ian Campbell
32 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-13 21:54 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
We synchronize domain configuration in the callback, right before we
return to caller. We depends solely on the return value of AO to
determine if AO is successful.
This approach cannot deal with half-baked device state (say, if AO
returns success but for various reasons other parts just fail and we
have some xenstore entries written / resource allocated). However we
cannot make thing worse as the original code cannot handle that either.
The good side of this approach is that in the future we can compare the
stored configuration and xenstore entries to spot any half-baked device
state so it can help fix that issue in the future.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 152 +++++++++++++++++++++++++++++++++++-------
tools/libxl/libxl_internal.h | 2 +
2 files changed, 129 insertions(+), 25 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index f93096b..a7bf0a4 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1794,29 +1794,6 @@ out:
/******************************************************************************/
-/* generic callback for devices that only need to set ao_complete */
-static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
-{
- STATE_AO_GC(aodev->ao);
-
- if (aodev->rc) {
- if (aodev->dev) {
- LOG(ERROR, "unable to %s %s with id %u",
- libxl__device_action_to_string(aodev->action),
- libxl__device_kind_to_string(aodev->dev->kind),
- aodev->dev->devid);
- } else {
- LOG(ERROR, "unable to %s device",
- libxl__device_action_to_string(aodev->action));
- }
- goto out;
- }
-
-out:
- libxl__ao_complete(egc, ao, aodev->rc);
- return;
-}
-
/* common function to get next device id */
static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
{
@@ -3548,6 +3525,126 @@ out:
} \
libxl_domain_config_dispose(&d_config); \
+static void device_nic_fixup(libxl_ctx *ctx, libxl_device_nic *dst,
+ libxl_device_nic *src)
+{
+ dst->devid = src->devid;
+ libxl_mac_copy(ctx, &dst->mac, &src->mac);
+}
+
+static void device_vtpm_fixup(libxl_ctx *ctx, libxl_device_vtpm *dst,
+ libxl_device_vtpm *src)
+{
+ libxl_uuid_copy(ctx, &dst->uuid, &src->uuid);
+}
+
+static void device_disk_fixup(libxl_ctx *ctx, libxl_device_disk *dst,
+ libxl_device_disk *src)
+{
+}
+
+#define DEVICE_AO_FAILED_MSG \
+ do { \
+ if (aodev->dev) { \
+ LOG(ERROR, "unable to %s %s with id %u", \
+ libxl__device_action_to_string(aodev->action), \
+ libxl__device_kind_to_string(aodev->dev->kind), \
+ aodev->dev->devid); \
+ } else { \
+ LOG(ERROR, "unable to %s device", \
+ libxl__device_action_to_string(aodev->action)); \
+ } \
+ } while (0)
+
+
+#define DEFINE_DEVICE_ADD_AOCOMPLETE(type,ptr,cnt) \
+ static void device_add_##type##_aocomplete(libxl__egc *egc, \
+ libxl__ao_device *aodev) \
+ { \
+ STATE_AO_GC(aodev->ao); \
+ int rc; \
+ \
+ if (aodev->rc) { \
+ DEVICE_AO_FAILED_MSG; \
+ goto out; \
+ } else { \
+ libxl_device_##type *p; \
+ \
+ LOAD_DOMAIN_CONFIG(aodev->dev->domid); \
+ \
+ d_config.ptr = \
+ libxl__realloc(gc, d_config.ptr, \
+ (d_config.cnt + 1) * \
+ sizeof(libxl_device_##type)); \
+ p = &d_config.ptr[d_config.cnt]; \
+ d_config.cnt++; \
+ \
+ libxl_device_##type##_copy(CTX, p, aodev->pdev_copy); \
+ \
+ device_##type##_fixup(CTX, p, aodev->pdev); \
+ \
+ STORE_DOMAIN_CONFIG(aodev->dev->domid); \
+ } \
+ \
+ out: \
+ /* Dispose our internal copy, which is allocated at the entry of \
+ * this AO. */ \
+ libxl_device_##type##_dispose(aodev->pdev_copy); \
+ libxl__ao_complete(egc, ao, aodev->rc); \
+ return; \
+ }
+
+DEFINE_DEVICE_ADD_AOCOMPLETE(nic, nics, num_nics);
+DEFINE_DEVICE_ADD_AOCOMPLETE(vtpm, vtpms, num_vtpms);
+DEFINE_DEVICE_ADD_AOCOMPLETE(disk, disks, num_disks);
+
+#define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
+#define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
+
+#define DEFINE_DEVICE_RM_AOCOMPLETE(type,ptr,cnt,compare) \
+ static void device_rm_##type##_aocomplete(libxl__egc *egc, \
+ libxl__ao_device *aodev) \
+ { \
+ STATE_AO_GC(aodev->ao); \
+ int rc; \
+ \
+ if (aodev->rc) { \
+ DEVICE_AO_FAILED_MSG; \
+ goto out; \
+ } else { \
+ int i, j; \
+ libxl_device_##type *p = aodev->pdev; \
+ LOAD_DOMAIN_CONFIG(aodev->dev->domid); \
+ \
+ for (i = j = 0; i < d_config.cnt; i++) { \
+ if (!compare(&d_config.ptr[i], p)) { \
+ if (i != j) { \
+ libxl_device_##type##_dispose(&d_config.ptr[j]);\
+ d_config.ptr[j] = d_config.ptr[i]; \
+ } \
+ j++; \
+ } \
+ } \
+ \
+ d_config.ptr = \
+ libxl__realloc(gc, d_config.ptr, \
+ j * sizeof(libxl_device_##type)); \
+ d_config.cnt = j; \
+ \
+ STORE_DOMAIN_CONFIG(aodev->dev->domid); \
+ } \
+ \
+ out: \
+ libxl__ao_complete(egc, ao, aodev->rc); \
+ return; \
+ }
+
+DEFINE_DEVICE_RM_AOCOMPLETE(nic, nics, num_nics, COMPARE_DEVID);
+DEFINE_DEVICE_RM_AOCOMPLETE(vtpm, vtpms, num_vtpms, COMPARE_DEVID);
+DEFINE_DEVICE_RM_AOCOMPLETE(disk, disks, num_disks, COMPARE_DISK);
+DEFINE_DEVICE_RM_AOCOMPLETE(vkb, vkbs, num_vkbs, COMPARE_DEVID);
+DEFINE_DEVICE_RM_AOCOMPLETE(vfb, vfbs, num_vfbs, COMPARE_DEVID);
+
/* Macro for defining device remove/destroy functions in a compact way */
/* The following functions are defined:
* libxl_device_disk_remove
@@ -3577,9 +3674,11 @@ out:
\
GCNEW(aodev); \
libxl__prepare_ao_device(ao, aodev); \
+ aodev->pdev = type; \
+ aodev->pdev_copy = NULL; /* unused */ \
aodev->action = LIBXL__DEVICE_ACTION_REMOVE; \
aodev->dev = device; \
- aodev->callback = device_addrm_aocomplete; \
+ aodev->callback = device_rm_##type##_aocomplete; \
aodev->force = f; \
libxl__initiate_device_remove(egc, aodev); \
\
@@ -3631,8 +3730,11 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
libxl__ao_device *aodev; \
\
GCNEW(aodev); \
+ aodev->pdev = type; \
+ aodev->pdev_copy = libxl__zalloc(gc, sizeof(*type)); \
+ libxl_device_##type##_copy(CTX, aodev->pdev_copy, aodev->pdev); \
libxl__prepare_ao_device(ao, aodev); \
- aodev->callback = device_addrm_aocomplete; \
+ aodev->callback = device_add_##type##_aocomplete; \
libxl__device_##type##_add(egc, domid, type, aodev); \
\
return AO_INPROGRESS; \
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 21bb774..06503df 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2106,6 +2106,8 @@ struct libxl__ao_device {
const char *what;
int num_exec;
libxl__ev_child child;
+ void *pdev; /* pointer to libxl_device_nic/vtpm/disk etc. */
+ void *pdev_copy; /* a copy of vanilla structure pointed to by pdev. */
};
/*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-13 21:53 ` [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning " Wei Liu
@ 2014-05-15 0:59 ` Dario Faggioli
2014-05-15 9:24 ` Wei Liu
2014-05-15 16:45 ` Ian Campbell
1 sibling, 1 reply; 127+ messages in thread
From: Dario Faggioli @ 2014-05-15 0:59 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, ian.campbell, xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 2847 bytes --]
On mar, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> This patch introduces a key value list called "vcpu_affinity" in libxl
> IDL to preserve VCPU to PCPU mapping. This is necessary for libxl to
> preserve all information to construct a domain.
>
> Also define LIBXL_HAVE_AFFINITY_KEY_VALUE_LIST in libxl.h to mark the
> change in API.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
>
Reviewed-and-Tested-by: Dario Faggioli <dario.faggioli@citrix.com>
One question: I've skimmed through the rest of the series, and it looks
like you are not doing anything particular with the other maps, already
existing in b_info (cpumap and nodemap) yet, is that right?
Also, a very minor comment on the code...
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 661999c..b818815 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
>
> + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> + if (d_config->b_info.vcpu_affinity) {
> + int i;
> + libxl_bitmap vcpu_cpumap;
> + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> +
> + vcpu_to_pcpu = libxl__zalloc(gc, sz);
> + memset(vcpu_to_pcpu, -1, sz);
> +
> + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> + const char *key, *val;
> + int k, v;
> +
> + key = kvl[i * 2];
> + if (!key)
> + break;
> + val = kvl[i * 2 + 1];
> +
> + k = atoi(key);
> + v = atoi(val);
> + vcpu_to_pcpu[k] = v;
> + }
> +
> + rc = libxl_cpu_bitmap_alloc(ctx, &vcpu_cpumap, 0);
> + if (rc) {
> + libxl_bitmap_dispose(&vcpu_cpumap);
> + return ERROR_FAIL;
> + }
> +
Perhaps you can move this up, i.e., try the allocation first so that, if
it fails, you can bail before getting into decoding the key/value list?
Also, if libxl_cpu_bitmap_alloc() fails, do you really have to call
libxl_bitmap_dispose()? I thought not.
Anyway, as said, these both are minor issues. Just give them a thought
if you respin the series but, if not, the patch is fine as it is for me.
Regards,
Dario
--
<<This happens because I choose it to happen!>> (Raistlin Majere)
-----------------------------------------------------------------
Dario Faggioli, Ph.D, http://about.me/dario.faggioli
Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 0:59 ` Dario Faggioli
@ 2014-05-15 9:24 ` Wei Liu
2014-05-15 15:31 ` Dario Faggioli
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-15 9:24 UTC (permalink / raw)
To: Dario Faggioli; +Cc: ian.jackson, Wei Liu, ian.campbell, xen-devel
On Thu, May 15, 2014 at 02:59:13AM +0200, Dario Faggioli wrote:
> On mar, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > This patch introduces a key value list called "vcpu_affinity" in libxl
> > IDL to preserve VCPU to PCPU mapping. This is necessary for libxl to
> > preserve all information to construct a domain.
> >
> > Also define LIBXL_HAVE_AFFINITY_KEY_VALUE_LIST in libxl.h to mark the
> > change in API.
> >
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> > Cc: Dario Faggioli <dario.faggioli@citrix.com>
> >
> Reviewed-and-Tested-by: Dario Faggioli <dario.faggioli@citrix.com>
>
Thanks.
> One question: I've skimmed through the rest of the series, and it looks
> like you are not doing anything particular with the other maps, already
> existing in b_info (cpumap and nodemap) yet, is that right?
>
Correct. I found out it's not necessary to touch them.
> Also, a very minor comment on the code...
>
> > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> > index 661999c..b818815 100644
> > --- a/tools/libxl/libxl_dom.c
> > +++ b/tools/libxl/libxl_dom.c
> > @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> > libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> > libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
> >
> > + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> > + if (d_config->b_info.vcpu_affinity) {
> > + int i;
> > + libxl_bitmap vcpu_cpumap;
> > + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> > +
> > + vcpu_to_pcpu = libxl__zalloc(gc, sz);
> > + memset(vcpu_to_pcpu, -1, sz);
> > +
> > + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> > + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> > + const char *key, *val;
> > + int k, v;
> > +
> > + key = kvl[i * 2];
> > + if (!key)
> > + break;
> > + val = kvl[i * 2 + 1];
> > +
> > + k = atoi(key);
> > + v = atoi(val);
> > + vcpu_to_pcpu[k] = v;
> > + }
> > +
> > + rc = libxl_cpu_bitmap_alloc(ctx, &vcpu_cpumap, 0);
> > + if (rc) {
> > + libxl_bitmap_dispose(&vcpu_cpumap);
> > + return ERROR_FAIL;
> > + }
> > +
> Perhaps you can move this up, i.e., try the allocation first so that, if
> it fails, you can bail before getting into decoding the key/value list?
>
That's more or less a personal taste...
> Also, if libxl_cpu_bitmap_alloc() fails, do you really have to call
> libxl_bitmap_dispose()? I thought not.
>
The paradigm of using libxl_type is to always call dispose.
Wei.
> Anyway, as said, these both are minor issues. Just give them a thought
> if you respin the series but, if not, the patch is fine as it is for me.
>
> Regards,
> Dario
>
> --
> <<This happens because I choose it to happen!>> (Raistlin Majere)
> -----------------------------------------------------------------
> Dario Faggioli, Ph.D, http://about.me/dario.faggioli
> Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 9:24 ` Wei Liu
@ 2014-05-15 15:31 ` Dario Faggioli
2014-05-15 15:37 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Dario Faggioli @ 2014-05-15 15:31 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, ian.campbell, xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 2805 bytes --]
On gio, 2014-05-15 at 10:24 +0100, Wei Liu wrote:
> > One question: I've skimmed through the rest of the series, and it looks
> > like you are not doing anything particular with the other maps, already
> > existing in b_info (cpumap and nodemap) yet, is that right?
> >
>
> Correct. I found out it's not necessary to touch them.
>
Great! I looked at the code and gave it a quick try and came to similar
conclusions.
> > > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> > > index 661999c..b818815 100644
> > > --- a/tools/libxl/libxl_dom.c
> > > +++ b/tools/libxl/libxl_dom.c
> > > @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> > > libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> > > libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
> > >
> > > + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> > > + if (d_config->b_info.vcpu_affinity) {
> > > + int i;
> > > + libxl_bitmap vcpu_cpumap;
> > > + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> > > +
> > > + vcpu_to_pcpu = libxl__zalloc(gc, sz);
> > > + memset(vcpu_to_pcpu, -1, sz);
> > > +
> > > + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> > > + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> > > + const char *key, *val;
> > > + int k, v;
> > > +
> > > + key = kvl[i * 2];
> > > + if (!key)
> > > + break;
> > > + val = kvl[i * 2 + 1];
> > > +
> > > + k = atoi(key);
> > > + v = atoi(val);
> > > + vcpu_to_pcpu[k] = v;
> > > + }
> > > +
> > > + rc = libxl_cpu_bitmap_alloc(ctx, &vcpu_cpumap, 0);
> > > + if (rc) {
> > > + libxl_bitmap_dispose(&vcpu_cpumap);
> > > + return ERROR_FAIL;
> > > + }
> > > +
> > Perhaps you can move this up, i.e., try the allocation first so that, if
> > it fails, you can bail before getting into decoding the key/value list?
> >
>
> That's more or less a personal taste...
>
Indeed it is.
Regards,
Dario
> > Also, if libxl_cpu_bitmap_alloc() fails, do you really have to call
> > libxl_bitmap_dispose()? I thought not.
> >
>
> The paradigm of using libxl_type is to always call dispose.
>
Alright, according to that same usage paradigm, aren't you missing an
libxl_bitmap_init(&vcpu_cpumap) then?
Regards,
Dario
--
<<This happens because I choose it to happen!>> (Raistlin Majere)
-----------------------------------------------------------------
Dario Faggioli, Ph.D, http://about.me/dario.faggioli
Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 15:31 ` Dario Faggioli
@ 2014-05-15 15:37 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-15 15:37 UTC (permalink / raw)
To: Dario Faggioli; +Cc: ian.jackson, Wei Liu, ian.campbell, xen-devel
On Thu, May 15, 2014 at 05:31:02PM +0200, Dario Faggioli wrote:
[...]
> >
> > The paradigm of using libxl_type is to always call dispose.
> >
> Alright, according to that same usage paradigm, aren't you missing an
> libxl_bitmap_init(&vcpu_cpumap) then?
>
I suppose so -- only that libxl_bitmap_init doens't do any practical
thing I managed to get by. I will add it.
Wei.
> Regards,
> Dario
>
> --
> <<This happens because I choose it to happen!>> (Raistlin Majere)
> -----------------------------------------------------------------
> Dario Faggioli, Ph.D, http://about.me/dario.faggioli
> Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function
2014-05-13 21:53 ` [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function Wei Liu
@ 2014-05-15 16:28 ` Ian Campbell
2014-05-20 14:47 ` Ian Jackson
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-15 16:28 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
I'm unsure whether additions to libxl_utils.h should have a
corresponding #define LIBXL_HAVE.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl
2014-05-13 21:53 ` [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl Wei Liu
@ 2014-05-15 16:38 ` Ian Campbell
2014-05-15 17:11 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-15 16:38 UTC (permalink / raw)
To: Wei Liu
Cc: Daniel De Graaf, Dario Faggioli, ian.jackson, Juergen Gross,
xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> @@ -619,6 +625,11 @@ static int cpupool_info(libxl__gc *gc,
> }
>
> info->poolid = xcinfo->cpupool_id;
> + info->pool_name = libxl_cpupoolid_to_name(CTX, info->poolid);
> + if (!info->pool_name) {
> + rc = ERROR_NOMEM;
libxl_cpupooid_to_name also fails if the pool doesn't exist. ERROR_FAIL
might be more appropriate?
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index 84f9c0e..2b06094 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -469,6 +469,30 @@
> #define LIBXL_EXTERNAL_CALLERS_ONLY /* disappears for callers outside libxl */
> #endif
>
> +/*
> + * LIBXL_HAVE_SSID_LABEL
> + *
> + * If this is defined, then libxl IDL contains string of XSM security
> + * label in all XSM related structures.
> + *
> + * If this string is not NULL, libxl will overwrite the numeric
> + * representation of this configuration regardless if it has been
> + * set by the caller, because libxl will do the parsing by itself.
A more natural to say this would be:
"If set this string takes precedence over the numeric field"
I think...
> + */
> +#define LIBXL_HAVE_SSID_LABEL 1
> +
> +/*
> + * LIBXL_HAVE_CPUPOOL_NAME
> + *
> + * If this is defined, then libxl IDL contains string of CPU pool
> + * name in all CPU pool related structures.
> + *
> + * If this string is not NULL, libxl will overwrite the numeric
> + * representation of this configuration regardless if it has been
> + * set by the caller, because libxl will do the parsing by itself.
Similarly.
> + */
> +#define LIBXL_HAVE_CPUPOOL_NAME 1
> +
> typedef uint8_t libxl_mac[6];
> #define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
> #define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index d015cf4..fe3bdd2 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -724,6 +724,63 @@ static void initiate_domain_create(libxl__egc *egc,
>
> domid = 0;
>
> + if (d_config->c_info.ssid_label) {
> + char *s = d_config->c_info.ssid_label;
> + ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
> + &d_config->c_info.ssidref);
> + if (ret) {
> + if (errno == ENOSYS) {
> + LOG(WARN, "XSM Disabled: init_seclabel not supported");
Should you set ssidref to the explicit invalid value here? I suppose it
isn't going to matter much?
> + ret = 0;
> + } else {
> + LOG(ERROR, "Invalid init_seclabel: %s", s);
> + goto error_out;
> + }
> + }
> + }
> +
> + if (d_config->b_info.exec_ssid_label) {
> + char *s = d_config->b_info.exec_ssid_label;
> + ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
> + &d_config->b_info.exec_ssidref);
> + if (ret) {
> + if (errno == ENOSYS) {
> + LOG(WARN, "XSM Disabled: seclabel not supported");
Same Again.
> + ret = 0;
> + } else {
> + LOG(ERROR, "Invalid seclabel: %s", s);
> + goto error_out;
> + }
> + }
> + }
> +
> + if (d_config->b_info.device_model_ssid_label) {
> + char *s = d_config->b_info.device_model_ssid_label;
> + ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
> + &d_config->b_info.device_model_ssidref);
> + if (ret) {
> + if (errno == ENOSYS) {
> + LOG(WARN,"XSM Disabled: device_model_stubdomain_seclabel not supported");
Again.
> + ret = 0;
> + } else {
> + LOG(ERROR, "Invalid device_model_stubdomain_seclabel: %s", s);
> + goto error_out;
> + }
> + }
> + }
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-13 21:53 ` [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning " Wei Liu
2014-05-15 0:59 ` Dario Faggioli
@ 2014-05-15 16:45 ` Ian Campbell
2014-05-15 17:06 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-15 16:45 UTC (permalink / raw)
To: Wei Liu; +Cc: Dario Faggioli, ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 0dfafe7..7b0901c 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -305,6 +305,7 @@ libxl_domain_build_info =
Struct("domain_build_info",[
> ("avail_vcpus", libxl_bitmap),
> ("cpumap", libxl_bitmap),
> ("nodemap", libxl_bitmap),
> + ("vcpu_affinity", libxl_key_value_list),
>
Is a key value list really the best way to represent this? At first
glance it seems like an array would be more suitable?
I've glanced through the rest on the assumption you have a convincing
reason why it should be a kvp list.
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 661999c..b818815 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
>
> + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> + if (d_config->b_info.vcpu_affinity) {
> + int i;
> + libxl_bitmap vcpu_cpumap;
> + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> +
> + vcpu_to_pcpu = libxl__zalloc(gc, sz);
In theory this could be a stack allocation, either with alloca or just
int vcpu_to_pcpu[sz];
> + memset(vcpu_to_pcpu, -1, sz);
> +
> + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> + const char *key, *val;
> + int k, v;
> +
> + key = kvl[i * 2];
Need to bounds check kvl here. I think you might be better off iterating
over the kvl and validating the k against max_vcpus.
> ("numa_placement", libxl_defbool),
> ("tsc_mode", libxl_tsc_mode),
> ("max_memkb", MemKB),
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index a1cb5b8..3200d40 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -88,9 +88,6 @@ xlchild children[child_max];
> static const char *common_domname;
> static int fd_lock = -1;
>
> -/* Stash for specific vcpu to pcpu mappping */
mappppppping.
> @@ -833,11 +823,30 @@ static void parse_config_data(const char *config_source,
> exit(1);
> }
> libxl_bitmap_set(&b_info->cpumap, i);
> - if (n_cpus < b_info->max_vcpus)
> - vcpu_to_pcpu[n_cpus] = i;
> + if (n_cpus < b_info->max_vcpus) {
> + kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 2));
Can't you get the length of the input list and just allocate the right
size to start with?
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-13 21:53 ` [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument Wei Liu
@ 2014-05-15 16:51 ` Ian Campbell
2014-05-15 17:13 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-15 16:51 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> @@ -82,7 +82,7 @@ int libxl_uuid_from_string(libxl_uuid *uuid, const char *in)
> }
> #undef LIBXL__UUID_PTRS
>
> -void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src)
> +void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src)
Since you might get NULL here I think all these ctx params should be
called ctx_unused or something, in case someone thinks they can use it.
Alternatively ctx_opt to indicate that it is optional and that care must
be taken if using it.
> {
> memcpy(dst->uuid, src->uuid, sizeof(dst->uuid));
> }
> diff --git a/tools/libxl/libxl_uuid.h b/tools/libxl/libxl_uuid.h
> index 93c65a7..37c4d5f 100644
> --- a/tools/libxl/libxl_uuid.h
> +++ b/tools/libxl/libxl_uuid.h
> @@ -53,10 +53,15 @@ typedef struct {
>
> #endif
>
> +typedef struct libxl__ctx libxl_ctx;
Maybe libxl_uuid.h should include libxl.h?
> int libxl_uuid_is_nil(libxl_uuid *uuid);
> void libxl_uuid_generate(libxl_uuid *uuid);
> int libxl_uuid_from_string(libxl_uuid *uuid, const char *in);
> -void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src);
> +void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src);
> +#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x040500
You need to add 0x040500 to the list of valid versions in libxl.h
> +void libxl_uuid_copy(dst, src) libxl_uuid_copy(NULL, dst, src)
> +#endif
> +
> void libxl_uuid_clear(libxl_uuid *uuid);
> int libxl_uuid_compare(libxl_uuid *uuid1, libxl_uuid *uuid2);
> uint8_t *libxl_uuid_bytearray(libxl_uuid *uuid);
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 16:45 ` Ian Campbell
@ 2014-05-15 17:06 ` Wei Liu
2014-05-15 17:19 ` Wei Liu
` (2 more replies)
0 siblings, 3 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-15 17:06 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Dario Faggioli, Wei Liu, xen-devel
On Thu, May 15, 2014 at 05:45:19PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
>
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> > index 0dfafe7..7b0901c 100644
> > --- a/tools/libxl/libxl_types.idl
> > +++ b/tools/libxl/libxl_types.idl
> > @@ -305,6 +305,7 @@ libxl_domain_build_info =
> Struct("domain_build_info",[
> > ("avail_vcpus", libxl_bitmap),
> > ("cpumap", libxl_bitmap),
> > ("nodemap", libxl_bitmap),
> > + ("vcpu_affinity", libxl_key_value_list),
> >
> Is a key value list really the best way to represent this? At first
> glance it seems like an array would be more suitable?
>
> I've glanced through the rest on the assumption you have a convincing
> reason why it should be a kvp list.
>
How can you effectively skip pinning a VCPU if it's an array? I can have
[ '0': '1', '3': '3' ] in KVL, but not able to represent it in an array
[ '1', ?, ?, '3' ].
> > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> > index 661999c..b818815 100644
> > --- a/tools/libxl/libxl_dom.c
> > +++ b/tools/libxl/libxl_dom.c
> > @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> > libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> > libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
> >
> > + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> > + if (d_config->b_info.vcpu_affinity) {
> > + int i;
> > + libxl_bitmap vcpu_cpumap;
> > + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> > +
> > + vcpu_to_pcpu = libxl__zalloc(gc, sz);
>
> In theory this could be a stack allocation, either with alloca or just
> int vcpu_to_pcpu[sz];
>
I would rather avoid dynamic-size stack allocation, bacause
"The alloca() function returns a pointer to the beginning of the
allocated space. If the allocation causes stack overflow,
program behavior is undefined."
> > + memset(vcpu_to_pcpu, -1, sz);
> > +
> > + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> > + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> > + const char *key, *val;
> > + int k, v;
> > +
> > + key = kvl[i * 2];
>
> Need to bounds check kvl here. I think you might be better off iterating
> over the kvl and validating the k against max_vcpus.
>
The next line is "bound-checking".
> > ("numa_placement", libxl_defbool),
> > ("tsc_mode", libxl_tsc_mode),
> > ("max_memkb", MemKB),
> > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> > index a1cb5b8..3200d40 100644
> > --- a/tools/libxl/xl_cmdimpl.c
> > +++ b/tools/libxl/xl_cmdimpl.c
> > @@ -88,9 +88,6 @@ xlchild children[child_max];
> > static const char *common_domname;
> > static int fd_lock = -1;
> >
> > -/* Stash for specific vcpu to pcpu mappping */
>
> mappppppping.
I'm deleting this line. :-)
> > @@ -833,11 +823,30 @@ static void parse_config_data(const char *config_source,
> > exit(1);
> > }
> > libxl_bitmap_set(&b_info->cpumap, i);
> > - if (n_cpus < b_info->max_vcpus)
> > - vcpu_to_pcpu[n_cpus] = i;
> > + if (n_cpus < b_info->max_vcpus) {
> > + kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 2));
>
> Can't you get the length of the input list and just allocate the right
> size to start with?
>
That introduces extra overhead. Say if you have 32 VCPU but only want to
pin a few.
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl
2014-05-15 16:38 ` Ian Campbell
@ 2014-05-15 17:11 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-15 17:11 UTC (permalink / raw)
To: Ian Campbell
Cc: Wei Liu, Dario Faggioli, ian.jackson, xen-devel, Daniel De Graaf,
Juergen Gross
On Thu, May 15, 2014 at 05:38:05PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > @@ -619,6 +625,11 @@ static int cpupool_info(libxl__gc *gc,
> > }
> >
> > info->poolid = xcinfo->cpupool_id;
> > + info->pool_name = libxl_cpupoolid_to_name(CTX, info->poolid);
> > + if (!info->pool_name) {
> > + rc = ERROR_NOMEM;
>
> libxl_cpupooid_to_name also fails if the pool doesn't exist. ERROR_FAIL
> might be more appropriate?
OK.
> > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> > index 84f9c0e..2b06094 100644
> > --- a/tools/libxl/libxl.h
> > +++ b/tools/libxl/libxl.h
> > @@ -469,6 +469,30 @@
> > #define LIBXL_EXTERNAL_CALLERS_ONLY /* disappears for callers outside libxl */
> > #endif
> >
> > +/*
> > + * LIBXL_HAVE_SSID_LABEL
> > + *
> > + * If this is defined, then libxl IDL contains string of XSM security
> > + * label in all XSM related structures.
> > + *
> > + * If this string is not NULL, libxl will overwrite the numeric
> > + * representation of this configuration regardless if it has been
> > + * set by the caller, because libxl will do the parsing by itself.
>
> A more natural to say this would be:
>
> "If set this string takes precedence over the numeric field"
>
> I think...
>
OK.
> > + */
> > +#define LIBXL_HAVE_SSID_LABEL 1
> > +
> > +/*
> > + * LIBXL_HAVE_CPUPOOL_NAME
> > + *
> > + * If this is defined, then libxl IDL contains string of CPU pool
> > + * name in all CPU pool related structures.
> > + *
> > + * If this string is not NULL, libxl will overwrite the numeric
> > + * representation of this configuration regardless if it has been
> > + * set by the caller, because libxl will do the parsing by itself.
>
> Similarly.
>
> > + */
> > +#define LIBXL_HAVE_CPUPOOL_NAME 1
> > +
> > typedef uint8_t libxl_mac[6];
> > #define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
> > #define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
> > diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> > index d015cf4..fe3bdd2 100644
> > --- a/tools/libxl/libxl_create.c
> > +++ b/tools/libxl/libxl_create.c
> > @@ -724,6 +724,63 @@ static void initiate_domain_create(libxl__egc *egc,
> >
> > domid = 0;
> >
> > + if (d_config->c_info.ssid_label) {
> > + char *s = d_config->c_info.ssid_label;
> > + ret = libxl_flask_context_to_sid(ctx, s, strlen(s),
> > + &d_config->c_info.ssidref);
> > + if (ret) {
> > + if (errno == ENOSYS) {
> > + LOG(WARN, "XSM Disabled: init_seclabel not supported");
>
> Should you set ssidref to the explicit invalid value here? I suppose it
> isn't going to matter much?
>
I don't think so. Nobody should try to make sense out of ssidref if XSM
is disabled anyway. And I really have no idea what is the "invalid
value" for ssidref.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-15 16:51 ` Ian Campbell
@ 2014-05-15 17:13 ` Wei Liu
2014-05-16 9:46 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-15 17:13 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Thu, May 15, 2014 at 05:51:07PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > @@ -82,7 +82,7 @@ int libxl_uuid_from_string(libxl_uuid *uuid, const char *in)
> > }
> > #undef LIBXL__UUID_PTRS
> >
> > -void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src)
> > +void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src)
>
> Since you might get NULL here I think all these ctx params should be
> called ctx_unused or something, in case someone thinks they can use it.
>
> Alternatively ctx_opt to indicate that it is optional and that care must
> be taken if using it.
>
OK.
> > {
> > memcpy(dst->uuid, src->uuid, sizeof(dst->uuid));
> > }
> > diff --git a/tools/libxl/libxl_uuid.h b/tools/libxl/libxl_uuid.h
> > index 93c65a7..37c4d5f 100644
> > --- a/tools/libxl/libxl_uuid.h
> > +++ b/tools/libxl/libxl_uuid.h
> > @@ -53,10 +53,15 @@ typedef struct {
> >
> > #endif
> >
> > +typedef struct libxl__ctx libxl_ctx;
>
> Maybe libxl_uuid.h should include libxl.h?
>
That leads to circular inclusion.
> > int libxl_uuid_is_nil(libxl_uuid *uuid);
> > void libxl_uuid_generate(libxl_uuid *uuid);
> > int libxl_uuid_from_string(libxl_uuid *uuid, const char *in);
> > -void libxl_uuid_copy(libxl_uuid *dst, const libxl_uuid *src);
> > +void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src);
> > +#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x040500
>
> You need to add 0x040500 to the list of valid versions in libxl.h
>
OK.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 17:06 ` Wei Liu
@ 2014-05-15 17:19 ` Wei Liu
2014-05-16 9:51 ` Ian Campbell
2014-05-16 8:10 ` Dario Faggioli
2014-05-16 9:57 ` Ian Campbell
2 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-15 17:19 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Dario Faggioli, Wei Liu, xen-devel
On Thu, May 15, 2014 at 06:06:50PM +0100, Wei Liu wrote:
[...]
> > > @@ -833,11 +823,30 @@ static void parse_config_data(const char *config_source,
> > > exit(1);
> > > }
> > > libxl_bitmap_set(&b_info->cpumap, i);
> > > - if (n_cpus < b_info->max_vcpus)
> > > - vcpu_to_pcpu[n_cpus] = i;
> > > + if (n_cpus < b_info->max_vcpus) {
> > > + kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 2));
> >
> > Can't you get the length of the input list and just allocate the right
> > size to start with?
> >
>
> That introduces extra overhead. Say if you have 32 VCPU but only want to
> pin a few.
>
I misread this one. I think you're right. But how can I can the length
of this list? Could not find an appropriate API. I guess I need to do it
myself?
Wei.
> Wei.
>
> > Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 17:06 ` Wei Liu
2014-05-15 17:19 ` Wei Liu
@ 2014-05-16 8:10 ` Dario Faggioli
2014-05-16 9:57 ` Ian Campbell
2 siblings, 0 replies; 127+ messages in thread
From: Dario Faggioli @ 2014-05-16 8:10 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, Ian Campbell, xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 1699 bytes --]
On gio, 2014-05-15 at 18:06 +0100, Wei Liu wrote:
> On Thu, May 15, 2014 at 05:45:19PM +0100, Ian Campbell wrote:
> > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> >
> > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> > > index 0dfafe7..7b0901c 100644
> > > --- a/tools/libxl/libxl_types.idl
> > > +++ b/tools/libxl/libxl_types.idl
> > > @@ -305,6 +305,7 @@ libxl_domain_build_info =
> > Struct("domain_build_info",[
> > > ("avail_vcpus", libxl_bitmap),
> > > ("cpumap", libxl_bitmap),
> > > ("nodemap", libxl_bitmap),
> > > + ("vcpu_affinity", libxl_key_value_list),
> > >
> > Is a key value list really the best way to represent this? At first
> > glance it seems like an array would be more suitable?
> >
> > I've glanced through the rest on the assumption you have a convincing
> > reason why it should be a kvp list.
> >
>
> How can you effectively skip pinning a VCPU if it's an array? I can have
> [ '0': '1', '3': '3' ] in KVL, but not able to represent it in an array
> [ '1', ?, ?, '3' ].
>
I think I agree with Wei.
When everything was in xl, an array is what was being used, marking with
'-1' (IIRC) the spots of not-to-be-pinned vcpus.
Now that we're passing the info to libxl, that would mean always passing
an array of max_vcpus elements, even if the to-be-pinned vcpus are only
2 or 3.
Regards,
Dario
--
<<This happens because I choose it to happen!>> (Raistlin Majere)
-----------------------------------------------------------------
Dario Faggioli, Ph.D, http://about.me/dario.faggioli
Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-15 17:13 ` Wei Liu
@ 2014-05-16 9:46 ` Ian Campbell
2014-05-16 10:18 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 9:46 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Thu, 2014-05-15 at 18:13 +0100, Wei Liu wrote:
> > > +typedef struct libxl__ctx libxl_ctx;
> >
> > Maybe libxl_uuid.h should include libxl.h?
> >
>
> That leads to circular inclusion.
Do the #define guards not solve that?
Or do you mean that libxl.h's include of libxl_uuid.h might be before
libxl_ctx is typedefd?
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 17:19 ` Wei Liu
@ 2014-05-16 9:51 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 9:51 UTC (permalink / raw)
To: Wei Liu; +Cc: Dario Faggioli, ian.jackson, xen-devel
On Thu, 2014-05-15 at 18:19 +0100, Wei Liu wrote:
> On Thu, May 15, 2014 at 06:06:50PM +0100, Wei Liu wrote:
> [...]
> > > > @@ -833,11 +823,30 @@ static void parse_config_data(const char *config_source,
> > > > exit(1);
> > > > }
> > > > libxl_bitmap_set(&b_info->cpumap, i);
> > > > - if (n_cpus < b_info->max_vcpus)
> > > > - vcpu_to_pcpu[n_cpus] = i;
> > > > + if (n_cpus < b_info->max_vcpus) {
> > > > + kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 2));
> > >
> > > Can't you get the length of the input list and just allocate the right
> > > size to start with?
> > >
> >
> > That introduces extra overhead. Say if you have 32 VCPU but only want to
> > pin a few.
> >
>
> I misread this one. I think you're right. But how can I can the length
> of this list? Could not find an appropriate API. I guess I need to do it
> myself?
xlu_cfg_get_list takes int *entries_r.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-15 17:06 ` Wei Liu
2014-05-15 17:19 ` Wei Liu
2014-05-16 8:10 ` Dario Faggioli
@ 2014-05-16 9:57 ` Ian Campbell
2014-05-16 10:15 ` Wei Liu
2 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 9:57 UTC (permalink / raw)
To: Wei Liu; +Cc: Dario Faggioli, ian.jackson, xen-devel
On Thu, 2014-05-15 at 18:06 +0100, Wei Liu wrote:
> On Thu, May 15, 2014 at 05:45:19PM +0100, Ian Campbell wrote:
> > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> >
> > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> > > index 0dfafe7..7b0901c 100644
> > > --- a/tools/libxl/libxl_types.idl
> > > +++ b/tools/libxl/libxl_types.idl
> > > @@ -305,6 +305,7 @@ libxl_domain_build_info =
> > Struct("domain_build_info",[
> > > ("avail_vcpus", libxl_bitmap),
> > > ("cpumap", libxl_bitmap),
> > > ("nodemap", libxl_bitmap),
> > > + ("vcpu_affinity", libxl_key_value_list),
> > >
> > Is a key value list really the best way to represent this? At first
> > glance it seems like an array would be more suitable?
> >
> > I've glanced through the rest on the assumption you have a convincing
> > reason why it should be a kvp list.
> >
>
> How can you effectively skip pinning a VCPU if it's an array? I can have
> [ '0': '1', '3': '3' ] in KVL, but not able to represent it in an array
> [ '1', ?, ?, '3' ].
Isn't there an explicit value for any?
> > > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> > > index 661999c..b818815 100644
> > > --- a/tools/libxl/libxl_dom.c
> > > +++ b/tools/libxl/libxl_dom.c
> > > @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> > > libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> > > libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
> > >
> > > + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> > > + if (d_config->b_info.vcpu_affinity) {
> > > + int i;
> > > + libxl_bitmap vcpu_cpumap;
> > > + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> > > +
> > > + vcpu_to_pcpu = libxl__zalloc(gc, sz);
> >
> > In theory this could be a stack allocation, either with alloca or just
> > int vcpu_to_pcpu[sz];
> >
>
> I would rather avoid dynamic-size stack allocation, bacause
>
> "The alloca() function returns a pointer to the beginning of the
> allocated space. If the allocation causes stack overflow,
> program behavior is undefined."
I think that's true regardless of how the stack is overflowed, be it an
allocation, an oversized array or a deep call chain. But I don't think
we are talking about quantities of data which are unreasonable to put on
the stack, even with thousands of guest CPUs?
> > > + memset(vcpu_to_pcpu, -1, sz);
> > > +
> > > + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> > > + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> > > + const char *key, *val;
> > > + int k, v;
> > > +
> > > + key = kvl[i * 2];
> >
> > Need to bounds check kvl here. I think you might be better off iterating
> > over the kvl and validating the k against max_vcpus.
> >
>
> The next line is "bound-checking".
The it is too late, you've already run off the end of kvl. (I'm talking
about the bounds of i*2, not the bounds of the resulting key BTW).
>
> > > @@ -833,11 +823,30 @@ static void parse_config_data(const char *config_source,
> > > exit(1);
> > > }
> > > libxl_bitmap_set(&b_info->cpumap, i);
> > > - if (n_cpus < b_info->max_vcpus)
> > > - vcpu_to_pcpu[n_cpus] = i;
> > > + if (n_cpus < b_info->max_vcpus) {
> > > + kvl = xrealloc(kvl, sizeof(char *) * (len * 2 + 2));
> >
> > Can't you get the length of the input list and just allocate the right
> > size to start with?
> >
>
> That introduces extra overhead. Say if you have 32 VCPU but only want to
> pin a few.
is that something to worry about in the context of a userspace library
interface?
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-16 9:57 ` Ian Campbell
@ 2014-05-16 10:15 ` Wei Liu
2014-05-16 10:28 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-16 10:15 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Dario Faggioli, Wei Liu, xen-devel
On Fri, May 16, 2014 at 10:57:59AM +0100, Ian Campbell wrote:
> On Thu, 2014-05-15 at 18:06 +0100, Wei Liu wrote:
> > On Thu, May 15, 2014 at 05:45:19PM +0100, Ian Campbell wrote:
> > > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > >
> > > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> > > > index 0dfafe7..7b0901c 100644
> > > > --- a/tools/libxl/libxl_types.idl
> > > > +++ b/tools/libxl/libxl_types.idl
> > > > @@ -305,6 +305,7 @@ libxl_domain_build_info =
> > > Struct("domain_build_info",[
> > > > ("avail_vcpus", libxl_bitmap),
> > > > ("cpumap", libxl_bitmap),
> > > > ("nodemap", libxl_bitmap),
> > > > + ("vcpu_affinity", libxl_key_value_list),
> > > >
> > > Is a key value list really the best way to represent this? At first
> > > glance it seems like an array would be more suitable?
> > >
> > > I've glanced through the rest on the assumption you have a convincing
> > > reason why it should be a kvp list.
> > >
> >
> > How can you effectively skip pinning a VCPU if it's an array? I can have
> > [ '0': '1', '3': '3' ] in KVL, but not able to represent it in an array
> > [ '1', ?, ?, '3' ].
>
> Isn't there an explicit value for any?
>
Yes, but then that's not very efficient if you only want to pin a few
vcpu, say, if you have 128 vcpu but only want to pin several.
> > > > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> > > > index 661999c..b818815 100644
> > > > --- a/tools/libxl/libxl_dom.c
> > > > +++ b/tools/libxl/libxl_dom.c
> > > > @@ -263,6 +263,54 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> > > > libxl_domain_set_nodeaffinity(ctx, domid, &info->nodemap);
> > > > libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap);
> > > >
> > > > + /* If we have vcpu affinity list, pin vcpu to pcpu. */
> > > > + if (d_config->b_info.vcpu_affinity) {
> > > > + int i;
> > > > + libxl_bitmap vcpu_cpumap;
> > > > + int *vcpu_to_pcpu, sz = sizeof(int) * d_config->b_info.max_vcpus;
> > > > +
> > > > + vcpu_to_pcpu = libxl__zalloc(gc, sz);
> > >
> > > In theory this could be a stack allocation, either with alloca or just
> > > int vcpu_to_pcpu[sz];
> > >
> >
> > I would rather avoid dynamic-size stack allocation, bacause
> >
> > "The alloca() function returns a pointer to the beginning of the
> > allocated space. If the allocation causes stack overflow,
> > program behavior is undefined."
>
> I think that's true regardless of how the stack is overflowed, be it an
> allocation, an oversized array or a deep call chain. But I don't think
> we are talking about quantities of data which are unreasonable to put on
> the stack, even with thousands of guest CPUs?
>
Fair enough. If you don't worry about that then I'm fine with that too.
;-)
> > > > + memset(vcpu_to_pcpu, -1, sz);
> > > > +
> > > > + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> > > > + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> > > > + const char *key, *val;
> > > > + int k, v;
> > > > +
> > > > + key = kvl[i * 2];
> > >
> > > Need to bounds check kvl here. I think you might be better off iterating
> > > over the kvl and validating the k against max_vcpus.
> > >
> >
> > The next line is "bound-checking".
>
> The it is too late, you've already run off the end of kvl. (I'm talking
> about the bounds of i*2, not the bounds of the resulting key BTW).
>
We haven't run off the end. The last single element of a KV list is
sentinel.
i 0 1 N
KVL K0 V0 K1 V1 ... KN VN S <-- sentinel, NULL
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 9:46 ` Ian Campbell
@ 2014-05-16 10:18 ` Wei Liu
2014-05-16 10:30 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-16 10:18 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Fri, May 16, 2014 at 10:46:52AM +0100, Ian Campbell wrote:
> On Thu, 2014-05-15 at 18:13 +0100, Wei Liu wrote:
>
> > > > +typedef struct libxl__ctx libxl_ctx;
> > >
> > > Maybe libxl_uuid.h should include libxl.h?
> > >
> >
> > That leads to circular inclusion.
>
> Do the #define guards not solve that?
>
> Or do you mean that libxl.h's include of libxl_uuid.h might be before
> libxl_ctx is typedefd?
>
The latter. libxl includes libxl_uuid.h at the beginning.
Wei.
> Ian.
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning down to libxl
2014-05-16 10:15 ` Wei Liu
@ 2014-05-16 10:28 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 10:28 UTC (permalink / raw)
To: Wei Liu; +Cc: Dario Faggioli, ian.jackson, xen-devel
On Fri, 2014-05-16 at 11:15 +0100, Wei Liu wrote:
> On Fri, May 16, 2014 at 10:57:59AM +0100, Ian Campbell wrote:
> > On Thu, 2014-05-15 at 18:06 +0100, Wei Liu wrote:
> > > On Thu, May 15, 2014 at 05:45:19PM +0100, Ian Campbell wrote:
> > > > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > > >
> > > > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> > > > > index 0dfafe7..7b0901c 100644
> > > > > --- a/tools/libxl/libxl_types.idl
> > > > > +++ b/tools/libxl/libxl_types.idl
> > > > > @@ -305,6 +305,7 @@ libxl_domain_build_info =
> > > > Struct("domain_build_info",[
> > > > > ("avail_vcpus", libxl_bitmap),
> > > > > ("cpumap", libxl_bitmap),
> > > > > ("nodemap", libxl_bitmap),
> > > > > + ("vcpu_affinity", libxl_key_value_list),
> > > > >
> > > > Is a key value list really the best way to represent this? At first
> > > > glance it seems like an array would be more suitable?
> > > >
> > > > I've glanced through the rest on the assumption you have a convincing
> > > > reason why it should be a kvp list.
> > > >
> > >
> > > How can you effectively skip pinning a VCPU if it's an array? I can have
> > > [ '0': '1', '3': '3' ] in KVL, but not able to represent it in an array
> > > [ '1', ?, ?, '3' ].
> >
> > Isn't there an explicit value for any?
> >
>
> Yes, but then that's not very efficient if you only want to pin a few
> vcpu, say, if you have 128 vcpu but only want to pin several.
I'm not sure how worried I am about that in the context of libxl -- Ian,
what do you think?
> > > > > + memset(vcpu_to_pcpu, -1, sz);
> > > > > +
> > > > > + for (i = 0; i < d_config->b_info.max_vcpus; i++) {
> > > > > + libxl_key_value_list kvl = d_config->b_info.vcpu_affinity;
> > > > > + const char *key, *val;
> > > > > + int k, v;
> > > > > +
> > > > > + key = kvl[i * 2];
> > > >
> > > > Need to bounds check kvl here. I think you might be better off iterating
> > > > over the kvl and validating the k against max_vcpus.
> > > >
> > >
> > > The next line is "bound-checking".
> >
> > The it is too late, you've already run off the end of kvl. (I'm talking
> > about the bounds of i*2, not the bounds of the resulting key BTW).
> >
>
> We haven't run off the end. The last single element of a KV list is
> sentinel.
So it is, sorry I misread.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 10:18 ` Wei Liu
@ 2014-05-16 10:30 ` Ian Campbell
2014-05-16 11:17 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 10:30 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Fri, 2014-05-16 at 11:18 +0100, Wei Liu wrote:
> On Fri, May 16, 2014 at 10:46:52AM +0100, Ian Campbell wrote:
> > On Thu, 2014-05-15 at 18:13 +0100, Wei Liu wrote:
> >
> > > > > +typedef struct libxl__ctx libxl_ctx;
> > > >
> > > > Maybe libxl_uuid.h should include libxl.h?
> > > >
> > >
> > > That leads to circular inclusion.
> >
> > Do the #define guards not solve that?
> >
> > Or do you mean that libxl.h's include of libxl_uuid.h might be before
> > libxl_ctx is typedefd?
> >
>
> The latter. libxl includes libxl_uuid.h at the beginning.
Is reordering the typedef wrt that an option?
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 10:30 ` Ian Campbell
@ 2014-05-16 11:17 ` Wei Liu
2014-05-16 11:21 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-16 11:17 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Fri, May 16, 2014 at 11:30:52AM +0100, Ian Campbell wrote:
> On Fri, 2014-05-16 at 11:18 +0100, Wei Liu wrote:
> > On Fri, May 16, 2014 at 10:46:52AM +0100, Ian Campbell wrote:
> > > On Thu, 2014-05-15 at 18:13 +0100, Wei Liu wrote:
> > >
> > > > > > +typedef struct libxl__ctx libxl_ctx;
> > > > >
> > > > > Maybe libxl_uuid.h should include libxl.h?
> > > > >
> > > >
> > > > That leads to circular inclusion.
> > >
> > > Do the #define guards not solve that?
> > >
> > > Or do you mean that libxl.h's include of libxl_uuid.h might be before
> > > libxl_ctx is typedefd?
> > >
> >
> > The latter. libxl includes libxl_uuid.h at the beginning.
>
> Is reordering the typedef wrt that an option?
>
Moving typedef before including libxl_FOO.h does the job, I think.
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 11:17 ` Wei Liu
@ 2014-05-16 11:21 ` Wei Liu
2014-05-16 11:23 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-16 11:21 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Fri, May 16, 2014 at 12:17:26PM +0100, Wei Liu wrote:
> On Fri, May 16, 2014 at 11:30:52AM +0100, Ian Campbell wrote:
> > On Fri, 2014-05-16 at 11:18 +0100, Wei Liu wrote:
> > > On Fri, May 16, 2014 at 10:46:52AM +0100, Ian Campbell wrote:
> > > > On Thu, 2014-05-15 at 18:13 +0100, Wei Liu wrote:
> > > >
> > > > > > > +typedef struct libxl__ctx libxl_ctx;
> > > > > >
> > > > > > Maybe libxl_uuid.h should include libxl.h?
> > > > > >
> > > > >
> > > > > That leads to circular inclusion.
> > > >
> > > > Do the #define guards not solve that?
> > > >
> > > > Or do you mean that libxl.h's include of libxl_uuid.h might be before
> > > > libxl_ctx is typedefd?
> > > >
> > >
> > > The latter. libxl includes libxl_uuid.h at the beginning.
> >
> > Is reordering the typedef wrt that an option?
> >
>
> Moving typedef before including libxl_FOO.h does the job, I think.
>
Opps, hit "send" too fast. It still fails.
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index be722b6..9664cae 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -319,6 +319,8 @@
#include <xentoollog.h>
+typedef struct libxl__ctx libxl_ctx;
+
#include <libxl_uuid.h>
#include <_libxl_list.h>
@@ -542,8 +544,6 @@
*/
#define LIBXL_HAVE_CPUPOOL_NAME 1
-typedef struct libxl__ctx libxl_ctx;
-
typedef uint8_t libxl_mac[6];
#define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
#define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
diff --git a/tools/libxl/libxl_uuid.h b/tools/libxl/libxl_uuid.h
index 041b927..5cbee99 100644
--- a/tools/libxl/libxl_uuid.h
+++ b/tools/libxl/libxl_uuid.h
@@ -15,6 +15,8 @@
#ifndef __LIBXL_UUID_H__
#define __LIBXL_UUID_H__
+#include <libxl.h>
+
#define LIBXL_UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
#define LIBXL_UUID_FMTLEN ((2*16)+4) /* 16 hex bytes plus 4 hypens */
#define LIBXL__UUID_BYTES(uuid) uuid[0], uuid[1], uuid[2], uuid[3], \
@@ -53,7 +55,6 @@ typedef struct {
#endif
-typedef struct libxl__ctx libxl_ctx;
int libxl_uuid_is_nil(libxl_uuid *uuid);
void libxl_uuid_generate(libxl_uuid *uuid);
int libxl_uuid_from_string(libxl_uuid *uuid, const char
And it fais with:
In file included from ./libxl.h:636:0,
from ./libxl_uuid.h:18,
from libxl_uuid.c:17:
./_libxl_types.h:290:5: error: unknown type name ‘libxl_uuid’
./_libxl_types.h:331:5: error: unknown type name ‘libxl_uuid’
./_libxl_types.h:367:5: error: unknown type name ‘libxl_uuid’
./_libxl_types.h:585:5: error: unknown type name ‘libxl_uuid’
./_libxl_types.h:661:5: error: unknown type name ‘libxl_uuid’
./_libxl_types.h:766:5: error: unknown type name ‘libxl_uuid’
In file included from ./libxl_uuid.h:18:0,
from libxl_uuid.c:17:
./libxl.h:813:116: error: unknown type name ‘libxl_uuid’
In file included from ./libxl_uuid.h:18:0,
from libxl_uuid.c:17:
./libxl.h:1227:47: error: unknown type name ‘libxl_uuid’
In file included from libxl_uuid.c:19:0:
libxl_internal.h:56:3: error: #error libxl.h should be included via libxl_internal.h, not separately
libxl_internal.h:59:0: error: "LIBXL_EXTERNAL_CALLERS_ONLY" redefined [-Werror]
In file included from ./libxl_uuid.h:18:0,
from libxl_uuid.c:17:
./libxl.h:512:0: note: this is the location of the previous definition
cc1: all warnings being treated as errors
make: *** [libxl_uuid.o] Error 1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 11:21 ` Wei Liu
@ 2014-05-16 11:23 ` Ian Campbell
2014-05-16 11:28 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 11:23 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Fri, 2014-05-16 at 12:21 +0100, Wei Liu wrote:
> libxl_internal.h:56:3: error: #error libxl.h should be included via libxl_internal.h, not separately
> libxl_internal.h:59:0: error: "LIBXL_EXTERNAL_CALLERS_ONLY" redefined [-Werror]
I forgot about this. I think with this change you don't need the libxl.h
include in libxl_uuid.h. It is included either via libxl.h or
libxl_internal.h.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 11:23 ` Ian Campbell
@ 2014-05-16 11:28 ` Wei Liu
2014-05-16 11:31 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-16 11:28 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Fri, May 16, 2014 at 12:23:57PM +0100, Ian Campbell wrote:
> On Fri, 2014-05-16 at 12:21 +0100, Wei Liu wrote:
>
> > libxl_internal.h:56:3: error: #error libxl.h should be included via libxl_internal.h, not separately
> > libxl_internal.h:59:0: error: "LIBXL_EXTERNAL_CALLERS_ONLY" redefined [-Werror]
>
> I forgot about this. I think with this change you don't need the libxl.h
> include in libxl_uuid.h. It is included either via libxl.h or
> libxl_internal.h.
>
I don't see inclusion of libxl_internal.h in libxl_uuid.h.
Removing the inclusion of libxl.h in libxl_uuid.h results in this:
gcc -O1 -fno-omit-frame-pointer -m64 -g -fno-strict-aliasing -std=gnu99
-Wall -Wstrict-prototypes -Wdeclaration-after-statement
-Wno-unused-but-set-variable -Wno-unused-local-typedefs
-D__XEN_TOOLS__ -MMD -MF .libxl_uuid.o.d -D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE -fno-optimize-sibling-calls -Werror
-Wno-format-zero-length -Wmissing-declarations
-Wno-declaration-after-statement -Wformat-nonliteral -I. -fPIC -pthread
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/libxc
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/include
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/libxc
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/include
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/xenstore
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/include
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/blktap2/control
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/blktap2/include
-I/local/scratch/xen-toolstack.git/tools/libxl/../../tools/include
-Wshadow -include
/local/scratch/xen-toolstack.git/tools/libxl/../../tools/config.h -c -o
libxl_uuid.o libxl_uuid.c
In file included from libxl_uuid.c:17:0:
./libxl_uuid.h:59:22: error: unknown type name ‘libxl_ctx’
libxl_uuid.c:38:6: error: no previous declaration for ‘libxl_uuid_copy’
[-Werror=missing-declarations]
cc1: all warnings being treated as errors
make: *** [libxl_uuid.o] Error 1
> Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument
2014-05-16 11:28 ` Wei Liu
@ 2014-05-16 11:31 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-16 11:31 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Fri, 2014-05-16 at 12:28 +0100, Wei Liu wrote:
> On Fri, May 16, 2014 at 12:23:57PM +0100, Ian Campbell wrote:
> > On Fri, 2014-05-16 at 12:21 +0100, Wei Liu wrote:
> >
> > > libxl_internal.h:56:3: error: #error libxl.h should be included via libxl_internal.h, not separately
> > > libxl_internal.h:59:0: error: "LIBXL_EXTERNAL_CALLERS_ONLY" redefined [-Werror]
> >
> > I forgot about this. I think with this change you don't need the libxl.h
> > include in libxl_uuid.h. It is included either via libxl.h or
> > libxl_internal.h.
> >
>
> I don't see inclusion of libxl_internal.h in libxl_uuid.h.
I mean that it is either:
libxl_foo.c -> libxl_internal.h -> libxl.h -> libxl_uuid.h
or
xl_foo.c -> libxl.h -> libxl_uuid.h
Noone includes libxl_uuid.h directly (and it seems they shouldn't)
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file
2014-05-13 21:53 ` [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file Wei Liu
@ 2014-05-20 12:44 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 12:44 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> Print out a warning and suggest user use "-V" option when invoking "xl
> create". Also remove that option in manpage.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
I think this is the right thing to do:
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Please can you extract some of the rationale for why this option is
wrongheaded and should be removed from the threads/conversations on the
subject and insert them into the commit message.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types
2014-05-13 21:53 ` [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types Wei Liu
@ 2014-05-20 12:49 ` Ian Campbell
2014-05-20 14:54 ` Ian Jackson
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 12:49 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/libxl.h | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index 31877da..303bd71 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -240,6 +240,16 @@
> * libxl_types.idl). The library provides a common set of methods for
> * initialising and freeing these types.
> *
> + * IDL-generated libxl types should be used as follows: the user must
> + * always call the "init" function before using a type, even if the
> + * variable is simply being passed by reference as an out parameter
> + * to a libxl function. The user must always calls "dispose" exactly
calls should be just call here
> + * once afterwards, to clean up, regardless of whether operations on
> + * this object succeeded or failed. See the xl code for examples.
> + *
> + * "init" is idempotent.
I wondered if this was true, or if calling it twice would leak. None of
the _init functions allocate any memory so this is OK, I think.
Calling init on a partially setup object could leak things though, so
init is only idempotent until you initialise some of the fields, which
isn't a terribly useful guarantee I don't think.
> We intend that "dispose" will become
> + * idempotent, but this is not currently the case.
> + *
> * void libxl_<type>_init(<type> *p):
> *
> * Initialises the members of "p" to all defaults. These may either
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json
2014-05-13 21:53 ` [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json Wei Liu
@ 2014-05-20 12:50 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 12:50 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here
2014-05-13 21:53 ` [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here Wei Liu
@ 2014-05-20 12:51 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 12:51 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> They will be used by both JSON generator and parser so they should be in
> header file.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 10/32] libxl: fix JSON generator for uint64_t
2014-05-13 21:53 ` [PATCH V5 10/32] libxl: fix JSON generator for uint64_t Wei Liu
@ 2014-05-20 12:55 ` Ian Campbell
2014-05-20 13:15 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 12:55 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> yajl_gen_integer cannot cope with uint64_t.
Please can you describe how it fails and/or what it generates in
practice. Perhaps indicate if/how we would cope with it on parse?
In particular I think the result of this change does *not* involve
adding quotes around the number?
> A new function called
> libxl__uint64_gen_json is introduced to handle uint64_t.
>
> Also removed a duplicated definition of MemKB while I was there.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/idl.py | 2 +-
> tools/libxl/libxl_json.c | 21 +++++++++++++++++++++
> tools/libxl/libxl_json.h | 1 +
> tools/libxl/libxl_types.idl | 4 +---
> 4 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
> index e4dc79b..69e08e1 100644
> --- a/tools/libxl/idl.py
> +++ b/tools/libxl/idl.py
> @@ -266,7 +266,7 @@ integer = Number("int", namespace = None, signed = True)
> uint8 = UInt(8)
> uint16 = UInt(16)
> uint32 = UInt(32)
> -uint64 = UInt(64)
> +uint64 = UInt(64, json_fn = "libxl__uint64_gen_json")
>
> string = Builtin("char *", namespace = None, dispose_fn = "free",
> json_fn = "libxl__string_gen_json",
> diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
> index 3ea56a4..ff23376 100644
> --- a/tools/libxl/libxl_json.c
> +++ b/tools/libxl/libxl_json.c
> @@ -794,6 +794,27 @@ out:
> return ret;
> }
>
> +yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val)
> +{
> + char *num;
> + unsigned int len;
> + yajl_gen_status s;
> +
> + if (asprintf(&num, "%"PRIu64, val) == -1) {
> + s = yajl_gen_in_error_state;
> + goto out;
> + }
> +
> + len = strlen(num);
asprintf returns len - 1 on success (I think, check for off by one in
my reading of the manpage).
> +
> + s = yajl_gen_number(hand, num, len);
> +
> + free(num);
> +
> +out:
> + return s;
> +}
> +
> /*
> * Local variables:
> * mode: C
> diff --git a/tools/libxl/libxl_json.h b/tools/libxl/libxl_json.h
> index a4dd8fc..a45d429 100644
> --- a/tools/libxl/libxl_json.h
> +++ b/tools/libxl/libxl_json.h
> @@ -22,6 +22,7 @@
> # include <yajl/yajl_version.h>
> #endif
>
> +yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val);
> yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p);
> yajl_gen_status libxl_domid_gen_json(yajl_gen hand, libxl_domid *p);
> yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *p);
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 7b0901c..30a4f7a 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -22,7 +22,7 @@ libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE)
> # Specific integer types
> #
>
> -MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT")
> +MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT", json_fn = "libxl__uint64_gen_json")
>
> #
> # Constants / Enumerations
> @@ -288,8 +288,6 @@ libxl_domain_restore_params = Struct("domain_restore_params", [
> ("checkpointed_stream", integer),
> ])
>
> -MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT")
> -
> libxl_domain_sched_params = Struct("domain_sched_params",[
> ("sched", libxl_scheduler),
> ("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}),
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number
2014-05-13 21:53 ` [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number Wei Liu
@ 2014-05-20 12:56 ` Ian Campbell
2014-05-20 15:11 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 12:56 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
I assume the actual interpretation comes later...
I noticed that there wasn't a matching libxl__json_object_is_number.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 10/32] libxl: fix JSON generator for uint64_t
2014-05-20 12:55 ` Ian Campbell
@ 2014-05-20 13:15 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-20 13:15 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 01:55:03PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > yajl_gen_integer cannot cope with uint64_t.
>
> Please can you describe how it fails and/or what it generates in
> practice. Perhaps indicate if/how we would cope with it on parse?
>
No problem.
> In particular I think the result of this change does *not* involve
> adding quotes around the number?
>
Yes, you're right.
> > A new function called
> > libxl__uint64_gen_json is introduced to handle uint64_t.
> >
> > Also removed a duplicated definition of MemKB while I was there.
> >
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> > ---
> > tools/libxl/idl.py | 2 +-
> > tools/libxl/libxl_json.c | 21 +++++++++++++++++++++
> > tools/libxl/libxl_json.h | 1 +
> > tools/libxl/libxl_types.idl | 4 +---
> > 4 files changed, 24 insertions(+), 4 deletions(-)
> >
> > diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
> > index e4dc79b..69e08e1 100644
> > --- a/tools/libxl/idl.py
> > +++ b/tools/libxl/idl.py
> > @@ -266,7 +266,7 @@ integer = Number("int", namespace = None, signed = True)
> > uint8 = UInt(8)
> > uint16 = UInt(16)
> > uint32 = UInt(32)
> > -uint64 = UInt(64)
> > +uint64 = UInt(64, json_fn = "libxl__uint64_gen_json")
> >
> > string = Builtin("char *", namespace = None, dispose_fn = "free",
> > json_fn = "libxl__string_gen_json",
> > diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
> > index 3ea56a4..ff23376 100644
> > --- a/tools/libxl/libxl_json.c
> > +++ b/tools/libxl/libxl_json.c
> > @@ -794,6 +794,27 @@ out:
> > return ret;
> > }
> >
> > +yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val)
> > +{
> > + char *num;
> > + unsigned int len;
> > + yajl_gen_status s;
> > +
> > + if (asprintf(&num, "%"PRIu64, val) == -1) {
> > + s = yajl_gen_in_error_state;
> > + goto out;
> > + }
> > +
> > + len = strlen(num);
>
> asprintf returns len - 1 on success (I think, check for off by one in
> my reading of the manpage).
>
OK, I will use that.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation
2014-05-13 21:54 ` [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation Wei Liu
@ 2014-05-20 13:26 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:26 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Generate JSON map handle according to KeyedUnion discriminator.
I know what this means because I've discussed it with you IRL, but I
suspect noone else (including you or I in 6 months time) will know what
this means.
I think an example of what is changing here would be invaluable.
You also need to mention the compatibility concerns and the rationale
for why it is OK to make this particular change (which IIRC was that the
existing syntax was so unusable no one could be using it).
>From eye-balling the diff to the generated code that aspect looks fine.
Ian.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/gentypes.py | 24 +++++++++++++++++++++---
> 1 file changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
> index 61a2b3d..01416e7 100644
> --- a/tools/libxl/gentypes.py
> +++ b/tools/libxl/gentypes.py
> @@ -186,6 +186,26 @@ def libxl_C_type_member_init(ty, field):
> s += "\n"
> return s
>
> +def libxl_C_type_gen_map_key(f, parent, indent = ""):
> + s = ""
> + if isinstance(f.type, idl.KeyedUnion):
> + s += "switch (%s) {\n" % (parent + f.type.keyvar.name)
> + for x in f.type.fields:
> + v = f.type.keyvar.name + "." + x.name
> + s += "case %s:\n" % x.enumname
> + s += " s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (v, v)
> + s += " if (s != yajl_gen_status_ok)\n"
> + s += " goto out;\n"
> + s += " break;\n"
> + s += "}\n"
> + else:
> + s += "s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (f.name, f.name)
> + s += "if (s != yajl_gen_status_ok)\n"
> + s += " goto out;\n"
> + if s != "":
> + s = indent + s
> + return s.replace("\n", "\n%s" % indent).rstrip(indent)
> +
> def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
> s = ""
> if parent is None:
> @@ -235,9 +255,7 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
> s += " goto out;\n"
> for f in [f for f in ty.fields if not f.const and not f.type.private]:
> (nparent,fexpr) = ty.member(v, f, parent is None)
> - s += "s = yajl_gen_string(hand, (const unsigned char *)\"%s\", sizeof(\"%s\")-1);\n" % (f.name, f.name)
> - s += "if (s != yajl_gen_status_ok)\n"
> - s += " goto out;\n"
> + s += libxl_C_type_gen_map_key(f, nparent)
> s += libxl_C_type_gen_json(f.type, fexpr, "", nparent)
> s += "s = yajl_gen_map_close(hand);\n"
> s += "if (s != yajl_gen_status_ok)\n"
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 19/32] libxl/gentypes.py: don't generate default values
2014-05-13 21:54 ` [PATCH V5 19/32] libxl/gentypes.py: don't generate default values Wei Liu
@ 2014-05-20 13:29 ` Ian Campbell
2014-05-20 17:17 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:29 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> If a type has init_val defined and a field of the type has the value of
> init_val, there's no need to generate output for that field.
Please can you explain why there is no need. And I think you need to
mention JSON here somewhere.
> Also define a bunch of init_vals for enumeration types.
I'm not convinced by this. If a type has no initval then you should
compare it to zero, which is a valid thing to do even for an enum.
NB you changed the init_val for some typesto (e.g. from 1 to
LIBXL_VGA_INTERFACE_TYPE_CIRRUS), which is a no semantic change change,
but did mean I had to double check.
Ian.
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/gentypes.py | 27 ++++++++++++++++++++++++---
> tools/libxl/libxl_types.idl | 27 ++++++++++++++-------------
> 2 files changed, 38 insertions(+), 16 deletions(-)
>
> diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
> index 01416e7..d2ed12a 100644
> --- a/tools/libxl/gentypes.py
> +++ b/tools/libxl/gentypes.py
> @@ -135,7 +135,7 @@ def _libxl_C_type_init(ty, v, indent = " ", parent = None, subinit=False):
> else:
> s += _libxl_C_type_init(f.type, fexpr, "", nparent)
> else:
> - if ty.init_val is not None:
> + if ty.init_val is not None and ty.typename != "libxl_defbool":
> s += "%s = %s;\n" % (ty.pass_arg(v, parent is None), ty.init_val)
> elif ty.init_fn is not None:
> s += "%s(%s);\n" % (ty.init_fn, ty.pass_arg(v, parent is None))
> @@ -206,6 +206,13 @@ def libxl_C_type_gen_map_key(f, parent, indent = ""):
> s = indent + s
> return s.replace("\n", "\n%s" % indent).rstrip(indent)
>
> +def get_init_val(f):
> + if f.init_val is not None:
> + return f.init_val
> + elif f.type.init_val is not None:
> + return f.type.init_val
> + return None
> +
> def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
> s = ""
> if parent is None:
> @@ -255,8 +262,22 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None):
> s += " goto out;\n"
> for f in [f for f in ty.fields if not f.const and not f.type.private]:
> (nparent,fexpr) = ty.member(v, f, parent is None)
> - s += libxl_C_type_gen_map_key(f, nparent)
> - s += libxl_C_type_gen_json(f.type, fexpr, "", nparent)
> + init_val = get_init_val(f)
> + if init_val:
> + if f.type.typename != "libxl_defbool":
> + s += "if (%s != %s) {\n" % (fexpr, init_val)
> + else:
> + s += "if (%s.val != %s) {\n" % (fexpr, init_val)
> + indent1 = " "
> + else:
> + indent1 = ""
> +
> + s += libxl_C_type_gen_map_key(f, nparent, indent1)
> + s += libxl_C_type_gen_json(f.type, fexpr, indent, nparent)
> +
> + if init_val:
> + s += "}\n"
> +
> s += "s = yajl_gen_map_close(hand);\n"
> s += "if (s != yajl_gen_status_ok)\n"
> s += " goto out;\n"
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 2162c37..35da8ba 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -5,7 +5,8 @@
>
> namespace("libxl_")
>
> -libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE)
> +libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE,
> + init_val="LIBXL__DEFBOOL_DEFAULT")
>
> libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False)
> libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", autogenerate_json = False, signed = True, init_val="-1")
> @@ -55,13 +56,13 @@ libxl_device_model_version = Enumeration("device_model_version", [
> (0, "UNKNOWN"),
> (1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm)
> (2, "QEMU_XEN"), # Upstream based qemu-xen device model
> - ])
> + ], init_val = "LIBXL_DEVICE_MODEL_VERSION_UNKNOWN")
>
> libxl_console_type = Enumeration("console_type", [
> (0, "UNKNOWN"),
> (1, "SERIAL"),
> (2, "PV"),
> - ])
> + ], init_val = "LIBXL_CONSOLE_TYPE_UNKNOWN")
>
> libxl_disk_format = Enumeration("disk_format", [
> (0, "UNKNOWN"),
> @@ -70,20 +71,20 @@ libxl_disk_format = Enumeration("disk_format", [
> (3, "VHD"),
> (4, "RAW"),
> (5, "EMPTY"),
> - ])
> + ], init_val = "LIBXL_DISK_FORMAT_UNKNOWN")
>
> libxl_disk_backend = Enumeration("disk_backend", [
> (0, "UNKNOWN"),
> (1, "PHY"),
> (2, "TAP"),
> (3, "QDISK"),
> - ])
> + ], init_val = "LIBXL_DISK_BACKEND_UNKNOWN")
>
> libxl_nic_type = Enumeration("nic_type", [
> (0, "UNKNOWN"),
> (1, "VIF_IOEMU"),
> (2, "VIF"),
> - ])
> + ], init_val = "LIBXL_NIC_TYPE_UNKNOWN")
>
> libxl_action_on_shutdown = Enumeration("action_on_shutdown", [
> (1, "DESTROY"),
> @@ -95,7 +96,7 @@ libxl_action_on_shutdown = Enumeration("action_on_shutdown", [
>
> (5, "COREDUMP_DESTROY"),
> (6, "COREDUMP_RESTART"),
> - ], init_val = 1)
> + ], init_val = "LIBXL_ACTION_ON_SHUTDOWN_DESTROY")
>
> libxl_trigger = Enumeration("trigger", [
> (0, "UNKNOWN"),
> @@ -105,14 +106,14 @@ libxl_trigger = Enumeration("trigger", [
> (4, "INIT"),
> (5, "RESET"),
> (6, "S3RESUME"),
> - ])
> + ], init_val = "LIBXL_TRIGGER_UNKNOWN")
>
> libxl_tsc_mode = Enumeration("tsc_mode", [
> (0, "default"),
> (1, "always_emulate"),
> (2, "native"),
> (3, "native_paravirt"),
> - ])
> + ], init_val = "LIBXL_TSC_MODE_DEFAULT")
>
> # Consistent with the values defined for HVM_PARAM_TIMER_MODE.
> libxl_timer_mode = Enumeration("timer_mode", [
> @@ -128,7 +129,7 @@ libxl_bios_type = Enumeration("bios_type", [
> (1, "rombios"),
> (2, "seabios"),
> (3, "ovmf"),
> - ])
> + ], init_val = "LIBXL_BIOS_TYPE_UNKNOWN")
>
> # Consistent with values defined in domctl.h
> # Except unknown which we have made up
> @@ -138,7 +139,7 @@ libxl_scheduler = Enumeration("scheduler", [
> (5, "credit"),
> (6, "credit2"),
> (7, "arinc653"),
> - ])
> + ], init_val = "LIBXL_SCHEDULER_UNKNOWN")
>
> # Consistent with SHUTDOWN_* in sched.h (apart from UNKNOWN)
> libxl_shutdown_reason = Enumeration("shutdown_reason", [
> @@ -154,12 +155,12 @@ libxl_vga_interface_type = Enumeration("vga_interface_type", [
> (1, "CIRRUS"),
> (2, "STD"),
> (3, "NONE"),
> - ], init_val = 1)
> + ], init_val = "LIBXL_VGA_INTERFACE_TYPE_CIRRUS")
>
> libxl_vendor_device = Enumeration("vendor_device", [
> (0, "NONE"),
> (1, "XENSERVER"),
> - ])
> + ], init_val = "LIBXL_VENDOR_DEVICE_NONE")
> #
> # Complex libxl types
> #
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct
2014-05-13 21:54 ` [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
@ 2014-05-20 13:35 ` Ian Campbell
2014-06-01 17:43 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:35 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> libxl_FOO_parse_json functions are generated.
>
> Note that these functions are used to parse libxl__json_object to
> libxl__FOO struct. They don't consume JSON string.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
I eyeballed this again and the only query I have is this:
+ if (libxl__json_map_get("enable", o, JSON_STRING)) {
+ x = libxl__json_map_get("enable", o, JSON_STRING);
These two get calls are a bit redundant.
Looking at the code generator I don't think it forces this on you and
you could arrange instead for:
x = libxl__json_map_get("enable", o, JSON_STRING);
if (x) {
...
Perhaps you need to save x in a new local parent so you can restore it
in that case.
saved_parent = x;
x = libxl__json_map_get("enable", o, JSON_STRING);
if (x) {
...
}
x = saved_parent;
(perhaps putting in its own block and declaring saved_parent locally
each time).
+ rc = libxl_defbool_parse_json(gc, x, &p->enable);
+ if (rc)
+ goto out;
+ x = x->parent;
+ }
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length
2014-05-13 21:54 ` [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length Wei Liu
@ 2014-05-20 13:36 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:36 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
> ---
> tools/libxl/libxl.c | 12 ++++++++++++
> tools/libxl/libxl.h | 1 +
> 2 files changed, 13 insertions(+)
>
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index 0589d4e..0a73a98 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -216,6 +216,18 @@ int libxl_string_list_length(const libxl_string_list *psl)
> return i;
> }
>
> +int libxl_key_value_list_length(libxl_key_value_list *pkvl)
> +{
> + int i = 0;
> + libxl_key_value_list kvl = *pkvl;
> +
> + if (kvl)
> + while (kvl[2 * i]) /* Only checks keys */
> + i++;
{}s for the outermost if would aid readbility a bit should you need to
respin for some reason.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length
2014-05-13 21:54 ` [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length Wei Liu
@ 2014-05-20 13:36 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:36 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
(with same optional comment about {}s around the if)
> ---
> tools/libxl/libxl.h | 1 +
> tools/libxl/libxl_cpuid.c | 12 ++++++++++++
> 2 files changed, 13 insertions(+)
>
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index 3886b9e..4b75802 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -573,6 +573,7 @@ void libxl_bitmap_dispose(libxl_bitmap *map);
> typedef struct libxl__cpuid_policy libxl_cpuid_policy;
> typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
> void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list);
> +int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *l);
>
> #define LIBXL_PCI_FUNC_ALL (~0U)
>
> diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
> index d9007b2..fe14b87 100644
> --- a/tools/libxl/libxl_cpuid.c
> +++ b/tools/libxl/libxl_cpuid.c
> @@ -455,6 +455,18 @@ int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
> return 0;
> }
>
> +int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *pl)
> +{
> + int i = 0;
> + libxl_cpuid_policy_list l = *pl;
> +
> + if (l)
> + while (l[i].input[0] != XEN_CPUID_INPUT_UNUSED)
> + i++;
> +
> + return i;
> +}
> +
> /*
> * Local variables:
> * mode: C
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 24/32] libxl: copy function for builtin types
2014-05-13 21:54 ` [PATCH V5 24/32] libxl: copy function for builtin types Wei Liu
@ 2014-05-20 13:39 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:39 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> These functions will be used in later patch to deep-copy a structure.
>
> Functions introduced:
> * libxl_string_list_copy
> * libxl_key_value_list_copy
> * libxl_hwcap_copy
> * libxl_mac_copy
> * libxl_cpuid_policy_list_copy
> * libxl_string_copy
> * libxl_bitmap_copy_alloc
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
> +void libxl_hwcap_copy(libxl_ctx *ctx,libxl_hwcap *dst, libxl_hwcap *src)
> +{
> + int i;
> +
> + for (i = 0; i < 8; i++)
> + (*dst)[i] = (*src)[i];
> +}
> +
> +void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src)
> +{
> + int i;
> +
> + for (i = 0; i < 6; i++)
> + (*dst)[i] = (*src)[i];
These two might be candidates for using memcpy.
> diff --git a/tools/libxl/libxl_uuid.h b/tools/libxl/libxl_uuid.h
> index 37c4d5f..041b927 100644
> --- a/tools/libxl/libxl_uuid.h
> +++ b/tools/libxl/libxl_uuid.h
> @@ -61,7 +61,6 @@ void libxl_uuid_copy(libxl_ctx *ctx, libxl_uuid *dst, const libxl_uuid *src);
> #if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x040500
> void libxl_uuid_copy(dst, src) libxl_uuid_copy(NULL, dst, src)
> #endif
> -
Stray change.
> void libxl_uuid_clear(libxl_uuid *uuid);
> int libxl_uuid_compare(libxl_uuid *uuid1, libxl_uuid *uuid2);
> uint8_t *libxl_uuid_bytearray(libxl_uuid *uuid);
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 25/32] libxl IDL: generate deep copy functions
2014-05-13 21:54 ` [PATCH V5 25/32] libxl IDL: generate deep copy functions Wei Liu
@ 2014-05-20 13:42 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 13:42 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Introduces copy_fn for a type.
>
> For most builtin types we can use direct assignment. For those builtin
> types which cannot use direct assignment we use the copy functions in
> previous patch.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
I did briefly wonder if libxl_string_copy was really necessary as part
of the API (as oppposed to an internal function). But in the end I
decided it didn't really matter.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-05-13 21:54 ` [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions Wei Liu
@ 2014-05-20 14:03 ` Ian Campbell
2014-06-01 18:41 ` Wei Liu
2014-05-20 15:01 ` Ian Jackson
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 14:03 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Introduce a new format in libxl userdata store called "libxl-json". This
> format contains the deserialized version of domain configuration of a
> domain.
>
> Two libxl functions to load and store domain configuration are also
> introduced. They use the new "libxl-json" format.
Is the intention that application should use these to read/modify/write
the domain config on changes, as opposed to it being internal
functionality which libxl should use to keep things up to date?
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/libxl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
> tools/libxl/libxl.h | 10 ++++++++
> 2 files changed, 78 insertions(+)
>
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index c9475d7..b578a5c 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -5751,6 +5751,74 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src)
> for (i = 0; i < 6; i++)
> (*dst)[i] = (*src)[i];
> }
> +
> +int libxl_load_domain_configuration(libxl_ctx *ctx, uint32_t domid,
> + libxl_domain_config *d_config)
> +{
> + GC_INIT(ctx);
> + uint8_t *data;
> + int rc, len;
> +
> + rc = libxl_userdata_retrieve(ctx, domid, "libxl-json", &data, &len);
> + if (rc) {
> + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
You can use LOGEV here to shorten lines and loge below etc.
> + "Failed to retrieve domain configuration for domain %d",
> + domid);
> + rc = ERROR_FAIL;
> + goto out;
> + }
> +
> + if (len == 0) {
> + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
> + "Configuration data stream empty for domain %d",
> + domid);
> + rc = ERROR_FAIL;
> + goto out;
> + }
> +
> + /* Make sure this string ends with \0 -- the parser expects a NULL
> + * terminated string.
Could this be achieved by strlen(d_config_json)+1 when saving? Assuming
that string is NULL terminated.
> + */
> + if (data[len-1] != '\0') {
> + data = libxl__realloc(gc, data, len + 1);
> + data[len] = '\0';
> + }
> +
> + rc = libxl_domain_config_from_json(ctx, d_config, (const char *)data);
> +
> +out:
> + free(data);
data might have been libxl__realloc'd above, so isn't it gc'd?
> + GC_FREE;
> + return rc;
> +}
> +
> +int libxl_store_domain_configuration(libxl_ctx *ctx, uint32_t domid,
> + libxl_domain_config *d_config)
> +{
> + GC_INIT(ctx);
> + char *d_config_json;
> + int rc;
> +
> + d_config_json = libxl_domain_config_to_json(ctx, d_config);
> +
> + rc = libxl_userdata_store(ctx, domid, "libxl-json",
> + (const uint8_t *)d_config_json,
> + strlen(d_config_json));
> + if (rc) {
> + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
LOGEV.
> + "Failed to store domain configuration for domain %d",
> + domid);
> + rc = ERROR_FAIL;
> + goto out;
> + }
> +
> + free(d_config_json);
> +
> +out:
> + GC_FREE;
> + return rc;
> +}
> +
> /*
> * Local variables:
> * mode: C
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index d5dfe2e..be722b6 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -1140,6 +1140,8 @@ void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid,
> * "xl" domain config file in xl format, Unix line endings
> * "libvirt-xml" domain config file in libvirt XML format. See
> * http://libvirt.org/formatdomain.html
> + * "libxl-json" domain config file in JSON format, generated by
> + * libxl
I think I would mention libxl_domain_config. Something like
"libxl_domain_config object in JSON format, generated by libxl."
perhaps.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain
2014-05-13 21:54 ` [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain Wei Liu
@ 2014-05-20 14:12 ` Ian Campbell
2014-06-01 19:02 ` Wei Liu
2014-05-20 15:04 ` Ian Jackson
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 14:12 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> This patch utilizes "libxl-json" format and helper functions introduced
> in previous patch to store up-to-do domain configuration when creating a
> domain.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
This seems to end up saving the domain config 2 or even 3 times. I think
we need an explanation as to why that is.
Also we need to know what the invariants are, what must (not) change
either before or after each sequencing point, what must be in each
update etc.
Can you not save the raw version at the start (before anything has
touched it) and then do the domid, uuid, mac, vtpm etc all at the end in
domcreate_complete? (Don't you do the uuid twice? The comments mention
it twice)
> +static void update_domain_config(libxl_ctx *ctx,
Internal functions should take a libxl__gc not a ctx.
> @@ -1366,6 +1400,25 @@ static void domcreate_complete(libxl__egc *egc,
> if (!rc && d_config->b_info.exec_ssidref)
> rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref);
>
> + if (!rc) {
> + libxl_domain_config d_config_saved;
> +
> + libxl_domain_config_init(&d_config_saved);
> + rc = libxl_load_domain_configuration(CTX, dcs->guest_domid,
> + &d_config_saved);
> + if (rc) {
> + LOG(ERROR, "cannot load domain configuration: %d", rc);
> + goto out;
> + }
> + update_domain_config(CTX, &d_config_saved, d_config);
> + rc = libxl_store_domain_configuration(CTX, dcs->guest_domid,
> + &d_config_saved);
> + if (rc)
> + LOG(ERROR, "cannot store domain configuration: %d", rc);
> + libxl_domain_config_dispose(&d_config_saved);
Unless you are sure this is the only place this will be needed A helper
of the form libxl__domain_config_update(gc, &update_domain_config, data)
might be useful. i.e. read, call a callback, write. data is a void *
passed to the update_domain_config callback.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-13 21:54 ` [PATCH V5 29/32] xl: use "libxl-json" format Wei Liu
@ 2014-05-20 14:23 ` Ian Campbell
2014-05-20 15:13 ` Ian Jackson
2014-06-01 19:37 ` Wei Liu
2014-05-20 15:11 ` Ian Jackson
1 sibling, 2 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 14:23 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Before this change, xl stores domain configuration in "xl" format, which
> is in fact a verbatim copy of user supplied domain config.
>
> As now libxl is able to handle domain configuration with "libxl-json"
> format, use that wherever possible.
>
> Tests done so far (xl.{new,old} denotes xl with{,out} "xl_json"
> support):
>
> 1. xl.new create then xl.new save, hexdump saved file: domain config
> saved in JSON format
> 2. xl.new create, xl.new save then xl.old restore: failed on
> mandatory flag check
> 3. xl.new create, xl.new save then xl.new restore: succeeded
> 4. xl.old create, xl.old save then xl.new restore: succeeded
> 5. xl.new create then local migrate, receiving end xl.new: succeeded
> 6. xl.old create then local migrate, receiving end xl.new: succeeded
I think xl.old create, xl.new save, xl.new restore would be interesting
(it should work I think)
For cases like #4 and #6 if you subsequently save the domain does it use
xl or libxl-json? What I'm asking is does the oldness persist forever or
is it laundered out (which in turn feeds into how long old support needs
to stay in the tree...)
> @@ -1787,13 +1770,10 @@ static int handle_domain_death(uint32_t *r_domid,
> break;
>
> case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
> - reload_domain_config(*r_domid, config_data, config_len);
> restart = 2;
> break;
>
> case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
> - reload_domain_config(*r_domid, config_data, config_len);
Why is it not equally necessary to reload the JSON config at this point
if it exists?
(commit message should explain this, and in general anywhere that the
need to reload/refresh the config differs, because my expectation was of
a more straight forward substitution of reload_domain_config for the new
function).
> -
> restart = 1;
> /* fall-through */
> case LIBXL_ACTION_ON_SHUTDOWN_DESTROY:
[...]
> - parse_config_data(config_source, config_data, config_len, &d_config);
> + if (config_in_json) {
> + char *config_c = config_data;
> + if (config_c[config_len-1] != '\0') {
> + config_c = xrealloc(config_c, config_len + 1);
> + config_c[config_len] = '\0';
I think this is somewhere that arranging via the protocol that things
must be null terminated might make sense.
> + /* If we're doing migration, the domain name was appended with
> + * "--incoming" a few lines above. So we need to remove that
> + * suffix in the stored configuration.
It's not possible to save this before we do that appending?
Or should we not be updating the domain config as we do the renaming at
the end?
> + */
> + if (migrate_fd >= 0) {
> + libxl_domain_config d;
> + int xlen = strlen("--incoming");
> + int orig_len;
> +
> + ret = libxl_load_domain_configuration(ctx, domid, &d);
> + if (ret) {
> + perror("cannot load config data");
> + ret = ERROR_FAIL;
> + goto error_out;
> + }
> +
> + orig_len = strlen(d.c_info.name);
> + d.c_info.name = xrealloc(d.c_info.name, orig_len - xlen);
> + d.c_info.name[orig_len - xlen] = 0;
Since the new name is always shorter you could do this simply by
sticking a \0 in the middle without needing to realloc.
> @@ -3102,22 +3119,18 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
> s = yajl_gen_status_ok;
>
> for (i = 0; i < nb_domain; i++) {
> + libxl_domain_config_init(&d_config);
> /* no detailed info available on dom0 */
> if (info[i].domid == 0)
> continue;
> - rc = libxl_userdata_retrieve(ctx, info[i].domid, "xl", &data, &len);
> + rc = libxl_load_domain_configuration(ctx, info[i].domid, &d_config);
If a domain was created with xl.old will we not now fail to list details
of it here?
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 30/32] libxl: consider force removal of device successful
2014-05-13 21:54 ` [PATCH V5 30/32] libxl: consider force removal of device successful Wei Liu
@ 2014-05-20 14:26 ` Ian Campbell
2014-06-01 19:44 ` Wei Liu
2014-05-20 15:15 ` Ian Jackson
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 14:26 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> The current behavior of libxl to remove a device is, if the backend
> times out, libxl will initiate a force removal (destroy) of that device.
> However, libxl still returns failure in that case, even if the force
> removal was successful.
>
> If a device is force removed and the force removal succeeds, from
> guest's PoV this device is gone. Libxl should consider this a
> successful case as well.
This seems reasonable.
However the implementation confuses me. Perhaps this is one for Ian J,
but let me see if I can work it out.
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/libxl_device.c | 12 ++++++++++--
> tools/libxl/libxl_internal.h | 4 ++++
> 2 files changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
> index fa99f77..ce0b358 100644
> --- a/tools/libxl/libxl_device.c
> +++ b/tools/libxl/libxl_device.c
> @@ -845,6 +845,11 @@ void libxl__initiate_device_remove(libxl__egc *egc,
> if (rc < 0) goto out;
> }
>
> + /* At this point the XS transaction is committed. So check if we were
> + * force removing the device.
Why does the fact that we were or not force committing relate to the XS
transaction?
> + */
> + aodev->force_removed = aodev->force;
> +
> rc = libxl__ev_devstate_wait(gc, &aodev->backend_ds,
> device_backend_callback,
> state_path, XenbusStateClosed,
> @@ -928,7 +933,7 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
> return;
> }
>
> - if (rc) {
> + if (rc && !aodev->force_removed) {
> LOG(ERROR, "unable to %s device with path %s",
> libxl__device_action_to_string(aodev->action),
> libxl__device_backend_path(gc, aodev->dev));
> @@ -939,7 +944,10 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
> return;
>
> out:
> - aodev->rc = rc;
> + /* If force removal is successful, the device is gone from guest's
> + * PoV. Libxl should return success, too.
> + */
> + aodev->rc = aodev->force_removed ? 0 : rc;
This is the bit which confuses me most. If the forced removal was
successful, why was rc not 0 already in that case?
I'm also not sure where the case that the force remove also fails is.
Perhaps it cannot possibly fail?
> device_hotplug_done(egc, aodev);
> return;
> }
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 89bbf7d..21bb774 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -2086,6 +2086,10 @@ struct libxl__ao_device {
> libxl__device_action action;
> libxl__device *dev;
> int force;
> + /* If force removal is successful, force_removed=1. The device is
> + * gone from guest's PoV
> + */
> + int force_removed;
> libxl__device_callback *callback;
> /* return value, zeroed by user on entry, is valid on callback */
> int rc;
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-13 21:54 ` [PATCH V5 31/32] libxl: update domain configuration when updating memory targets Wei Liu
@ 2014-05-20 14:32 ` Ian Campbell
2014-06-01 20:00 ` Wei Liu
2014-05-20 15:21 ` Ian Jackson
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 14:32 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ---
> tools/libxl/libxl.c | 36 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
>
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index b578a5c..f93096b 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -3529,6 +3529,25 @@ out:
>
> /******************************************************************************/
>
> +/* Macro to load / store domain configuration. They must use in pair.
> + * Load macro defines d_config that can be used by other code. Store
> + * macro will dispose d_config.
> + */
I was asking for a helper earlier, I suppose this could be useful there
too.
TBH I think a helper fn and callback arrangement would be preferable to
magic macros (macros only when there is no alternative I think). I
suppose that would result in a plethora of little callback helpers
though. Hrm, what do you think?
> +#define LOAD_DOMAIN_CONFIG(domid) \
> + libxl_domain_config d_config; \
> + libxl_domain_config_init(&d_config); \
> + rc = libxl_load_domain_configuration(CTX, (domid), &d_config); \
> + if (rc) \
> + goto out; \
> +
> +#define STORE_DOMAIN_CONFIG(domid) \
> + rc = libxl_store_domain_configuration(CTX, (domid), &d_config); \
> + if (rc) { \
> + libxl_domain_config_dispose(&d_config); \
> + goto out; \
> + } \
> + libxl_domain_config_dispose(&d_config); \
rc =
libxl_domain_config_dispose
if (rc)
goto out;
would work here I think, since dispose doesn't clobber rc.
> +
> /* Macro for defining device remove/destroy functions in a compact way */
> /* The following functions are defined:
> * libxl_device_disk_remove
> @@ -4005,6 +4024,14 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
> goto out;
> }
>
> + {
> + LOAD_DOMAIN_CONFIG(domid);
> +
> + d_config.b_info.max_memkb = max_memkb;
> +
> + STORE_DOMAIN_CONFIG(domid);
> + }
> +
> rc = 0;
> out:
> GC_FREE;
> @@ -4241,6 +4268,15 @@ out:
> if (errno == EAGAIN)
> goto retry_transaction;
>
> + /* Currently Dom0 information is not yet managed by libxl */
> + if (!rc && domid) {
> + LOAD_DOMAIN_CONFIG(domid);
> +
> + d_config.b_info.target_memkb = new_target_memkb;
> +
> + STORE_DOMAIN_CONFIG(domid);
> + }
> +
> out_no_transaction:
> GC_FREE;
> return rc;
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device
2014-05-13 21:54 ` [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device Wei Liu
@ 2014-05-20 14:35 ` Ian Campbell
2014-05-20 15:33 ` Ian Jackson
1 sibling, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 14:35 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> We synchronize domain configuration in the callback, right before we
> return to caller. We depends solely on the return value of AO to
> determine if AO is successful.
>
> This approach cannot deal with half-baked device state (say, if AO
> returns success but for various reasons other parts just fail and we
> have some xenstore entries written / resource allocated). However we
> cannot make thing worse as the original code cannot handle that either.
> The good side of this approach is that in the future we can compare the
> stored configuration and xenstore entries to spot any half-baked device
> state so it can help fix that issue in the future.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
This looks broadly sensible to me, but I generally defer to Ian J on
anything involving the ao machinery...
> ---
> tools/libxl/libxl.c | 152 +++++++++++++++++++++++++++++++++++-------
> tools/libxl/libxl_internal.h | 2 +
> 2 files changed, 129 insertions(+), 25 deletions(-)
>
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index f93096b..a7bf0a4 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -1794,29 +1794,6 @@ out:
>
> /******************************************************************************/
>
> -/* generic callback for devices that only need to set ao_complete */
> -static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
> -{
> - STATE_AO_GC(aodev->ao);
> -
> - if (aodev->rc) {
> - if (aodev->dev) {
> - LOG(ERROR, "unable to %s %s with id %u",
> - libxl__device_action_to_string(aodev->action),
> - libxl__device_kind_to_string(aodev->dev->kind),
> - aodev->dev->devid);
> - } else {
> - LOG(ERROR, "unable to %s device",
> - libxl__device_action_to_string(aodev->action));
> - }
> - goto out;
> - }
> -
> -out:
> - libxl__ao_complete(egc, ao, aodev->rc);
> - return;
> -}
> -
> /* common function to get next device id */
> static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
> {
> @@ -3548,6 +3525,126 @@ out:
> } \
> libxl_domain_config_dispose(&d_config); \
>
> +static void device_nic_fixup(libxl_ctx *ctx, libxl_device_nic *dst,
> + libxl_device_nic *src)
> +{
> + dst->devid = src->devid;
> + libxl_mac_copy(ctx, &dst->mac, &src->mac);
> +}
> +
> +static void device_vtpm_fixup(libxl_ctx *ctx, libxl_device_vtpm *dst,
> + libxl_device_vtpm *src)
> +{
> + libxl_uuid_copy(ctx, &dst->uuid, &src->uuid);
> +}
> +
> +static void device_disk_fixup(libxl_ctx *ctx, libxl_device_disk *dst,
> + libxl_device_disk *src)
> +{
> +}
> +
> +#define DEVICE_AO_FAILED_MSG \
> + do { \
> + if (aodev->dev) { \
> + LOG(ERROR, "unable to %s %s with id %u", \
> + libxl__device_action_to_string(aodev->action), \
> + libxl__device_kind_to_string(aodev->dev->kind), \
> + aodev->dev->devid); \
> + } else { \
> + LOG(ERROR, "unable to %s device", \
> + libxl__device_action_to_string(aodev->action)); \
> + } \
> + } while (0)
> +
> +
> +#define DEFINE_DEVICE_ADD_AOCOMPLETE(type,ptr,cnt) \
> + static void device_add_##type##_aocomplete(libxl__egc *egc, \
> + libxl__ao_device *aodev) \
> + { \
> + STATE_AO_GC(aodev->ao); \
> + int rc; \
> + \
> + if (aodev->rc) { \
> + DEVICE_AO_FAILED_MSG; \
> + goto out; \
> + } else { \
> + libxl_device_##type *p; \
> + \
> + LOAD_DOMAIN_CONFIG(aodev->dev->domid); \
> + \
> + d_config.ptr = \
> + libxl__realloc(gc, d_config.ptr, \
> + (d_config.cnt + 1) * \
> + sizeof(libxl_device_##type)); \
> + p = &d_config.ptr[d_config.cnt]; \
> + d_config.cnt++; \
> + \
> + libxl_device_##type##_copy(CTX, p, aodev->pdev_copy); \
> + \
> + device_##type##_fixup(CTX, p, aodev->pdev); \
> + \
> + STORE_DOMAIN_CONFIG(aodev->dev->domid); \
> + } \
> + \
> + out: \
> + /* Dispose our internal copy, which is allocated at the entry of \
> + * this AO. */ \
> + libxl_device_##type##_dispose(aodev->pdev_copy); \
> + libxl__ao_complete(egc, ao, aodev->rc); \
> + return; \
> + }
> +
> +DEFINE_DEVICE_ADD_AOCOMPLETE(nic, nics, num_nics);
> +DEFINE_DEVICE_ADD_AOCOMPLETE(vtpm, vtpms, num_vtpms);
> +DEFINE_DEVICE_ADD_AOCOMPLETE(disk, disks, num_disks);
> +
> +#define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
> +#define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
> +
> +#define DEFINE_DEVICE_RM_AOCOMPLETE(type,ptr,cnt,compare) \
> + static void device_rm_##type##_aocomplete(libxl__egc *egc, \
> + libxl__ao_device *aodev) \
> + { \
> + STATE_AO_GC(aodev->ao); \
> + int rc; \
> + \
> + if (aodev->rc) { \
> + DEVICE_AO_FAILED_MSG; \
> + goto out; \
> + } else { \
> + int i, j; \
> + libxl_device_##type *p = aodev->pdev; \
> + LOAD_DOMAIN_CONFIG(aodev->dev->domid); \
> + \
> + for (i = j = 0; i < d_config.cnt; i++) { \
> + if (!compare(&d_config.ptr[i], p)) { \
> + if (i != j) { \
> + libxl_device_##type##_dispose(&d_config.ptr[j]);\
> + d_config.ptr[j] = d_config.ptr[i]; \
> + } \
> + j++; \
> + } \
> + } \
> + \
> + d_config.ptr = \
> + libxl__realloc(gc, d_config.ptr, \
> + j * sizeof(libxl_device_##type)); \
> + d_config.cnt = j; \
> + \
> + STORE_DOMAIN_CONFIG(aodev->dev->domid); \
> + } \
> + \
> + out: \
> + libxl__ao_complete(egc, ao, aodev->rc); \
> + return; \
> + }
> +
> +DEFINE_DEVICE_RM_AOCOMPLETE(nic, nics, num_nics, COMPARE_DEVID);
> +DEFINE_DEVICE_RM_AOCOMPLETE(vtpm, vtpms, num_vtpms, COMPARE_DEVID);
> +DEFINE_DEVICE_RM_AOCOMPLETE(disk, disks, num_disks, COMPARE_DISK);
> +DEFINE_DEVICE_RM_AOCOMPLETE(vkb, vkbs, num_vkbs, COMPARE_DEVID);
> +DEFINE_DEVICE_RM_AOCOMPLETE(vfb, vfbs, num_vfbs, COMPARE_DEVID);
> +
> /* Macro for defining device remove/destroy functions in a compact way */
> /* The following functions are defined:
> * libxl_device_disk_remove
> @@ -3577,9 +3674,11 @@ out:
> \
> GCNEW(aodev); \
> libxl__prepare_ao_device(ao, aodev); \
> + aodev->pdev = type; \
> + aodev->pdev_copy = NULL; /* unused */ \
> aodev->action = LIBXL__DEVICE_ACTION_REMOVE; \
> aodev->dev = device; \
> - aodev->callback = device_addrm_aocomplete; \
> + aodev->callback = device_rm_##type##_aocomplete; \
> aodev->force = f; \
> libxl__initiate_device_remove(egc, aodev); \
> \
> @@ -3631,8 +3730,11 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
> libxl__ao_device *aodev; \
> \
> GCNEW(aodev); \
> + aodev->pdev = type; \
> + aodev->pdev_copy = libxl__zalloc(gc, sizeof(*type)); \
> + libxl_device_##type##_copy(CTX, aodev->pdev_copy, aodev->pdev); \
> libxl__prepare_ao_device(ao, aodev); \
> - aodev->callback = device_addrm_aocomplete; \
> + aodev->callback = device_add_##type##_aocomplete; \
> libxl__device_##type##_add(egc, domid, type, aodev); \
> \
> return AO_INPROGRESS; \
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 21bb774..06503df 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -2106,6 +2106,8 @@ struct libxl__ao_device {
> const char *what;
> int num_exec;
> libxl__ev_child child;
> + void *pdev; /* pointer to libxl_device_nic/vtpm/disk etc. */
> + void *pdev_copy; /* a copy of vanilla structure pointed to by pdev. */
> };
>
> /*
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function
2014-05-15 16:28 ` Ian Campbell
@ 2014-05-20 14:47 ` Ian Jackson
2014-05-20 17:24 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 14:47 UTC (permalink / raw)
To: Ian Campbell; +Cc: Wei Liu, xen-devel
Ian Campbell writes ("Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function"):
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>
> I'm unsure whether additions to libxl_utils.h should have a
> corresponding #define LIBXL_HAVE.
Yes, I think they probably should.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types
2014-05-20 12:49 ` Ian Campbell
@ 2014-05-20 14:54 ` Ian Jackson
2014-05-20 15:02 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 14:54 UTC (permalink / raw)
To: Ian Campbell; +Cc: Wei Liu, xen-devel
Ian Campbell writes ("Re: [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types"):
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > + * once afterwards, to clean up, regardless of whether operations on
> > + * this object succeeded or failed. See the xl code for examples.
> > + *
> > + * "init" is idempotent.
>
> I wondered if this was true, or if calling it twice would leak. None of
> the _init functions allocate any memory so this is OK, I think.
I think it's a necessary guarantee that they don't, for this to be a
convenient interface.
> Calling init on a partially setup object could leak things though, so
> init is only idempotent until you initialise some of the fields, which
> isn't a terribly useful guarantee I don't think.
Uh. What a strange thing to say.
init is idempotent even if you have already filled in some of the
fields with allocated values. If you initialise some of the fields
and then call init one or more times it's just like calling it once.
What you mean is that it is _incorrect_ to call init on a struct with
allocations in it. Yes. That's surely obvious. But it has nothing
to do with idempotency.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-05-13 21:54 ` [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions Wei Liu
2014-05-20 14:03 ` Ian Campbell
@ 2014-05-20 15:01 ` Ian Jackson
2014-06-01 18:46 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:01 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.campbell, xen-devel
Wei Liu writes ("[PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions"):
> Introduce a new format in libxl userdata store called "libxl-json". This
> format contains the deserialized version of domain configuration of a
> domain.
I don't think "deserialised" means what you think it means here.
JSON is a data structure serialisation format. So the structure is
serialised, not deserialised. But it would be better to just say "the
JSON version" or some such.
I don't think I understand what role these two functions play in the
public API. libxl_load_domain_configuration doesn't really "load" a
configuration; it obtains the configuration of a running domain. But
at the moment it doesn't do anything unless store has been called.
I can't see why an application would ever want to call
libxl_store_domain_configuration. If it did, what would it mean ?
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types
2014-05-20 14:54 ` Ian Jackson
@ 2014-05-20 15:02 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 15:02 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, xen-devel
On Tue, 2014-05-20 at 15:54 +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types"):
> > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > > + * once afterwards, to clean up, regardless of whether operations on
> > > + * this object succeeded or failed. See the xl code for examples.
> > > + *
> > > + * "init" is idempotent.
> >
> > I wondered if this was true, or if calling it twice would leak. None of
> > the _init functions allocate any memory so this is OK, I think.
>
> I think it's a necessary guarantee that they don't, for this to be a
> convenient interface.
Yes.
> > Calling init on a partially setup object could leak things though, so
> > init is only idempotent until you initialise some of the fields, which
> > isn't a terribly useful guarantee I don't think.
>
> Uh. What a strange thing to say.
>
> init is idempotent even if you have already filled in some of the
> fields with allocated values. If you initialise some of the fields
> and then call init one or more times it's just like calling it once.
Right, that is true, but the first call was destructive is what I was
getting at. I think I was simply thinking myself into circles.
> What you mean is that it is _incorrect_ to call init on a struct with
> allocations in it. Yes. That's surely obvious. But it has nothing
> to do with idempotency.
Right.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain
2014-05-13 21:54 ` [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain Wei Liu
2014-05-20 14:12 ` Ian Campbell
@ 2014-05-20 15:04 ` Ian Jackson
1 sibling, 0 replies; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:04 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.campbell, xen-devel
Wei Liu writes ("[PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain"):
> This patch utilizes "libxl-json" format and helper functions introduced
> in previous patch to store up-to-do domain configuration when creating a
> domain.
This looks like it's going in the right direction. I agree with Ian
C's comments.
Also:
> @@ -814,6 +819,16 @@ static void initiate_domain_create(libxl__egc *egc,
> dcs->guest_domid = domid;
> dcs->dmss.dm.guest_domid = 0; /* means we haven't spawned */
>
> + /* At this point we've got domid and UUID, store configuration */
> + ret = libxl_store_domain_configuration(ctx, domid, &d_config_saved);
> + if (ret) {
> + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot store domain configuration: %d",
This line needs wrapping.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number
2014-05-20 12:56 ` Ian Campbell
@ 2014-05-20 15:11 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 15:11 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-20 at 13:56 +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>
> I assume the actual interpretation comes later...
>
> I noticed that there wasn't a matching libxl__json_object_is_number.
NM, it was in #14 which I didn't read this time because I'd already
acked it...
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-13 21:54 ` [PATCH V5 29/32] xl: use "libxl-json" format Wei Liu
2014-05-20 14:23 ` Ian Campbell
@ 2014-05-20 15:11 ` Ian Jackson
2014-05-20 15:15 ` Ian Campbell
2014-06-01 19:07 ` Wei Liu
1 sibling, 2 replies; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:11 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.campbell, xen-devel
Wei Liu writes ("[PATCH V5 29/32] xl: use "libxl-json" format"):
> Before this change, xl stores domain configuration in "xl" format, which
> is in fact a verbatim copy of user supplied domain config.
...
> + /* If we're doing migration, the domain name was appended with
> + * "--incoming" a few lines above. So we need to remove that
> + * suffix in the stored configuration.
> + */
> + if (migrate_fd >= 0) {
> + libxl_domain_config d;
> + int xlen = strlen("--incoming");
> + int orig_len;
> +
> + ret = libxl_load_domain_configuration(ctx, domid, &d);
Firstly, I think this editing of libxl's copy of domain config way is
a layering violation.
But it ought to be unnecessary, because either libxl_domain_rename
or "libxl_load_domain_configuration" should deal with it. I would
much prefer the latter, as that results in the domain name being
stored only in one place.
I mostly agree with Ian's comments.
Thanks,
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 14:23 ` Ian Campbell
@ 2014-05-20 15:13 ` Ian Jackson
2014-05-20 15:31 ` Ian Campbell
2014-06-01 19:37 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:13 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
Ian Campbell writes ("Re: [PATCH V5 29/32] xl: use "libxl-json" format"):
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > Tests done so far (xl.{new,old} denotes xl with{,out} "xl_json"
> > support):
> >
> > 1. xl.new create then xl.new save, hexdump saved file: domain config
> > saved in JSON format
> > 2. xl.new create, xl.new save then xl.old restore: failed on
> > mandatory flag check
> > 3. xl.new create, xl.new save then xl.new restore: succeeded
> > 4. xl.old create, xl.old save then xl.new restore: succeeded
> > 5. xl.new create then local migrate, receiving end xl.new: succeeded
> > 6. xl.old create then local migrate, receiving end xl.new: succeeded
>
> I think xl.old create, xl.new save, xl.new restore would be interesting
> (it should work I think)
The first xl.new won't find the stored json domain config, so no. But
this isn't something you're supposed to be able to do between Xen
releases (because new tools means new hypervisor so a reboot).
> For cases like #4 and #6 if you subsequently save the domain does it use
> xl or libxl-json? What I'm asking is does the oldness persist forever or
> is it laundered out (which in turn feeds into how long old support needs
> to stay in the tree...)
AIUI it gets laundered out.
Thanks,
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 15:11 ` Ian Jackson
@ 2014-05-20 15:15 ` Ian Campbell
2014-05-20 15:39 ` Ian Jackson
2014-06-01 19:07 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 15:15 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, xen-devel
On Tue, 2014-05-20 at 16:11 +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 29/32] xl: use "libxl-json" format"):
> > Before this change, xl stores domain configuration in "xl" format, which
> > is in fact a verbatim copy of user supplied domain config.
> ...
> > + /* If we're doing migration, the domain name was appended with
> > + * "--incoming" a few lines above. So we need to remove that
> > + * suffix in the stored configuration.
> > + */
> > + if (migrate_fd >= 0) {
> > + libxl_domain_config d;
> > + int xlen = strlen("--incoming");
> > + int orig_len;
> > +
> > + ret = libxl_load_domain_configuration(ctx, domid, &d);
>
> Firstly, I think this editing of libxl's copy of domain config way is
> a layering violation.
>
> But it ought to be unnecessary, because either libxl_domain_rename
That would lend credence to the idea that these functions ought to be
internal to the library, or at least the store one should (get is still
useful to applications I suppose, e.g. xl list).
> or "libxl_load_domain_configuration" should deal with it. I would
> much prefer the latter, as that results in the domain name being
> stored only in one place.
You mean libxl_load_dmoain_config should have special handling for
domains names ending --incoming (or --.* perhaps)? That doesn't seem
right, I suspect you meant something else.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 30/32] libxl: consider force removal of device successful
2014-05-13 21:54 ` [PATCH V5 30/32] libxl: consider force removal of device successful Wei Liu
2014-05-20 14:26 ` Ian Campbell
@ 2014-05-20 15:15 ` Ian Jackson
2014-06-01 19:46 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:15 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.campbell, xen-devel
Wei Liu writes ("[PATCH V5 30/32] libxl: consider force removal of device successful"):
> The current behavior of libxl to remove a device is, if the backend
> times out, libxl will initiate a force removal (destroy) of that device.
> However, libxl still returns failure in that case, even if the force
> removal was successful.
>
> If a device is force removed and the force removal succeeds, from
> guest's PoV this device is gone. Libxl should consider this a
> successful case as well.
I think that the problem should be reported to the caller somehow. I
would invent a new libxl status code.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-13 21:54 ` [PATCH V5 31/32] libxl: update domain configuration when updating memory targets Wei Liu
2014-05-20 14:32 ` Ian Campbell
@ 2014-05-20 15:21 ` Ian Jackson
2014-05-20 15:35 ` Ian Campbell
2014-06-01 20:22 ` Wei Liu
1 sibling, 2 replies; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:21 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.campbell, xen-devel
Wei Liu writes ("[PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
...
> @@ -4005,6 +4024,14 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
> goto out;
> }
>
> + {
> + LOAD_DOMAIN_CONFIG(domid);
> +
> + d_config.b_info.max_memkb = max_memkb;
> +
> + STORE_DOMAIN_CONFIG(domid);
I think this is a fundamentally hazardous way to deal with domain
configuration updates.
The result is that there are two places where the domain's maximum
memory is recorded - the actual running domain state, and the saved
json configuration. In error situations it is possible for these to
become out of step.
What you should do instead is have the domain configuration retrieval
code (currently known as libxl_load_domain_configuration) do
xc_domain_getmaxmem (or whatever it is) and update the value in the
config data it is about to return.
That way there is only one place where the maxmem information is
stored. (There is of course another copy in the json config state but
it will always be ignored so can be disregarded.) So it is not
possible for the system to be in an inconsistent state.
The same considerations apply to device addition and removal, vif MAC
address update, etc.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 15:13 ` Ian Jackson
@ 2014-05-20 15:31 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 15:31 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, xen-devel
On Tue, 2014-05-20 at 16:13 +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 29/32] xl: use "libxl-json" format"):
> > On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > > Tests done so far (xl.{new,old} denotes xl with{,out} "xl_json"
> > > support):
> > >
> > > 1. xl.new create then xl.new save, hexdump saved file: domain config
> > > saved in JSON format
> > > 2. xl.new create, xl.new save then xl.old restore: failed on
> > > mandatory flag check
> > > 3. xl.new create, xl.new save then xl.new restore: succeeded
> > > 4. xl.old create, xl.old save then xl.new restore: succeeded
> > > 5. xl.new create then local migrate, receiving end xl.new: succeeded
> > > 6. xl.old create then local migrate, receiving end xl.new: succeeded
> >
> > I think xl.old create, xl.new save, xl.new restore would be interesting
> > (it should work I think)
>
> The first xl.new won't find the stored json domain config, so no. But
> this isn't something you're supposed to be able to do between Xen
> releases (because new tools means new hypervisor so a reboot).
Yes, I was thinking in a developer oriented way where I'm too lazy to
reboot ;-)
> > For cases like #4 and #6 if you subsequently save the domain does it use
> > xl or libxl-json? What I'm asking is does the oldness persist forever or
> > is it laundered out (which in turn feeds into how long old support needs
> > to stay in the tree...)
>
> AIUI it gets laundered out.
Good!
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device
2014-05-13 21:54 ` [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device Wei Liu
2014-05-20 14:35 ` Ian Campbell
@ 2014-05-20 15:33 ` Ian Jackson
2014-06-01 20:57 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:33 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.campbell, xen-devel
Wei Liu writes ("[PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device"):
> This approach cannot deal with half-baked device state (say, if AO
> returns success but for various reasons other parts just fail and we
> have some xenstore entries written / resource allocated). However we
> cannot make thing worse as the original code cannot handle that either.
> The good side of this approach is that in the future we can compare the
> stored configuration and xenstore entries to spot any half-baked device
> state so it can help fix that issue in the future.
I'm still concerned about this.
And seeing the code which results from doing it this way hasn't really
convinced me otherwise. These macros are going to need to be adjusted
again.
Wouldn't it be better to write something which can merge (a) the
information currently obtained by libxl_device_disk_list,
libxl__device_disk_from_xs_be et al and (b) the new JSON
configuration ?
Then you could arrange to add the device to the JSON config before
doing anything else, and remove it afterwards, and then there would be
no undesirable states etc.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 15:21 ` Ian Jackson
@ 2014-05-20 15:35 ` Ian Campbell
2014-05-20 15:44 ` Ian Jackson
2014-06-01 20:22 ` Wei Liu
1 sibling, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 15:35 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, xen-devel
On Tue, 2014-05-20 at 16:21 +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ...
> > @@ -4005,6 +4024,14 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
> > goto out;
> > }
> >
> > + {
> > + LOAD_DOMAIN_CONFIG(domid);
> > +
> > + d_config.b_info.max_memkb = max_memkb;
> > +
> > + STORE_DOMAIN_CONFIG(domid);
>
> I think this is a fundamentally hazardous way to deal with domain
> configuration updates.
>
> The result is that there are two places where the domain's maximum
> memory is recorded - the actual running domain state, and the saved
> json configuration. In error situations it is possible for these to
> become out of step.
>
> What you should do instead is have the domain configuration retrieval
> code (currently known as libxl_load_domain_configuration) do
> xc_domain_getmaxmem (or whatever it is) and update the value in the
> config data it is about to return.
>
> That way there is only one place where the maxmem information is
> stored. (There is of course another copy in the json config state but
> it will always be ignored so can be disregarded.) So it is not
> possible for the system to be in an inconsistent state.
>
> The same considerations apply to device addition and removal, vif MAC
> address update, etc.
The device cases in particular are a lot harder to handle in that way.
This was how I originally envisaged this would work, Wei's approach
seemed to me to be much much simpler.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 15:15 ` Ian Campbell
@ 2014-05-20 15:39 ` Ian Jackson
2014-06-01 19:18 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:39 UTC (permalink / raw)
To: Ian Campbell; +Cc: Wei Liu, xen-devel
Ian Campbell writes ("Re: [PATCH V5 29/32] xl: use "libxl-json" format"):
> On Tue, 2014-05-20 at 16:11 +0100, Ian Jackson wrote:
> > Firstly, I think this editing of libxl's copy of domain config way is
> > a layering violation.
> >
> > But it ought to be unnecessary, because either libxl_domain_rename
>
> That would lend credence to the idea that these functions ought to be
> internal to the library, or at least the store one should (get is still
> useful to applications I suppose, e.g. xl list).
Indeed.
> > or "libxl_load_domain_configuration" should deal with it. I would
> > much prefer the latter, as that results in the domain name being
> > stored only in one place.
>
> You mean libxl_load_dmoain_config should have special handling for
> domains names ending --incoming (or --.* perhaps)? That doesn't seem
> right, I suspect you meant something else.
No, that's not what I mean.
I mean that libxl_load_domain_config[1] should obtain the actual
domain name from xenstore, the same way that libxl_domid_to_name does,
and put it into the retreived configuration.
Ian.
[1] should probably be called libxl_get_domain_config or something
like that, because "load" might suggest "loading" the config into the
system to make it effective.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 15:35 ` Ian Campbell
@ 2014-05-20 15:44 ` Ian Jackson
2014-05-20 15:55 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 15:44 UTC (permalink / raw)
To: Ian Campbell; +Cc: Wei Liu, xen-devel
Ian Campbell writes ("Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> The device cases in particular are a lot harder to handle in that way.
> This was how I originally envisaged this would work, Wei's approach
> seemed to me to be much much simpler.
Much of the work of turning the xenstore info for a device back into a
libxl_disk_device or whatever has already been done: see e.g.
libxl__device_disk_from_xs_be.
Merging the lists from libxl_device_disk_list and the JSON
configuration shouldn't be too hard and will eliminate a lot of worry
about races.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 15:44 ` Ian Jackson
@ 2014-05-20 15:55 ` Ian Campbell
2014-05-20 16:03 ` Ian Jackson
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-05-20 15:55 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, xen-devel
On Tue, 2014-05-20 at 16:44 +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> > The device cases in particular are a lot harder to handle in that way.
> > This was how I originally envisaged this would work, Wei's approach
> > seemed to me to be much much simpler.
>
> Much of the work of turning the xenstore info for a device back into a
> libxl_disk_device or whatever has already been done: see e.g.
> libxl__device_disk_from_xs_be.
For example this would omit the distinction between the user asking for
a default backend and them asking for a specific one. If the user asked
for the default then the receiving xl would end up inheriting the
sending xl's decision, which is not correct.
So the original configuration, before setdefaults etc, needs to be
stored somewhere that it can be retrieved. Same goes for a lot of fields
I think.
> Merging the lists from libxl_device_disk_list and the JSON
> configuration shouldn't be too hard and will eliminate a lot of worry
> about races.
I think the presence of defaults in the libxl API makes it hard.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 15:55 ` Ian Campbell
@ 2014-05-20 16:03 ` Ian Jackson
2014-05-21 8:38 ` Ian Campbell
2014-06-01 20:51 ` Wei Liu
0 siblings, 2 replies; 127+ messages in thread
From: Ian Jackson @ 2014-05-20 16:03 UTC (permalink / raw)
To: Ian Campbell; +Cc: Wei Liu, xen-devel
Ian Campbell writes ("Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> On Tue, 2014-05-20 at 16:44 +0100, Ian Jackson wrote:
> > Merging the lists from libxl_device_disk_list and the JSON
> > configuration shouldn't be too hard and will eliminate a lot of worry
> > about races.
>
> I think the presence of defaults in the libxl API makes it hard.
What I'm suggesting for the implementation of "get list of disks for
retreived configuration" is something like this:
* Read JSON with list of stored disk configs
* Iterate over actual devices a la libxl_device_disk_list
* For each device, look for corresponding configuration in
disk config.
* If no such configuration, print a warning and make one up
along the lines of libxl_device_disk_getinfo
* If there was such a configuration, update the dynamically
adjustable fields by copying them from xenstore:
* currently, I think this is only the backing device
info (which can be modified dynamically for cds at least)
* Add resulting disk config to new list of disk configs
* Replace stored list of disk configs with new one
The effect is that the pre-defaulted configuration takes precedence
but that it is safe to write a JSON configuration containing devices
which are about to be added.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 19/32] libxl/gentypes.py: don't generate default values
2014-05-20 13:29 ` Ian Campbell
@ 2014-05-20 17:17 ` Wei Liu
2014-05-21 8:31 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-05-20 17:17 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 02:29:09PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > If a type has init_val defined and a field of the type has the value of
> > init_val, there's no need to generate output for that field.
>
> Please can you explain why there is no need. And I think you need to
> mention JSON here somewhere.
>
Sure.
"If a type has init_val defined and a field of the type has the value of
init_val, there's no need to generate output for that field in JSON
output. When the parser consumes that generated JSON object, all default
values should be automatically filled in."
> > Also define a bunch of init_vals for enumeration types.
>
> I'm not convinced by this. If a type has no initval then you should
> compare it to zero, which is a valid thing to do even for an enum.
>
What I really did here for enum type was to replace magic number 0 (or
any other predefined value) with a meaningful macro, so that the
generated code can have
if (FOO == LIBXL_FOO_DEFAULT)
other than
if (FOO == 0)
which has better readability.
> NB you changed the init_val for some typesto (e.g. from 1 to
> LIBXL_VGA_INTERFACE_TYPE_CIRRUS), which is a no semantic change change,
> but did mean I had to double check.
>
Corret, I didn't intend to make any semantic changes.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function
2014-05-20 14:47 ` Ian Jackson
@ 2014-05-20 17:24 ` Wei Liu
2014-05-21 8:27 ` Ian Campbell
2014-05-21 8:37 ` Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function) Ian Campbell
0 siblings, 2 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-20 17:24 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, Ian Campbell, xen-devel
On Tue, May 20, 2014 at 03:47:42PM +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function"):
> > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> >
> > Acked-by: Ian Campbell <ian.campbell@citrix.com>
> >
> > I'm unsure whether additions to libxl_utils.h should have a
> > corresponding #define LIBXL_HAVE.
>
> Yes, I think they probably should.
>
I will have the following snippet in libxl.h
/* LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID
*
* If this is defined, libxl has a library function called
* libxl_cpupool_qualifier_to_cpupoolid, which takes in a CPU pool
* qualifier in the form of number or string, then returns the ID of
* that CPU pool.
*/
#define LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID 1
Do you think it is OK? Can I retain Ian's ack?
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function
2014-05-20 17:24 ` Wei Liu
@ 2014-05-21 8:27 ` Ian Campbell
2014-05-21 8:37 ` Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function) Ian Campbell
1 sibling, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-21 8:27 UTC (permalink / raw)
To: Wei Liu; +Cc: Ian Jackson, xen-devel
On Tue, 2014-05-20 at 18:24 +0100, Wei Liu wrote:
> On Tue, May 20, 2014 at 03:47:42PM +0100, Ian Jackson wrote:
> > Ian Campbell writes ("Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function"):
> > > On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> > > > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> > >
> > > Acked-by: Ian Campbell <ian.campbell@citrix.com>
> > >
> > > I'm unsure whether additions to libxl_utils.h should have a
> > > corresponding #define LIBXL_HAVE.
> >
> > Yes, I think they probably should.
Actually I was confusing libxl_utils.h with libxlu_*.h here.
libxl_utils.h is part of libxl proper so you are of course correct.
> I will have the following snippet in libxl.h
>
> /* LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID
> *
> * If this is defined, libxl has a library function called
> * libxl_cpupool_qualifier_to_cpupoolid, which takes in a CPU pool
> * qualifier in the form of number or string, then returns the ID of
> * that CPU pool.
> */
> #define LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID 1
>
> Do you think it is OK? Can I retain Ian's ack?
Ack.
>
> Wei.
>
> > Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 19/32] libxl/gentypes.py: don't generate default values
2014-05-20 17:17 ` Wei Liu
@ 2014-05-21 8:31 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-21 8:31 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-20 at 18:17 +0100, Wei Liu wrote:
> On Tue, May 20, 2014 at 02:29:09PM +0100, Ian Campbell wrote:
> > On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > > If a type has init_val defined and a field of the type has the value of
> > > init_val, there's no need to generate output for that field.
> >
> > Please can you explain why there is no need. And I think you need to
> > mention JSON here somewhere.
> >
>
> Sure.
>
> "If a type has init_val defined and a field of the type has the value of
> init_val, there's no need to generate output for that field in JSON
> output. When the parser consumes that generated JSON object, all default
> values should be automatically filled in."
Ack.
> > > Also define a bunch of init_vals for enumeration types.
> >
> > I'm not convinced by this. If a type has no initval then you should
> > compare it to zero, which is a valid thing to do even for an enum.
> >
>
> What I really did here for enum type was to replace magic number 0 (or
> any other predefined value) with a meaningful macro, so that the
> generated code can have
> if (FOO == LIBXL_FOO_DEFAULT)
> other than
> if (FOO == 0)
> which has better readability.
I'm more concerned with the readability of the .idl files than the
generated code. I think having to specify defaults for everything harms
that.
I think if (FOO) and if (!FOO) are perfectly fine in the generated code
for the cases where there is no init_val. Likewise == 0 or != 0.
I wouldn't object to the code noticing that there was no init_val and
doing a lookup for the name given to 0 so it could use it (if it
exists), but that seems like unnecessary work in the code generator.
> > NB you changed the init_val for some typesto (e.g. from 1 to
> > LIBXL_VGA_INTERFACE_TYPE_CIRRUS), which is a no semantic change change,
> > but did mean I had to double check.
> >
>
> Corret, I didn't intend to make any semantic changes.
Could you just note in the commit log that there are cases of switching
to the named init_val from a numeric one as well as adding new init_vals
(assuming there is any need to add new ones after hte above comments are
taken into account)
Thanks,
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function)
2014-05-20 17:24 ` Wei Liu
2014-05-21 8:27 ` Ian Campbell
@ 2014-05-21 8:37 ` Ian Campbell
2014-05-22 9:35 ` George Dunlap
2014-05-27 23:04 ` Wei Liu
1 sibling, 2 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-21 8:37 UTC (permalink / raw)
To: Wei Liu; +Cc: Ian Jackson, xen-devel
On Tue, 2014-05-20 at 18:24 +0100, Wei Liu wrote:
> I will have the following snippet in libxl.h
>
> /* LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID
> *
> * If this is defined, libxl has a library function called
> * libxl_cpupool_qualifier_to_cpupoolid, which takes in a CPU pool
> * qualifier in the form of number or string, then returns the ID of
> * that CPU pool.
> */
> #define LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID 1
I have a more general comment/thought about these LIBXL_HAVE comments.
We've gotten into this pattern of adding a little bit of commentary to
these comments (I think just because the first one happened too look
this way) which either duplicate things which seem more or less obvious
(LIBXL_HAVE_FOO_BAR => The struct FOO has a field BAR) or, worse, add
documentation of that field which really belongs at the site of the
field definition not here.
Does anyone else thing that the comments associated with these defines
should be terse and/or non-existent and that the bulk of most of them
belongs next to the definition of the field/function in question?
NB: I'm in no way suggesting that anything in this series needs to
change because of this...
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 16:03 ` Ian Jackson
@ 2014-05-21 8:38 ` Ian Campbell
2014-06-01 20:51 ` Wei Liu
1 sibling, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-21 8:38 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, xen-devel
On Tue, 2014-05-20 at 17:03 +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> > On Tue, 2014-05-20 at 16:44 +0100, Ian Jackson wrote:
> > > Merging the lists from libxl_device_disk_list and the JSON
> > > configuration shouldn't be too hard and will eliminate a lot of worry
> > > about races.
> >
> > I think the presence of defaults in the libxl API makes it hard.
>
> What I'm suggesting for the implementation of "get list of disks for
> retreived configuration" is something like this:
>
> * Read JSON with list of stored disk configs
>
> * Iterate over actual devices a la libxl_device_disk_list
> * For each device, look for corresponding configuration in
> disk config.
> * If no such configuration, print a warning and make one up
> along the lines of libxl_device_disk_getinfo
> * If there was such a configuration, update the dynamically
> adjustable fields by copying them from xenstore:
> * currently, I think this is only the backing device
> info (which can be modified dynamically for cds at least)
> * Add resulting disk config to new list of disk configs
>
> * Replace stored list of disk configs with new one
>
> The effect is that the pre-defaulted configuration takes precedence
> but that it is safe to write a JSON configuration containing devices
> which are about to be added.
It sounds workable to me, but I'll leave it up to Wei to poke holes in
it since he has been closer to this stuff...
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
` (31 preceding siblings ...)
2014-05-13 21:54 ` [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device Wei Liu
@ 2014-05-21 10:18 ` Ian Campbell
32 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-05-21 10:18 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-05-13 at 22:53 +0100, Wei Liu wrote:
> This series contains all patches necessary to fully preserve domain
> configurations across save / restore.
I've cherry-picked and applied:
1f77529 libxl_json: allow basic JSON type objects generation
d638671 libxl_internal.h: introduce libxl__json_object_get_number
7dd6000 libxl_internal.h: introduce libxl__json_object_is_{null, number, double
f68570a libxl_internal: make JSON_* types a bit-field
a84725c libxl_internal.h: move / add some libxl defbool #define here
fe54fc1 libxl.h: document libxl_<type>_to_json
00bfad1 libxl.h: document the paradigm of using libxl types
e620f2d libxl: fix memory leak in libxl_cpuid_dispose
I think that corresponds to patches 6-9, 13-15 and 17.
I did also look at
#11 libxl IDL: rename json_fn to json_gen_fn
#12 libxl_json: introduce libxl__object_from_json
#16 libxl_json: introduce parser functions for builtin types
but they tripped over missing previous patches (mostly in minor seeming
ways, e.g .#11 depends in a trivially fixable way on #10 "libxl: fix
JSON generator for uint64_t" but I didn't want to risk it)
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function)
2014-05-21 8:37 ` Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function) Ian Campbell
@ 2014-05-22 9:35 ` George Dunlap
2014-05-27 23:04 ` Wei Liu
1 sibling, 0 replies; 127+ messages in thread
From: George Dunlap @ 2014-05-22 9:35 UTC (permalink / raw)
To: Ian Campbell; +Cc: Ian Jackson, Wei Liu, xen-devel@lists.xen.org
On Wed, May 21, 2014 at 9:37 AM, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> On Tue, 2014-05-20 at 18:24 +0100, Wei Liu wrote:
>> I will have the following snippet in libxl.h
>>
>> /* LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID
>> *
>> * If this is defined, libxl has a library function called
>> * libxl_cpupool_qualifier_to_cpupoolid, which takes in a CPU pool
>> * qualifier in the form of number or string, then returns the ID of
>> * that CPU pool.
>> */
>> #define LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID 1
>
> I have a more general comment/thought about these LIBXL_HAVE comments.
> We've gotten into this pattern of adding a little bit of commentary to
> these comments (I think just because the first one happened too look
> this way) which either duplicate things which seem more or less obvious
> (LIBXL_HAVE_FOO_BAR => The struct FOO has a field BAR) or, worse, add
> documentation of that field which really belongs at the site of the
> field definition not here.
>
> Does anyone else thing that the comments associated with these defines
> should be terse and/or non-existent and that the bulk of most of them
> belongs next to the definition of the field/function in question?
Hmm, that's an interesting idea. I'd have to think about it some
more, but there does seem to be some sense to doing things that way,
and I don't immediately see an objection.
-George
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function)
2014-05-21 8:37 ` Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function) Ian Campbell
2014-05-22 9:35 ` George Dunlap
@ 2014-05-27 23:04 ` Wei Liu
1 sibling, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-05-27 23:04 UTC (permalink / raw)
To: Ian Campbell; +Cc: Ian Jackson, Wei Liu, xen-devel
On Wed, May 21, 2014 at 09:37:31AM +0100, Ian Campbell wrote:
> On Tue, 2014-05-20 at 18:24 +0100, Wei Liu wrote:
> > I will have the following snippet in libxl.h
> >
> > /* LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID
> > *
> > * If this is defined, libxl has a library function called
> > * libxl_cpupool_qualifier_to_cpupoolid, which takes in a CPU pool
> > * qualifier in the form of number or string, then returns the ID of
> > * that CPU pool.
> > */
> > #define LIBXL_HAVE_CPUPOOL_QUALIFIER_TO_CPUPOOLID 1
>
> I have a more general comment/thought about these LIBXL_HAVE comments.
> We've gotten into this pattern of adding a little bit of commentary to
> these comments (I think just because the first one happened too look
> this way) which either duplicate things which seem more or less obvious
> (LIBXL_HAVE_FOO_BAR => The struct FOO has a field BAR) or, worse, add
> documentation of that field which really belongs at the site of the
> field definition not here.
>
> Does anyone else thing that the comments associated with these defines
> should be terse and/or non-existent and that the bulk of most of them
> belongs next to the definition of the field/function in question?
>
I don't object to eliminating these comments, but I don't see problem
with the way it is now either...
Wei.
> NB: I'm in no way suggesting that anything in this series needs to
> change because of this...
>
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct
2014-05-20 13:35 ` Ian Campbell
@ 2014-06-01 17:43 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 17:43 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 02:35:02PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > libxl_FOO_parse_json functions are generated.
> >
> > Note that these functions are used to parse libxl__json_object to
> > libxl__FOO struct. They don't consume JSON string.
> >
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
>
> I eyeballed this again and the only query I have is this:
>
> + if (libxl__json_map_get("enable", o, JSON_STRING)) {
> + x = libxl__json_map_get("enable", o, JSON_STRING);
>
> These two get calls are a bit redundant.
>
> Looking at the code generator I don't think it forces this on you and
> you could arrange instead for:
> x = libxl__json_map_get("enable", o, JSON_STRING);
> if (x) {
> ...
>
> Perhaps you need to save x in a new local parent so you can restore it
> in that case.
> saved_parent = x;
> x = libxl__json_map_get("enable", o, JSON_STRING);
> if (x) {
> ...
> }
> x = saved_parent;
>
Done.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-05-20 14:03 ` Ian Campbell
@ 2014-06-01 18:41 ` Wei Liu
2014-06-02 16:19 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-01 18:41 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 03:03:56PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > Introduce a new format in libxl userdata store called "libxl-json". This
> > format contains the deserialized version of domain configuration of a
> > domain.
> >
> > Two libxl functions to load and store domain configuration are also
> > introduced. They use the new "libxl-json" format.
>
> Is the intention that application should use these to read/modify/write
> the domain config on changes, as opposed to it being internal
> functionality which libxl should use to keep things up to date?
>
I think it is a valid usecase that a user of libxl wants to know
libxl's view of a guest's configuration, and I think user is free to
manipulate that view if it wants to.
Xl does this in later patch, when it migrate a domain the name is
modified to "XX--incoming" then changed back to "XX".
> >
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> > ---
> > tools/libxl/libxl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > tools/libxl/libxl.h | 10 ++++++++
> > 2 files changed, 78 insertions(+)
> >
> > diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> > index c9475d7..b578a5c 100644
> > --- a/tools/libxl/libxl.c
> > +++ b/tools/libxl/libxl.c
> > @@ -5751,6 +5751,74 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src)
> > for (i = 0; i < 6; i++)
> > (*dst)[i] = (*src)[i];
> > }
> > +
> > +int libxl_load_domain_configuration(libxl_ctx *ctx, uint32_t domid,
> > + libxl_domain_config *d_config)
> > +{
> > + GC_INIT(ctx);
> > + uint8_t *data;
> > + int rc, len;
> > +
> > + rc = libxl_userdata_retrieve(ctx, domid, "libxl-json", &data, &len);
> > + if (rc) {
> > + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
>
> You can use LOGEV here to shorten lines and loge below etc.
>
OK.
> > + "Failed to retrieve domain configuration for domain %d",
> > + domid);
> > + rc = ERROR_FAIL;
> > + goto out;
> > + }
> > +
> > + if (len == 0) {
> > + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
>
> > + "Configuration data stream empty for domain %d",
> > + domid);
> > + rc = ERROR_FAIL;
> > + goto out;
> > + }
> > +
> > + /* Make sure this string ends with \0 -- the parser expects a NULL
> > + * terminated string.
>
> Could this be achieved by strlen(d_config_json)+1 when saving? Assuming
> that string is NULL terminated.
>
I need to try. If it works then I will switch to that.
> > + */
> > + if (data[len-1] != '\0') {
> > + data = libxl__realloc(gc, data, len + 1);
> > + data[len] = '\0';
> > + }
> > +
> > + rc = libxl_domain_config_from_json(ctx, d_config, (const char *)data);
> > +
> > +out:
> > + free(data);
>
> data might have been libxl__realloc'd above, so isn't it gc'd?
>
No, it's malloc'ed in libxl_read_file_contents.
> > + GC_FREE;
> > + return rc;
> > +}
> > +
[...]
> > * Local variables:
> > * mode: C
> > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> > index d5dfe2e..be722b6 100644
> > --- a/tools/libxl/libxl.h
> > +++ b/tools/libxl/libxl.h
> > @@ -1140,6 +1140,8 @@ void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid,
> > * "xl" domain config file in xl format, Unix line endings
> > * "libvirt-xml" domain config file in libvirt XML format. See
> > * http://libvirt.org/formatdomain.html
> > + * "libxl-json" domain config file in JSON format, generated by
> > + * libxl
>
> I think I would mention libxl_domain_config. Something like
> "libxl_domain_config object in JSON format, generated by libxl."
> perhaps.
>
OK.
Wei.
>
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-05-20 15:01 ` Ian Jackson
@ 2014-06-01 18:46 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 18:46 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, ian.campbell, xen-devel
On Tue, May 20, 2014 at 04:01:28PM +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions"):
> > Introduce a new format in libxl userdata store called "libxl-json". This
> > format contains the deserialized version of domain configuration of a
> > domain.
>
> I don't think "deserialised" means what you think it means here.
> JSON is a data structure serialisation format. So the structure is
> serialised, not deserialised. But it would be better to just say "the
> JSON version" or some such.
>
OK.
> I don't think I understand what role these two functions play in the
> public API. libxl_load_domain_configuration doesn't really "load" a
> configuration; it obtains the configuration of a running domain. But
> at the moment it doesn't do anything unless store has been called.
>
How about calling it "retrieve"? I'm pretty bad at naming things.
> I can't see why an application would ever want to call
> libxl_store_domain_configuration. If it did, what would it mean ?
>
Xl needs to manipulate domain configuration when it migrates a
domain. The receiving end first modifies domain name to "XX--incoming",
then modifies the name back to "XX".
This kind of application specified behavior (the migration protocol
itself) is certainly not part of libxl, so we need to privode to method
let the application update libxl stored configuration as needed.
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain
2014-05-20 14:12 ` Ian Campbell
@ 2014-06-01 19:02 ` Wei Liu
2014-06-02 16:21 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-01 19:02 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 03:12:18PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > This patch utilizes "libxl-json" format and helper functions introduced
> > in previous patch to store up-to-do domain configuration when creating a
> > domain.
> >
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
>
> This seems to end up saving the domain config 2 or even 3 times. I think
> we need an explanation as to why that is.
>
Twice (see below).
> Also we need to know what the invariants are, what must (not) change
> either before or after each sequencing point, what must be in each
> update etc.
>
The first save is the vanilla copy, that's what the user provides.
Then udpate_domain_config is called to pull in everything that may get
changed by libxl to the vanilla copy. What's pulled in is documented in
update_domain_config.
The second save saves the updated version.
> Can you not save the raw version at the start (before anything has
> touched it) and then do the domid, uuid, mac, vtpm etc all at the end in
> domcreate_complete? (Don't you do the uuid twice? The comments mention
> it twice)
>
I don't follow. I think this is what being done at the moment. The
vanilla domain configuration is saved at the beginning of domain
creation then updated when domain creation completes. It's exactly what
you suggested.
Re UUID, no. Domain UUID and UUID for devices are different things.
> > +static void update_domain_config(libxl_ctx *ctx,
>
> Internal functions should take a libxl__gc not a ctx.
>
OK.
> > @@ -1366,6 +1400,25 @@ static void domcreate_complete(libxl__egc *egc,
> > if (!rc && d_config->b_info.exec_ssidref)
> > rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref);
> >
> > + if (!rc) {
> > + libxl_domain_config d_config_saved;
> > +
> > + libxl_domain_config_init(&d_config_saved);
> > + rc = libxl_load_domain_configuration(CTX, dcs->guest_domid,
> > + &d_config_saved);
> > + if (rc) {
> > + LOG(ERROR, "cannot load domain configuration: %d", rc);
> > + goto out;
> > + }
> > + update_domain_config(CTX, &d_config_saved, d_config);
> > + rc = libxl_store_domain_configuration(CTX, dcs->guest_domid,
> > + &d_config_saved);
> > + if (rc)
> > + LOG(ERROR, "cannot store domain configuration: %d", rc);
> > + libxl_domain_config_dispose(&d_config_saved);
>
> Unless you are sure this is the only place this will be needed A helper
> of the form libxl__domain_config_update(gc, &update_domain_config, data)
> might be useful. i.e. read, call a callback, write. data is a void *
> passed to the update_domain_config callback.
>
This form might be useful in later patch as well. I will see what I can
do.
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 15:11 ` Ian Jackson
2014-05-20 15:15 ` Ian Campbell
@ 2014-06-01 19:07 ` Wei Liu
2014-06-02 16:23 ` Ian Campbell
1 sibling, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-01 19:07 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, ian.campbell, xen-devel
On Tue, May 20, 2014 at 04:11:44PM +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 29/32] xl: use "libxl-json" format"):
> > Before this change, xl stores domain configuration in "xl" format, which
> > is in fact a verbatim copy of user supplied domain config.
> ...
> > + /* If we're doing migration, the domain name was appended with
> > + * "--incoming" a few lines above. So we need to remove that
> > + * suffix in the stored configuration.
> > + */
> > + if (migrate_fd >= 0) {
> > + libxl_domain_config d;
> > + int xlen = strlen("--incoming");
> > + int orig_len;
> > +
> > + ret = libxl_load_domain_configuration(ctx, domid, &d);
>
> Firstly, I think this editing of libxl's copy of domain config way is
> a layering violation.
>
> But it ought to be unnecessary, because either libxl_domain_rename
> or "libxl_load_domain_configuration" should deal with it. I would
> much prefer the latter, as that results in the domain name being
> stored only in one place.
>
Huh? I suppose to avoid "layering violation" I should make
libxl_domain_rename manipulate the stored configuration, shouldn't I?
But you're suggesting I make libxl_load_domain_configuration work?
I'm confused.
Wei.
> I mostly agree with Ian's comments.
>
> Thanks,
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 15:39 ` Ian Jackson
@ 2014-06-01 19:18 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 19:18 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, Ian Campbell, xen-devel
On Tue, May 20, 2014 at 04:39:42PM +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 29/32] xl: use "libxl-json" format"):
> > On Tue, 2014-05-20 at 16:11 +0100, Ian Jackson wrote:
> > > Firstly, I think this editing of libxl's copy of domain config way is
> > > a layering violation.
> > >
> > > But it ought to be unnecessary, because either libxl_domain_rename
> >
> > That would lend credence to the idea that these functions ought to be
> > internal to the library, or at least the store one should (get is still
> > useful to applications I suppose, e.g. xl list).
>
> Indeed.
>
> > > or "libxl_load_domain_configuration" should deal with it. I would
> > > much prefer the latter, as that results in the domain name being
> > > stored only in one place.
> >
> > You mean libxl_load_dmoain_config should have special handling for
> > domains names ending --incoming (or --.* perhaps)? That doesn't seem
> > right, I suspect you meant something else.
>
> No, that's not what I mean.
>
> I mean that libxl_load_domain_config[1] should obtain the actual
> domain name from xenstore, the same way that libxl_domid_to_name does,
> and put it into the retreived configuration.
>
> Ian.
>
> [1] should probably be called libxl_get_domain_config or something
> like that, because "load" might suggest "loading" the config into the
> system to make it effective.
(I should've looked at the whole thread before sending my previous
email)
In this case the stored version has "--incoming" suffix. I would still
prefer we have everything in one place, that is, in the stored JSON
version, so that other functions only need to use "get" to get hold of
the current configuration.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-05-20 14:23 ` Ian Campbell
2014-05-20 15:13 ` Ian Jackson
@ 2014-06-01 19:37 ` Wei Liu
2014-06-02 16:30 ` Ian Campbell
1 sibling, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-01 19:37 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 03:23:26PM +0100, Ian Campbell wrote:
[...]
> > @@ -1787,13 +1770,10 @@ static int handle_domain_death(uint32_t *r_domid,
> > break;
> >
> > case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
> > - reload_domain_config(*r_domid, config_data, config_len);
> > restart = 2;
> > break;
> >
> > case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
> > - reload_domain_config(*r_domid, config_data, config_len);
>
> Why is it not equally necessary to reload the JSON config at this point
> if it exists?
>
Because domain configuration is loaded in the caller of
handle_domain_death now.
> (commit message should explain this, and in general anywhere that the
> need to reload/refresh the config differs, because my expectation was of
> a more straight forward substitution of reload_domain_config for the new
> function).
>
No problem.
> > -
> > restart = 1;
> > /* fall-through */
> > case LIBXL_ACTION_ON_SHUTDOWN_DESTROY:
> [...]
> > - parse_config_data(config_source, config_data, config_len, &d_config);
> > + if (config_in_json) {
> > + char *config_c = config_data;
> > + if (config_c[config_len-1] != '\0') {
> > + config_c = xrealloc(config_c, config_len + 1);
> > + config_c[config_len] = '\0';
>
> I think this is somewhere that arranging via the protocol that things
> must be null terminated might make sense.
>
Sure, if I can manage to arrange saving extra "\0" at the end of stream.
> > + /* If we're doing migration, the domain name was appended with
> > + * "--incoming" a few lines above. So we need to remove that
> > + * suffix in the stored configuration.
>
> It's not possible to save this before we do that appending?
>
The save is done by libxl, when we create domain. At this point we are
still in xl.
> Or should we not be updating the domain config as we do the renaming at
> the end?
>
I agree that libxl_domain_rename is a better place to update stored
domain name.
> > + */
> > + if (migrate_fd >= 0) {
> > + libxl_domain_config d;
> > + int xlen = strlen("--incoming");
> > + int orig_len;
> > +
> > + ret = libxl_load_domain_configuration(ctx, domid, &d);
> > + if (ret) {
> > + perror("cannot load config data");
> > + ret = ERROR_FAIL;
> > + goto error_out;
> > + }
> > +
> > + orig_len = strlen(d.c_info.name);
> > + d.c_info.name = xrealloc(d.c_info.name, orig_len - xlen);
> > + d.c_info.name[orig_len - xlen] = 0;
>
> Since the new name is always shorter you could do this simply by
> sticking a \0 in the middle without needing to realloc.
Ack.
But this hunk will be gone if we make libxl_domain_rename capable of
storing new domain name.
>
> > @@ -3102,22 +3119,18 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
> > s = yajl_gen_status_ok;
> >
> > for (i = 0; i < nb_domain; i++) {
> > + libxl_domain_config_init(&d_config);
> > /* no detailed info available on dom0 */
> > if (info[i].domid == 0)
> > continue;
> > - rc = libxl_userdata_retrieve(ctx, info[i].domid, "xl", &data, &len);
> > + rc = libxl_load_domain_configuration(ctx, info[i].domid, &d_config);
>
> If a domain was created with xl.old will we not now fail to list details
> of it here?
>
Don't you need to restart if you install new tool? Is this a valid
usecase?
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 30/32] libxl: consider force removal of device successful
2014-05-20 14:26 ` Ian Campbell
@ 2014-06-01 19:44 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 19:44 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 03:26:59PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > The current behavior of libxl to remove a device is, if the backend
> > times out, libxl will initiate a force removal (destroy) of that device.
> > However, libxl still returns failure in that case, even if the force
> > removal was successful.
> >
> > If a device is force removed and the force removal succeeds, from
> > guest's PoV this device is gone. Libxl should consider this a
> > successful case as well.
>
> This seems reasonable.
>
> However the implementation confuses me. Perhaps this is one for Ian J,
> but let me see if I can work it out.
>
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> > ---
> > tools/libxl/libxl_device.c | 12 ++++++++++--
> > tools/libxl/libxl_internal.h | 4 ++++
> > 2 files changed, 14 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
> > index fa99f77..ce0b358 100644
> > --- a/tools/libxl/libxl_device.c
> > +++ b/tools/libxl/libxl_device.c
> > @@ -845,6 +845,11 @@ void libxl__initiate_device_remove(libxl__egc *egc,
> > if (rc < 0) goto out;
> > }
> >
> > + /* At this point the XS transaction is committed. So check if we were
> > + * force removing the device.
>
> Why does the fact that we were or not force committing relate to the XS
> transaction?
>
Force removal is in fact removing xenstore entries. If XS transcation
fails then force removal (if aodev->force == 1) also fails.
> > + */
> > + aodev->force_removed = aodev->force;
> > +
> > rc = libxl__ev_devstate_wait(gc, &aodev->backend_ds,
> > device_backend_callback,
> > state_path, XenbusStateClosed,
> > @@ -928,7 +933,7 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
> > return;
> > }
> >
> > - if (rc) {
> > + if (rc && !aodev->force_removed) {
> > LOG(ERROR, "unable to %s device with path %s",
> > libxl__device_action_to_string(aodev->action),
> > libxl__device_backend_path(gc, aodev->dev));
> > @@ -939,7 +944,10 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
> > return;
> >
> > out:
> > - aodev->rc = rc;
> > + /* If force removal is successful, the device is gone from guest's
> > + * PoV. Libxl should return success, too.
> > + */
> > + aodev->rc = aodev->force_removed ? 0 : rc;
>
> This is the bit which confuses me most. If the forced removal was
> successful, why was rc not 0 already in that case?
>
rc is ERROR_TIMEOUT in the senario stated in commit message IIRC.
> I'm also not sure where the case that the force remove also fails is.
> Perhaps it cannot possibly fail?
>
XS transaction can fail.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 30/32] libxl: consider force removal of device successful
2014-05-20 15:15 ` Ian Jackson
@ 2014-06-01 19:46 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 19:46 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, ian.campbell, xen-devel
On Tue, May 20, 2014 at 04:15:45PM +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 30/32] libxl: consider force removal of device successful"):
> > The current behavior of libxl to remove a device is, if the backend
> > times out, libxl will initiate a force removal (destroy) of that device.
> > However, libxl still returns failure in that case, even if the force
> > removal was successful.
> >
> > If a device is force removed and the force removal succeeds, from
> > guest's PoV this device is gone. Libxl should consider this a
> > successful case as well.
>
> I think that the problem should be reported to the caller somehow. I
> would invent a new libxl status code.
>
OK. I will see what I can do. Basically it means a new status code
meaning "libxl is asked to remove that device, but backend times out, so
libxl destroy that device instead".
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 14:32 ` Ian Campbell
@ 2014-06-01 20:00 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 20:00 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Tue, May 20, 2014 at 03:32:04PM +0100, Ian Campbell wrote:
> On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> > ---
> > tools/libxl/libxl.c | 36 ++++++++++++++++++++++++++++++++++++
> > 1 file changed, 36 insertions(+)
> >
> > diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> > index b578a5c..f93096b 100644
> > --- a/tools/libxl/libxl.c
> > +++ b/tools/libxl/libxl.c
> > @@ -3529,6 +3529,25 @@ out:
> >
> > /******************************************************************************/
> >
> > +/* Macro to load / store domain configuration. They must use in pair.
> > + * Load macro defines d_config that can be used by other code. Store
> > + * macro will dispose d_config.
> > + */
>
> I was asking for a helper earlier, I suppose this could be useful there
> too.
>
> TBH I think a helper fn and callback arrangement would be preferable to
> magic macros (macros only when there is no alternative I think). I
> suppose that would result in a plethora of little callback helpers
> though. Hrm, what do you think?
>
Yes. The downside is we need to have many helpers. But I think it is a
better approach.
> > +#define LOAD_DOMAIN_CONFIG(domid) \
> > + libxl_domain_config d_config; \
> > + libxl_domain_config_init(&d_config); \
> > + rc = libxl_load_domain_configuration(CTX, (domid), &d_config); \
> > + if (rc) \
> > + goto out; \
> > +
> > +#define STORE_DOMAIN_CONFIG(domid) \
> > + rc = libxl_store_domain_configuration(CTX, (domid), &d_config); \
> > + if (rc) { \
> > + libxl_domain_config_dispose(&d_config); \
> > + goto out; \
> > + } \
> > + libxl_domain_config_dispose(&d_config); \
>
> rc =
> libxl_domain_config_dispose
> if (rc)
> goto out;
>
> would work here I think, since dispose doesn't clobber rc.
>
Yes, you're right.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 15:21 ` Ian Jackson
2014-05-20 15:35 ` Ian Campbell
@ 2014-06-01 20:22 ` Wei Liu
2014-06-02 16:32 ` Ian Campbell
1 sibling, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-01 20:22 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, ian.campbell, xen-devel
On Tue, May 20, 2014 at 04:21:26PM +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> ...
> > @@ -4005,6 +4024,14 @@ int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
> > goto out;
> > }
> >
> > + {
> > + LOAD_DOMAIN_CONFIG(domid);
> > +
> > + d_config.b_info.max_memkb = max_memkb;
> > +
> > + STORE_DOMAIN_CONFIG(domid);
>
> I think this is a fundamentally hazardous way to deal with domain
> configuration updates.
>
> The result is that there are two places where the domain's maximum
> memory is recorded - the actual running domain state, and the saved
> json configuration. In error situations it is possible for these to
> become out of step.
>
> What you should do instead is have the domain configuration retrieval
> code (currently known as libxl_load_domain_configuration) do
> xc_domain_getmaxmem (or whatever it is) and update the value in the
> config data it is about to return.
>
So you're actually suggesting I use the store JSON config as tempalte
and tempalte only, then pull in other runtime information in retrieval
code, right? This is not what I thought in the first place. I was
expecting libxl-json file always stores the current up to date
configuration.
I can see your approach can work better than mine. My only concern is
that some curious user might want to poke at libxl-json file, i.e. try
to get domain configuration without programming against libxl API. But I
think that should be forbidden, right?
Wei.
> That way there is only one place where the maxmem information is
> stored. (There is of course another copy in the json config state but
> it will always be ignored so can be disregarded.) So it is not
> possible for the system to be in an inconsistent state.
>
> The same considerations apply to device addition and removal, vif MAC
> address update, etc.
>
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-05-20 16:03 ` Ian Jackson
2014-05-21 8:38 ` Ian Campbell
@ 2014-06-01 20:51 ` Wei Liu
1 sibling, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-01 20:51 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, Ian Campbell, xen-devel
On Tue, May 20, 2014 at 05:03:06PM +0100, Ian Jackson wrote:
> Ian Campbell writes ("Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets"):
> > On Tue, 2014-05-20 at 16:44 +0100, Ian Jackson wrote:
> > > Merging the lists from libxl_device_disk_list and the JSON
> > > configuration shouldn't be too hard and will eliminate a lot of worry
> > > about races.
> >
> > I think the presence of defaults in the libxl API makes it hard.
>
> What I'm suggesting for the implementation of "get list of disks for
> retreived configuration" is something like this:
>
> * Read JSON with list of stored disk configs
>
> * Iterate over actual devices a la libxl_device_disk_list
> * For each device, look for corresponding configuration in
> disk config.
> * If no such configuration, print a warning and make one up
> along the lines of libxl_device_disk_getinfo
> * If there was such a configuration, update the dynamically
> adjustable fields by copying them from xenstore:
> * currently, I think this is only the backing device
> info (which can be modified dynamically for cds at least)
> * Add resulting disk config to new list of disk configs
>
> * Replace stored list of disk configs with new one
>
This comes back to our discussion on half-baked state. I would say that
if a device doesn't exist in JSON but in xenstore, it shouldn't be
considered a valid device, so that we don't need to store it in config.
As I see it the most possible way for one device that exists in xenstore
but not JSON is that we've successfully added that device but failed to
store JSON configuration. Saving file seems to be the least possible
point of failure, compared to other operations. If we fail at any point
before saving config, which results in half-baked xenstore state, the
device is not valid.
This is still an open question though, as my code seems to be the first
instance to try to deal with it.
Wei.
> The effect is that the pre-defaulted configuration takes precedence
> but that it is safe to write a JSON configuration containing devices
> which are about to be added.
>
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device
2014-05-20 15:33 ` Ian Jackson
@ 2014-06-01 20:57 ` Wei Liu
2014-06-02 16:33 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-01 20:57 UTC (permalink / raw)
To: Ian Jackson; +Cc: Wei Liu, ian.campbell, xen-devel
On Tue, May 20, 2014 at 04:33:45PM +0100, Ian Jackson wrote:
> Wei Liu writes ("[PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device"):
> > This approach cannot deal with half-baked device state (say, if AO
> > returns success but for various reasons other parts just fail and we
> > have some xenstore entries written / resource allocated). However we
> > cannot make thing worse as the original code cannot handle that either.
> > The good side of this approach is that in the future we can compare the
> > stored configuration and xenstore entries to spot any half-baked device
> > state so it can help fix that issue in the future.
>
> I'm still concerned about this.
>
> And seeing the code which results from doing it this way hasn't really
> convinced me otherwise. These macros are going to need to be adjusted
> again.
>
> Wouldn't it be better to write something which can merge (a) the
> information currently obtained by libxl_device_disk_list,
> libxl__device_disk_from_xs_be et al and (b) the new JSON
> configuration ?
>
This is certainly doable. But again, what's the desirable state to
record? If a device's entry is present in xenstore then it must be
valid? It might be my misundertanding of how we should handle half-baked
state. We shall have further discussion...
> Then you could arrange to add the device to the JSON config before
> doing anything else, and remove it afterwards, and then there would be
> no undesirable states etc.
>
Sorry, it's unclear to me what you want me to do. Why do I need to
remove a device after I add it?
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-06-01 18:41 ` Wei Liu
@ 2014-06-02 16:19 ` Ian Campbell
2014-06-02 19:56 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-06-02 16:19 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Sun, 2014-06-01 at 19:41 +0100, Wei Liu wrote:
> On Tue, May 20, 2014 at 03:03:56PM +0100, Ian Campbell wrote:
> > On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > > Introduce a new format in libxl userdata store called "libxl-json". This
> > > format contains the deserialized version of domain configuration of a
> > > domain.
> > >
> > > Two libxl functions to load and store domain configuration are also
> > > introduced. They use the new "libxl-json" format.
> >
> > Is the intention that application should use these to read/modify/write
> > the domain config on changes, as opposed to it being internal
> > functionality which libxl should use to keep things up to date?
> >
>
> I think it is a valid usecase that a user of libxl wants to know
> libxl's view of a guest's configuration, and I think user is free to
> manipulate that view if it wants to.
I think the get method is fine. The set is more debatable though.
> Xl does this in later patch, when it migrate a domain the name is
> modified to "XX--incoming" then changed back to "XX".
I think Ian J commented on that too, perhaps for other reasons.
Anyway, this should happen in libxl_domain_rename, shouldn't it?
> > > + */
> > > + if (data[len-1] != '\0') {
> > > + data = libxl__realloc(gc, data, len + 1);
> > > + data[len] = '\0';
> > > + }
> > > +
> > > + rc = libxl_domain_config_from_json(ctx, d_config, (const char *)data);
> > > +
> > > +out:
> > > + free(data);
> >
> > data might have been libxl__realloc'd above, so isn't it gc'd?
> >
>
> No, it's malloc'ed in libxl_read_file_contents.
But then you call libxl__realloc(gc,...). Won't that add the new pointer
to the gc (and fail to remove the old one from it because it wasn't
there)? Then you free it with free() and then GC_FREE will double free
it.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain
2014-06-01 19:02 ` Wei Liu
@ 2014-06-02 16:21 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-06-02 16:21 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Sun, 2014-06-01 at 20:02 +0100, Wei Liu wrote:
> On Tue, May 20, 2014 at 03:12:18PM +0100, Ian Campbell wrote:
> > On Tue, 2014-05-13 at 22:54 +0100, Wei Liu wrote:
> > > This patch utilizes "libxl-json" format and helper functions introduced
> > > in previous patch to store up-to-do domain configuration when creating a
> > > domain.
> > >
> > > Signed-off-by: Wei Liu <wei.liu2@citrix.com>
> >
> > This seems to end up saving the domain config 2 or even 3 times. I think
> > we need an explanation as to why that is.
> >
>
> Twice (see below).
>
> > Also we need to know what the invariants are, what must (not) change
> > either before or after each sequencing point, what must be in each
> > update etc.
> >
>
> The first save is the vanilla copy, that's what the user provides.
>
> Then udpate_domain_config is called to pull in everything that may get
> changed by libxl to the vanilla copy. What's pulled in is documented in
> update_domain_config.
>
> The second save saves the updated version.
>
> > Can you not save the raw version at the start (before anything has
> > touched it) and then do the domid, uuid, mac, vtpm etc all at the end in
> > domcreate_complete? (Don't you do the uuid twice? The comments mention
> > it twice)
> >
>
> I don't follow. I think this is what being done at the moment. The
> vanilla domain configuration is saved at the beginning of domain
> creation then updated when domain creation completes. It's exactly what
> you suggested.
>
> Re UUID, no. Domain UUID and UUID for devices are different things.
I think perhaps that's what I got confused about and thought there were
more saves than I expected.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-06-01 19:07 ` Wei Liu
@ 2014-06-02 16:23 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-06-02 16:23 UTC (permalink / raw)
To: Wei Liu; +Cc: Ian Jackson, xen-devel
On Sun, 2014-06-01 at 20:07 +0100, Wei Liu wrote:
> On Tue, May 20, 2014 at 04:11:44PM +0100, Ian Jackson wrote:
> > Wei Liu writes ("[PATCH V5 29/32] xl: use "libxl-json" format"):
> > > Before this change, xl stores domain configuration in "xl" format, which
> > > is in fact a verbatim copy of user supplied domain config.
> > ...
> > > + /* If we're doing migration, the domain name was appended with
> > > + * "--incoming" a few lines above. So we need to remove that
> > > + * suffix in the stored configuration.
> > > + */
> > > + if (migrate_fd >= 0) {
> > > + libxl_domain_config d;
> > > + int xlen = strlen("--incoming");
> > > + int orig_len;
> > > +
> > > + ret = libxl_load_domain_configuration(ctx, domid, &d);
> >
> > Firstly, I think this editing of libxl's copy of domain config way is
> > a layering violation.
> >
> > But it ought to be unnecessary, because either libxl_domain_rename
> > or "libxl_load_domain_configuration" should deal with it. I would
> > much prefer the latter, as that results in the domain name being
> > stored only in one place.
> >
>
> Huh? I suppose to avoid "layering violation" I should make
> libxl_domain_rename manipulate the stored configuration, shouldn't I?
> But you're suggesting I make libxl_load_domain_configuration work?
> I'm confused.
He was suggesting two alternatives, not two things to both be done.
I think we need to decide if the stored configuration is the original
user provide config, which is undated by
libxl_retrieve_domain_configuration vs each libxl operation updating the
stored state so that libxl_retrieve_domain_configuration before a simple
parse and return.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-06-01 19:37 ` Wei Liu
@ 2014-06-02 16:30 ` Ian Campbell
2014-06-03 10:02 ` Wei Liu
0 siblings, 1 reply; 127+ messages in thread
From: Ian Campbell @ 2014-06-02 16:30 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Sun, 2014-06-01 at 20:37 +0100, Wei Liu wrote:
> On Tue, May 20, 2014 at 03:23:26PM +0100, Ian Campbell wrote:
> [...]
> > > @@ -1787,13 +1770,10 @@ static int handle_domain_death(uint32_t *r_domid,
> > > break;
> > >
> > > case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
> > > - reload_domain_config(*r_domid, config_data, config_len);
> > > restart = 2;
> > > break;
> > >
> > > case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
> > > - reload_domain_config(*r_domid, config_data, config_len);
> >
> > Why is it not equally necessary to reload the JSON config at this point
> > if it exists?
> >
>
> Because domain configuration is loaded in the caller of
> handle_domain_death now.
OK. Is there any way that could be refactored into a separate patch to
make this one simpler to reason about?
> > Or should we not be updating the domain config as we do the renaming at
> > the end?
> >
>
> I agree that libxl_domain_rename is a better place to update stored
> domain name.
We should probably all agree on which of the approachs we want to use
before you refactor (there is more than one subthread suggesting various
ways...)
> >
> > > @@ -3102,22 +3119,18 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
> > > s = yajl_gen_status_ok;
> > >
> > > for (i = 0; i < nb_domain; i++) {
> > > + libxl_domain_config_init(&d_config);
> > > /* no detailed info available on dom0 */
> > > if (info[i].domid == 0)
> > > continue;
> > > - rc = libxl_userdata_retrieve(ctx, info[i].domid, "xl", &data, &len);
> > > + rc = libxl_load_domain_configuration(ctx, info[i].domid, &d_config);
> >
> > If a domain was created with xl.old will we not now fail to list details
> > of it here?
> >
>
> Don't you need to restart if you install new tool? Is this a valid
> usecase?
Yes, that's true. I had my lazy developer non-rebooting hat on ;-)
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 31/32] libxl: update domain configuration when updating memory targets
2014-06-01 20:22 ` Wei Liu
@ 2014-06-02 16:32 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-06-02 16:32 UTC (permalink / raw)
To: Wei Liu; +Cc: Ian Jackson, xen-devel
On Sun, 2014-06-01 at 21:22 +0100, Wei Liu wrote:
> I can see your approach can work better than mine. My only concern is
> that some curious user might want to poke at libxl-json file, i.e. try
> to get domain configuration without programming against libxl API. But I
> think that should be forbidden, right?
They are welcome to do it, but they'll get what we think should be in
there, which may not be what they thought they wanted... ;-)
(IOW, yes, pretty much ;-0 )
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device
2014-06-01 20:57 ` Wei Liu
@ 2014-06-02 16:33 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-06-02 16:33 UTC (permalink / raw)
To: Wei Liu; +Cc: Ian Jackson, xen-devel
On Sun, 2014-06-01 at 21:57 +0100, Wei Liu wrote:
> > Then you could arrange to add the device to the JSON config before
> > doing anything else, and remove it afterwards, and then there would be
> > no undesirable states etc.
> >
>
> Sorry, it's unclear to me what you want me to do. Why do I need to
> remove a device after I add it?
FWIW I read it as having a missing "on failure" somewhere.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions
2014-06-02 16:19 ` Ian Campbell
@ 2014-06-02 19:56 ` Wei Liu
0 siblings, 0 replies; 127+ messages in thread
From: Wei Liu @ 2014-06-02 19:56 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Mon, Jun 02, 2014 at 05:19:46PM +0100, Ian Campbell wrote:
[...]
>
> But then you call libxl__realloc(gc,...). Won't that add the new pointer
> to the gc (and fail to remove the old one from it because it wasn't
> there)? Then you free it with free() and then GC_FREE will double free
> it.
>
Oh, yes, you're right. I will fix this -- if this hunk is kept in my
future version. Thanks.
Wei.
> Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-06-02 16:30 ` Ian Campbell
@ 2014-06-03 10:02 ` Wei Liu
2014-06-03 10:34 ` Ian Campbell
0 siblings, 1 reply; 127+ messages in thread
From: Wei Liu @ 2014-06-03 10:02 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Mon, Jun 02, 2014 at 05:30:23PM +0100, Ian Campbell wrote:
> On Sun, 2014-06-01 at 20:37 +0100, Wei Liu wrote:
> > On Tue, May 20, 2014 at 03:23:26PM +0100, Ian Campbell wrote:
> > [...]
> > > > @@ -1787,13 +1770,10 @@ static int handle_domain_death(uint32_t *r_domid,
> > > > break;
> > > >
> > > > case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
> > > > - reload_domain_config(*r_domid, config_data, config_len);
> > > > restart = 2;
> > > > break;
> > > >
> > > > case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
> > > > - reload_domain_config(*r_domid, config_data, config_len);
> > >
> > > Why is it not equally necessary to reload the JSON config at this point
> > > if it exists?
> > >
> >
> > Because domain configuration is loaded in the caller of
> > handle_domain_death now.
>
> OK. Is there any way that could be refactored into a separate patch to
> make this one simpler to reason about?
>
The purpose of reload_domain_config is to load the "xl" file (in fact
the saved domain config) from libxl private data store. After we have
our API to retrieve domain configuration in libxl I don't see the need
for it anymore. And this change needs to come with the introduction of
"libxl-json" file, a separate change is not very feasible IMHO.
Wei.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [PATCH V5 29/32] xl: use "libxl-json" format
2014-06-03 10:02 ` Wei Liu
@ 2014-06-03 10:34 ` Ian Campbell
0 siblings, 0 replies; 127+ messages in thread
From: Ian Campbell @ 2014-06-03 10:34 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Tue, 2014-06-03 at 11:02 +0100, Wei Liu wrote:
> On Mon, Jun 02, 2014 at 05:30:23PM +0100, Ian Campbell wrote:
> > On Sun, 2014-06-01 at 20:37 +0100, Wei Liu wrote:
> > > On Tue, May 20, 2014 at 03:23:26PM +0100, Ian Campbell wrote:
> > > [...]
> > > > > @@ -1787,13 +1770,10 @@ static int handle_domain_death(uint32_t *r_domid,
> > > > > break;
> > > > >
> > > > > case LIBXL_ACTION_ON_SHUTDOWN_RESTART_RENAME:
> > > > > - reload_domain_config(*r_domid, config_data, config_len);
> > > > > restart = 2;
> > > > > break;
> > > > >
> > > > > case LIBXL_ACTION_ON_SHUTDOWN_RESTART:
> > > > > - reload_domain_config(*r_domid, config_data, config_len);
> > > >
> > > > Why is it not equally necessary to reload the JSON config at this point
> > > > if it exists?
> > > >
> > >
> > > Because domain configuration is loaded in the caller of
> > > handle_domain_death now.
> >
> > OK. Is there any way that could be refactored into a separate patch to
> > make this one simpler to reason about?
> >
>
> The purpose of reload_domain_config is to load the "xl" file (in fact
> the saved domain config) from libxl private data store. After we have
> our API to retrieve domain configuration in libxl I don't see the need
> for it anymore. And this change needs to come with the introduction of
> "libxl-json" file, a separate change is not very feasible IMHO.
If it's not possible to just replace the reload_domain_config with a
call to the retrieval function and then refactor later then that's fine.
Ian.
^ permalink raw reply [flat|nested] 127+ messages in thread
end of thread, other threads:[~2014-06-03 10:34 UTC | newest]
Thread overview: 127+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
2014-05-13 21:53 ` [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function Wei Liu
2014-05-15 16:28 ` Ian Campbell
2014-05-20 14:47 ` Ian Jackson
2014-05-20 17:24 ` Wei Liu
2014-05-21 8:27 ` Ian Campbell
2014-05-21 8:37 ` Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function) Ian Campbell
2014-05-22 9:35 ` George Dunlap
2014-05-27 23:04 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl Wei Liu
2014-05-15 16:38 ` Ian Campbell
2014-05-15 17:11 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning " Wei Liu
2014-05-15 0:59 ` Dario Faggioli
2014-05-15 9:24 ` Wei Liu
2014-05-15 15:31 ` Dario Faggioli
2014-05-15 15:37 ` Wei Liu
2014-05-15 16:45 ` Ian Campbell
2014-05-15 17:06 ` Wei Liu
2014-05-15 17:19 ` Wei Liu
2014-05-16 9:51 ` Ian Campbell
2014-05-16 8:10 ` Dario Faggioli
2014-05-16 9:57 ` Ian Campbell
2014-05-16 10:15 ` Wei Liu
2014-05-16 10:28 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument Wei Liu
2014-05-15 16:51 ` Ian Campbell
2014-05-15 17:13 ` Wei Liu
2014-05-16 9:46 ` Ian Campbell
2014-05-16 10:18 ` Wei Liu
2014-05-16 10:30 ` Ian Campbell
2014-05-16 11:17 ` Wei Liu
2014-05-16 11:21 ` Wei Liu
2014-05-16 11:23 ` Ian Campbell
2014-05-16 11:28 ` Wei Liu
2014-05-16 11:31 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file Wei Liu
2014-05-20 12:44 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 06/32] libxl: fix memory leak in libxl_cpuid_dispose Wei Liu
2014-05-13 21:53 ` [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types Wei Liu
2014-05-20 12:49 ` Ian Campbell
2014-05-20 14:54 ` Ian Jackson
2014-05-20 15:02 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json Wei Liu
2014-05-20 12:50 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here Wei Liu
2014-05-20 12:51 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 10/32] libxl: fix JSON generator for uint64_t Wei Liu
2014-05-20 12:55 ` Ian Campbell
2014-05-20 13:15 ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 11/32] libxl IDL: rename json_fn to json_gen_fn Wei Liu
2014-05-13 21:53 ` [PATCH V5 12/32] libxl_json: introduce libxl__object_from_json Wei Liu
2014-05-13 21:53 ` [PATCH V5 13/32] libxl_internal: make JSON_* types a bit-field Wei Liu
2014-05-13 21:53 ` [PATCH V5 14/32] libxl_internal.h: introduce libxl__json_object_is_{null, number, double} Wei Liu
2014-05-13 21:53 ` [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number Wei Liu
2014-05-20 12:56 ` Ian Campbell
2014-05-20 15:11 ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 16/32] libxl_json: introduce parser functions for builtin types Wei Liu
2014-05-13 21:53 ` [PATCH V5 17/32] libxl_json: allow basic JSON type objects generation Wei Liu
2014-05-13 21:54 ` [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation Wei Liu
2014-05-20 13:26 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 19/32] libxl/gentypes.py: don't generate default values Wei Liu
2014-05-20 13:29 ` Ian Campbell
2014-05-20 17:17 ` Wei Liu
2014-05-21 8:31 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
2014-05-20 13:35 ` Ian Campbell
2014-06-01 17:43 ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 21/32] libxl/gentest.py: test JSON parser Wei Liu
2014-05-13 21:54 ` [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length Wei Liu
2014-05-20 13:36 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length Wei Liu
2014-05-20 13:36 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 24/32] libxl: copy function for builtin types Wei Liu
2014-05-20 13:39 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 25/32] libxl IDL: generate deep copy functions Wei Liu
2014-05-20 13:42 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 26/32] libxl/gentest.py: test " Wei Liu
2014-05-13 21:54 ` [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions Wei Liu
2014-05-20 14:03 ` Ian Campbell
2014-06-01 18:41 ` Wei Liu
2014-06-02 16:19 ` Ian Campbell
2014-06-02 19:56 ` Wei Liu
2014-05-20 15:01 ` Ian Jackson
2014-06-01 18:46 ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain Wei Liu
2014-05-20 14:12 ` Ian Campbell
2014-06-01 19:02 ` Wei Liu
2014-06-02 16:21 ` Ian Campbell
2014-05-20 15:04 ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 29/32] xl: use "libxl-json" format Wei Liu
2014-05-20 14:23 ` Ian Campbell
2014-05-20 15:13 ` Ian Jackson
2014-05-20 15:31 ` Ian Campbell
2014-06-01 19:37 ` Wei Liu
2014-06-02 16:30 ` Ian Campbell
2014-06-03 10:02 ` Wei Liu
2014-06-03 10:34 ` Ian Campbell
2014-05-20 15:11 ` Ian Jackson
2014-05-20 15:15 ` Ian Campbell
2014-05-20 15:39 ` Ian Jackson
2014-06-01 19:18 ` Wei Liu
2014-06-01 19:07 ` Wei Liu
2014-06-02 16:23 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 30/32] libxl: consider force removal of device successful Wei Liu
2014-05-20 14:26 ` Ian Campbell
2014-06-01 19:44 ` Wei Liu
2014-05-20 15:15 ` Ian Jackson
2014-06-01 19:46 ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 31/32] libxl: update domain configuration when updating memory targets Wei Liu
2014-05-20 14:32 ` Ian Campbell
2014-06-01 20:00 ` Wei Liu
2014-05-20 15:21 ` Ian Jackson
2014-05-20 15:35 ` Ian Campbell
2014-05-20 15:44 ` Ian Jackson
2014-05-20 15:55 ` Ian Campbell
2014-05-20 16:03 ` Ian Jackson
2014-05-21 8:38 ` Ian Campbell
2014-06-01 20:51 ` Wei Liu
2014-06-01 20:22 ` Wei Liu
2014-06-02 16:32 ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device Wei Liu
2014-05-20 14:35 ` Ian Campbell
2014-05-20 15:33 ` Ian Jackson
2014-06-01 20:57 ` Wei Liu
2014-06-02 16:33 ` Ian Campbell
2014-05-21 10:18 ` [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Ian Campbell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).