* [PATCH v2 1/7] tools/libs/store: add get- and set-feature related functions
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-25 13:19 ` [PATCH v2 2/7] tools/xenstored: support specification of migration stream version Juergen Gross
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
Add functions for getting and setting Xenstore features to libxenstore:
xs_get_features_supported(): return the features supported by the
running Xenstore implementation as defined in xs_wire.h via the
XENSTORE_SERVER_FEATURE_* macros.
xs_get_features_domain(): return the features offered for a specific
domain.
xs_set_features_domain(): set the features available for a specific
domain.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/include/xenstore.h | 13 +++++++++
tools/libs/store/Makefile | 2 +-
tools/libs/store/libxenstore.map | 6 ++++
tools/libs/store/xs.c | 49 ++++++++++++++++++++++++++++++++
4 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/tools/include/xenstore.h b/tools/include/xenstore.h
index a442252849..423422dc50 100644
--- a/tools/include/xenstore.h
+++ b/tools/include/xenstore.h
@@ -264,6 +264,19 @@ bool xs_path_is_subpath(const char *parent, const char *child);
*/
bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid);
+/* Get the features supported by Xenstore.
+ * Returned as a bitmap of XENSTORE_SERVER_FEATURE_* values.
+ */
+bool xs_get_features_supported(struct xs_handle *h, unsigned int *features);
+
+/* Get the features available for a given domain. */
+bool xs_get_features_domain(struct xs_handle *h, unsigned int domid,
+ unsigned int *features);
+
+/* Set the features available for a given domain. */
+bool xs_set_features_domain(struct xs_handle *h, unsigned int domid,
+ unsigned int features);
+
char *xs_control_command(struct xs_handle *h, const char *cmd,
void *data, unsigned int len);
/* Deprecated: use xs_control_command() instead. */
diff --git a/tools/libs/store/Makefile b/tools/libs/store/Makefile
index 0649cf8307..fed43b0008 100644
--- a/tools/libs/store/Makefile
+++ b/tools/libs/store/Makefile
@@ -2,7 +2,7 @@ XEN_ROOT=$(CURDIR)/../../..
include $(XEN_ROOT)/tools/Rules.mk
MAJOR = 4
-MINOR = 0
+MINOR = 1
version-script := libxenstore.map
ifeq ($(CONFIG_Linux),y)
diff --git a/tools/libs/store/libxenstore.map b/tools/libs/store/libxenstore.map
index 7e6c7bdd30..cd9df86749 100644
--- a/tools/libs/store/libxenstore.map
+++ b/tools/libs/store/libxenstore.map
@@ -39,3 +39,9 @@ VERS_4.0 {
xs_strings_to_perms;
local: *; /* Do not expose anything by default */
};
+VERS_4.1 {
+ global:
+ xs_get_features_supported;
+ xs_get_features_domain;
+ xs_set_features_domain;
+} VERS_4.0;
diff --git a/tools/libs/store/xs.c b/tools/libs/store/xs.c
index cf3266807f..8f4b90a3cf 100644
--- a/tools/libs/store/xs.c
+++ b/tools/libs/store/xs.c
@@ -1407,6 +1407,55 @@ out:
return port;
}
+static bool xs_uint(char *reply, unsigned int *uintval)
+{
+ if (!reply)
+ return false;
+
+ *uintval = strtoul(reply, NULL, 10);
+ free(reply);
+
+ return true;
+}
+
+bool xs_get_features_supported(struct xs_handle *h, unsigned int *features)
+{
+ struct xsd_sockmsg msg = { .type = XS_GET_FEATURE };
+ struct iovec iov[1];
+
+ iov[0].iov_base = &msg;
+ iov[0].iov_len = sizeof(msg);
+
+ return xs_uint(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL), features);
+}
+
+bool xs_get_features_domain(struct xs_handle *h, unsigned int domid,
+ unsigned int *features)
+{
+ return xs_uint(single_with_domid(h, XS_GET_FEATURE, domid), features);
+}
+
+bool xs_set_features_domain(struct xs_handle *h, unsigned int domid,
+ unsigned int features)
+{
+ struct xsd_sockmsg msg = { .type = XS_SET_FEATURE };
+ char domid_str[MAX_STRLEN(domid)];
+ char feat_str[MAX_STRLEN(features)];
+ struct iovec iov[3];
+
+ snprintf(domid_str, sizeof(domid_str), "%u", domid);
+ snprintf(feat_str, sizeof(feat_str), "%u", features);
+
+ iov[0].iov_base = &msg;
+ iov[0].iov_len = sizeof(msg);
+ iov[1].iov_base = domid_str;
+ iov[1].iov_len = strlen(domid_str) + 1;
+ iov[2].iov_base = feat_str;
+ iov[2].iov_len = strlen(feat_str) + 1;
+
+ return xs_bool(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL));
+}
+
char *xs_control_command(struct xs_handle *h, const char *cmd,
void *data, unsigned int len)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 2/7] tools/xenstored: support specification of migration stream version
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
2025-07-25 13:19 ` [PATCH v2 1/7] tools/libs/store: add get- and set-feature related functions Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-25 13:19 ` [PATCH v2 3/7] tools/xenstored: add missing migration record definitions Juergen Gross
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
In order to prepare xenstored supporting migration stream versions
other than 1, add a parameter to the live update command allowing to
specify the version of the migration stream.
This will allow going back from xenstored using version 2 per default
to a xenstored only accepting version 1.
For now only version 1 is supported.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xenstored/control.c | 6 ++---
tools/xenstored/lu.c | 21 ++++++++++-----
tools/xenstored/lu.h | 1 +
tools/xs-clients/xenstore_control.c | 41 ++++++++++++++++++++++-------
4 files changed, 50 insertions(+), 19 deletions(-)
diff --git a/tools/xenstored/control.c b/tools/xenstored/control.c
index 9561289179..953c01b735 100644
--- a/tools/xenstored/control.c
+++ b/tools/xenstored/control.c
@@ -289,7 +289,7 @@ static struct cmd_s cmds[] = {
* Mini-OS: -b <binary-size>
* -d <size> <data-bytes> (multiple of those)
* 2. New command-line (optional): -c <cmdline>
- * 3. Start of update: -s [-F] [-t <timeout>]
+ * 3. Start of update: -s [-F] [-t <timeout>] [-v <version>]
* Any sub-operation needs to respond with the string "OK" in case
* of success, any other response indicates failure.
* A started live-update sequence can be aborted via "-a" (not
@@ -297,8 +297,8 @@ static struct cmd_s cmds[] = {
* sub-operation).
*/
{ "live-update", do_control_lu,
- "[-c <cmdline>] [-F] [-t <timeout>] <file>\n"
- " Default timeout is 60 seconds.", 5 },
+ "[-c <cmdline>] [-F] [-t <timeout>] [-v <version>] <file>\n"
+ " Default timeout is 60 seconds, default version is 1.", 7 },
#endif
{ "logfile", do_control_logfile, "<file>" },
{ "memreport", do_control_memreport, "[<file>]" },
diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
index 4fccbbc195..330820a8a2 100644
--- a/tools/xenstored/lu.c
+++ b/tools/xenstored/lu.c
@@ -283,7 +283,7 @@ static const char *lu_dump_state(const void *ctx, struct connection *conn)
return "Dump state open error";
memcpy(pre.ident, XS_STATE_IDENT, sizeof(pre.ident));
- pre.version = htobe32(XS_STATE_VERSION);
+ pre.version = htobe32(lu_status->version);
pre.flags = XS_STATE_FLAGS;
if (fwrite(&pre, sizeof(pre), 1, fp) != 1) {
ret = "Dump write error";
@@ -412,13 +412,16 @@ static bool do_lu_start(struct delayed_request *req)
}
static const char *lu_start(const void *ctx, struct connection *conn,
- bool force, unsigned int to)
+ bool force, unsigned int to, unsigned int vers)
{
syslog(LOG_INFO, "live-update: start, force=%d, to=%u\n", force, to);
if (!lu_status || lu_status->conn != conn)
return "Not in live-update session.";
+ if (!vers || vers > XS_STATE_VERSION)
+ return "Migration stream version not supported.";
+
#ifdef __MINIOS__
if (lu_status->kernel_size != lu_status->kernel_off)
return "Kernel not complete.";
@@ -426,6 +429,7 @@ static const char *lu_start(const void *ctx, struct connection *conn,
lu_status->force = force;
lu_status->timeout = to;
+ lu_status->version = vers;
lu_status->started_at = time(NULL);
lu_status->in = conn->in;
@@ -441,6 +445,7 @@ int do_control_lu(const void *ctx, struct connection *conn, const char **vec,
unsigned int i;
bool force = false;
unsigned int to = 0;
+ unsigned int vers = XS_STATE_VERSION;
if (num < 1)
return EINVAL;
@@ -457,15 +462,19 @@ int do_control_lu(const void *ctx, struct connection *conn, const char **vec,
return EINVAL;
} else if (!strcmp(vec[0], "-s")) {
for (i = 1; i < num; i++) {
- if (!strcmp(vec[i], "-F"))
+ if (!strcmp(vec[i], "-F")) {
force = true;
- else if (!strcmp(vec[i], "-t") && i < num - 1) {
+ } else if (!strcmp(vec[i], "-t") && i < num - 1) {
i++;
to = atoi(vec[i]);
- } else
+ } else if (!strcmp(vec[i], "-v") && i < num - 1) {
+ i++;
+ vers = atoi(vec[i]);
+ } else {
return EINVAL;
+ }
}
- ret = lu_start(ctx, conn, force, to);
+ ret = lu_start(ctx, conn, force, to, vers);
if (!ret)
return errno;
} else {
diff --git a/tools/xenstored/lu.h b/tools/xenstored/lu.h
index dacc9b6e42..512b8a6db2 100644
--- a/tools/xenstored/lu.h
+++ b/tools/xenstored/lu.h
@@ -26,6 +26,7 @@ struct live_update {
/* Start parameters. */
bool force;
unsigned int timeout;
+ unsigned int version;
time_t started_at;
};
diff --git a/tools/xs-clients/xenstore_control.c b/tools/xs-clients/xenstore_control.c
index 548363ee70..4b523931ce 100644
--- a/tools/xs-clients/xenstore_control.c
+++ b/tools/xs-clients/xenstore_control.c
@@ -26,7 +26,8 @@ static int add_to_buf(char **buf, const char *val, int len)
return len + vallen;
}
-static int live_update_start(struct xs_handle *xsh, bool force, unsigned int to)
+static int live_update_start(struct xs_handle *xsh, bool force, unsigned int to,
+ unsigned int vers)
{
int len = 0;
char *buf = NULL, *ret;
@@ -40,6 +41,15 @@ static int live_update_start(struct xs_handle *xsh, bool force, unsigned int to)
free(ret);
if (force)
len = add_to_buf(&buf, "-F", len);
+ if (vers) {
+ if (asprintf(&ret, "%u", vers) < 0) {
+ free(buf);
+ return 1;
+ }
+ len = add_to_buf(&buf, "-v", len);
+ len = add_to_buf(&buf, ret, len);
+ free(ret);
+ }
if (len < 0)
return 1;
@@ -197,7 +207,8 @@ static int send_kernel_blob(struct xs_handle *xsh, const char *binary)
* 3. start update (includes flags)
*/
static int live_update_stubdom(struct xs_handle *xsh, const char *binary,
- const char *cmdline, bool force, unsigned int to)
+ const char *cmdline, bool force, unsigned int to,
+ unsigned int vers)
{
int rc;
@@ -211,7 +222,7 @@ static int live_update_stubdom(struct xs_handle *xsh, const char *binary,
goto abort;
}
- rc = live_update_start(xsh, force, to);
+ rc = live_update_start(xsh, force, to, vers);
if (rc)
goto abort;
@@ -231,7 +242,8 @@ static int live_update_stubdom(struct xs_handle *xsh, const char *binary,
* 3. start update (includes flags)
*/
static int live_update_daemon(struct xs_handle *xsh, const char *binary,
- const char *cmdline, bool force, unsigned int to)
+ const char *cmdline, bool force, unsigned int to,
+ unsigned int vers)
{
int len = 0, rc;
char *buf = NULL, *ret;
@@ -256,7 +268,7 @@ static int live_update_daemon(struct xs_handle *xsh, const char *binary,
goto abort;
}
- rc = live_update_start(xsh, force, to);
+ rc = live_update_start(xsh, force, to, vers);
if (rc)
goto abort;
@@ -270,7 +282,7 @@ static int live_update_daemon(struct xs_handle *xsh, const char *binary,
static int live_update(struct xs_handle *xsh, int argc, char **argv)
{
int rc = 0;
- unsigned int i, to = 60;
+ unsigned int i, to = 60, vers = 0;
char *binary = NULL, *cmdline = NULL, *val;
bool force = false;
@@ -291,10 +303,19 @@ static int live_update(struct xs_handle *xsh, int argc, char **argv)
goto out;
}
to = atoi(argv[i]);
- } else if (!strcmp(argv[i], "-F"))
+ } else if (!strcmp(argv[i], "-F")) {
force = true;
- else
+ } else if (!strcmp(argv[i], "-v")) {
+ i++;
+ if (i == argc) {
+ fprintf(stderr, "Missing version value\n");
+ rc = 2;
+ goto out;
+ }
+ vers = atoi(argv[i]);
+ } else {
binary = argv[i];
+ }
}
if (!binary) {
@@ -305,9 +326,9 @@ static int live_update(struct xs_handle *xsh, int argc, char **argv)
val = xs_read(xsh, XBT_NULL, "/tool/xenstored/domid", &i);
if (val)
- rc = live_update_stubdom(xsh, binary, cmdline, force, to);
+ rc = live_update_stubdom(xsh, binary, cmdline, force, to, vers);
else
- rc = live_update_daemon(xsh, binary, cmdline, force, to);
+ rc = live_update_daemon(xsh, binary, cmdline, force, to, vers);
free(val);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 3/7] tools/xenstored: add missing migration record definitions
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
2025-07-25 13:19 ` [PATCH v2 1/7] tools/libs/store: add get- and set-feature related functions Juergen Gross
2025-07-25 13:19 ` [PATCH v2 2/7] tools/xenstored: support specification of migration stream version Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-25 13:19 ` [PATCH v2 4/7] tools/xenstored: add server feature support Juergen Gross
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
Add all the missing migration record structures and defines to the
xenstore_state.h header file.
Update the version of the migration stream to "2". In order to allow
receiving version 1 streams, change the version check of the header
to reject only streams with a version higher than the current known
one.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xenstored/control.c | 2 +-
tools/xenstored/lu.c | 2 +-
tools/xenstored/xenstore_state.h | 31 ++++++++++++++++++++++++++++++-
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/tools/xenstored/control.c b/tools/xenstored/control.c
index 953c01b735..2611a6fade 100644
--- a/tools/xenstored/control.c
+++ b/tools/xenstored/control.c
@@ -298,7 +298,7 @@ static struct cmd_s cmds[] = {
*/
{ "live-update", do_control_lu,
"[-c <cmdline>] [-F] [-t <timeout>] [-v <version>] <file>\n"
- " Default timeout is 60 seconds, default version is 1.", 7 },
+ " Default timeout is 60 seconds, default version is 2.", 7 },
#endif
{ "logfile", do_control_logfile, "<file>" },
{ "memreport", do_control_memreport, "[<file>]" },
diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
index 330820a8a2..2c6adecb56 100644
--- a/tools/xenstored/lu.c
+++ b/tools/xenstored/lu.c
@@ -136,7 +136,7 @@ void lu_read_state(void)
pre = state.buf;
if (memcmp(pre->ident, XS_STATE_IDENT, sizeof(pre->ident)) ||
- pre->version != htobe32(XS_STATE_VERSION) ||
+ !pre->version || be32toh(pre->version) > XS_STATE_VERSION ||
pre->flags != XS_STATE_FLAGS)
barf("Unknown record identifier");
for (head = state.buf + sizeof(*pre);
diff --git a/tools/xenstored/xenstore_state.h b/tools/xenstored/xenstore_state.h
index bad966caf4..3fd97d60d8 100644
--- a/tools/xenstored/xenstore_state.h
+++ b/tools/xenstored/xenstore_state.h
@@ -27,8 +27,10 @@
#ifndef htobe32
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define htobe32(x) __builtin_bswap32(x)
+#define be32toh(x) __builtin_bswap32(x)
#else
#define htobe32(x) (x)
+#define be32toh(x) (x)
#endif
#endif
@@ -36,7 +38,7 @@ struct xs_state_preamble {
char ident[8];
#define XS_STATE_IDENT "xenstore" /* To be used without the NUL byte. */
uint32_t version; /* Version in big endian format. */
-#define XS_STATE_VERSION 0x00000001
+#define XS_STATE_VERSION 0x00000002
uint32_t flags; /* Endianess. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define XS_STATE_FLAGS 0x00000000 /* Little endian. */
@@ -59,6 +61,9 @@ struct xs_state_record_header {
#define XS_STATE_TYPE_WATCH 0x00000003
#define XS_STATE_TYPE_TA 0x00000004
#define XS_STATE_TYPE_NODE 0x00000005
+#define XS_STATE_TYPE_GLB_QUOTA 0x00000006
+#define XS_STATE_TYPE_DOMAIN 0x00000007
+#define XS_STATE_TYPE_WATCH_EXT 0x00000008
uint32_t length; /* Length of record in bytes. */
};
@@ -98,6 +103,15 @@ struct xs_state_watch {
uint8_t data[]; /* Path bytes, token bytes, 0-7 pad bytes. */
};
+struct xs_state_watch_ext {
+ uint32_t conn_id; /* Connection this watch is associated with. */
+ uint16_t path_length; /* Number of bytes of path watched (incl. 0). */
+ uint16_t token_length; /* Number of bytes of watch token (incl. 0). */
+ uint16_t depth; /* Number of directory levels below watched path */
+ /* to consider for a match. */
+ uint8_t data[]; /* Path bytes, token bytes, 0-7 pad bytes. */
+};
+
/* Transaction: */
struct xs_state_transaction {
uint32_t conn_id; /* Connection this TA is associated with. */
@@ -129,4 +143,19 @@ struct xs_state_node {
struct xs_state_node_perm perms[];
/* Path and data follows, plus 0-7 pad bytes. */
};
+
+/* Global quota data: */
+struct xs_state_glb_quota {
+ uint16_t n_dom_quota; /* Number of quota values applying to domains. */
+ uint16_t n_glob_quota; /* Number of quota values applying globally only. */
+ uint32_t quota_val[]; /* Array of quota values (domain ones first). */
+};
+
+/* Domain data: */
+struct xs_state_domain {
+ uint16_t domain_id; /* Domain-id identifying the domain. */
+ uint16_t n_quota; /* Number of quota values. */
+ uint32_t features; /* Server features available to the domain. */
+ uint32_t quota_val[]; /* Array of quota values. */
+};
#endif /* XENSTORE_STATE_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 4/7] tools/xenstored: add server feature support
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
` (2 preceding siblings ...)
2025-07-25 13:19 ` [PATCH v2 3/7] tools/xenstored: add missing migration record definitions Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-25 13:38 ` Jason Andryuk
2025-07-25 13:19 ` [PATCH v2 5/7] tools/xenstored: support SET/GET_FEATURE commands Juergen Gross
` (2 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD
Add per domain server features, which are initialized by the supported
features at domain introduction, or by live update from the migration
stream. This requires to add the DOMAIN_DATA record to the migration
stream, but for now it will only contain the feature word.
Advertise the Xenstore features to guests by setting the appropriate
bits in the ring page.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- move setting interface->server_features to introduce_domain()
---
tools/xenstored/domain.c | 60 +++++++++++++++++++++++++++++++++++++++-
tools/xenstored/domain.h | 3 ++
tools/xenstored/lu.c | 14 ++++++++--
tools/xenstored/lu.h | 2 +-
4 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index e1d5e8d614..24ee99cbc6 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -32,6 +32,7 @@
#include "transaction.h"
#include "watch.h"
#include "control.h"
+#include "lu.h"
#include <xenevtchn.h>
#include <xenmanage.h>
@@ -42,6 +43,8 @@
#include <mini-os/xenbus.h>
#endif
+#define XENSTORE_FEATURES XENSTORE_SERVER_FEATURE_ERROR
+
static xenmanage_handle *xm_handle;
xengnttab_handle **xgt_handle;
static evtchn_port_t virq_port;
@@ -115,6 +118,9 @@ struct domain
/* Event channel port */
evtchn_port_t port;
+ /* Server features supported for this domain. */
+ unsigned int features;
+
/* Domain path in store. */
char *path;
@@ -799,6 +805,7 @@ static struct domain *alloc_domain(const void *context, unsigned int domid,
domain->unique_id = unique_id;
domain->generation = generation;
domain->introduced = false;
+ domain->features = XENSTORE_FEATURES;
if (hashtable_add(domhash, &domain->domid, domain)) {
talloc_free(domain);
@@ -992,7 +999,8 @@ void ignore_connection(struct connection *conn, unsigned int err)
{
trace("CONN %p ignored, reason %u\n", conn, err);
- if (conn->domain && conn->domain->interface)
+ if (conn->domain && conn->domain->interface &&
+ (conn->domain->features & XENSTORE_SERVER_FEATURE_ERROR))
conn->domain->interface->error = err;
conn->is_ignored = true;
@@ -1032,6 +1040,8 @@ static struct domain *introduce_domain(const void *ctx,
return NULL;
}
domain->interface = interface;
+ if (!restore)
+ interface->server_features = domain->features;
if (is_master_domain)
setup_structure(restore);
@@ -1849,6 +1859,54 @@ void read_state_connection(const void *ctx, const void *state)
}
}
+static int dump_state_domain(const void *k, void *v, void *arg)
+{
+ struct domain *domain = v;
+ FILE *fp = arg;
+ struct xs_state_domain sd;
+ struct xs_state_record_header head;
+
+ head.type = XS_STATE_TYPE_DOMAIN;
+ head.length = sizeof(sd);
+ memset(&sd, 0, sizeof(sd));
+ sd.domain_id = domain->domid;
+
+ if (lu_status->version > 1)
+ sd.features = domain->features;
+
+ if (fwrite(&head, sizeof(head), 1, fp) != 1)
+ return 1;
+ if (fwrite(&sd, sizeof(sd), 1, fp) != 1)
+ return 1;
+ if (dump_state_align(fp))
+ return 1;
+
+ return 0;
+}
+
+const char *dump_state_domains(FILE *fp)
+{
+ const char *ret = NULL;
+
+ if (hashtable_iterate(domhash, dump_state_domain, fp))
+ ret = "Dump domain error";
+
+ return ret;
+}
+
+void read_state_domain(const void *ctx, const void *state, unsigned int version)
+{
+ const struct xs_state_domain *sd = state;
+ struct domain *domain;
+
+ domain = find_domain_struct(sd->domain_id);
+ if (!domain)
+ barf("referenced domain not found");
+
+ if (version > 1)
+ domain->features = sd->features;
+}
+
struct domain_acc {
unsigned int domid;
int nodes;
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 844ac11510..8bfaca8f90 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -162,8 +162,11 @@ void wrl_apply_debit_direct(struct connection *conn);
void wrl_apply_debit_trans_commit(struct connection *conn);
const char *dump_state_connections(FILE *fp);
+const char *dump_state_domains(FILE *fp);
void read_state_connection(const void *ctx, const void *state);
+void read_state_domain(const void *ctx, const void *state,
+ unsigned int version);
struct hashtable *domain_check_acc_init(void);
void domain_check_acc_add(const struct node *node, struct hashtable *domains);
diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
index 2c6adecb56..77e0d377c5 100644
--- a/tools/xenstored/lu.c
+++ b/tools/xenstored/lu.c
@@ -21,6 +21,8 @@
#include "lu.h"
#include "watch.h"
+struct live_update *lu_status;
+
#ifndef NO_LIVE_UPDATE
struct lu_dump_state {
@@ -30,8 +32,6 @@ struct lu_dump_state {
char *filename;
};
-struct live_update *lu_status;
-
static int lu_destroy(void *data)
{
lu_status = NULL;
@@ -128,6 +128,7 @@ void lu_read_state(void)
struct xs_state_record_header *head;
void *ctx = talloc_new(NULL); /* Work context for subfunctions. */
struct xs_state_preamble *pre;
+ unsigned int version;
syslog(LOG_INFO, "live-update: read state\n");
lu_get_dump_state(&state);
@@ -135,8 +136,9 @@ void lu_read_state(void)
barf_perror("No state found after live-update");
pre = state.buf;
+ version = be32toh(pre->version);
if (memcmp(pre->ident, XS_STATE_IDENT, sizeof(pre->ident)) ||
- !pre->version || be32toh(pre->version) > XS_STATE_VERSION ||
+ !version || version > XS_STATE_VERSION ||
pre->flags != XS_STATE_FLAGS)
barf("Unknown record identifier");
for (head = state.buf + sizeof(*pre);
@@ -159,6 +161,9 @@ void lu_read_state(void)
case XS_STATE_TYPE_NODE:
read_state_node(ctx, head + 1);
break;
+ case XS_STATE_TYPE_DOMAIN:
+ read_state_domain(ctx, head + 1, version);
+ break;
default:
xprintf("live-update: unknown state record %08x\n",
head->type);
@@ -297,6 +302,9 @@ static const char *lu_dump_state(const void *ctx, struct connection *conn)
if (ret)
goto out;
ret = dump_state_nodes(fp, ctx);
+ if (ret)
+ goto out;
+ ret = dump_state_domains(fp);
if (ret)
goto out;
diff --git a/tools/xenstored/lu.h b/tools/xenstored/lu.h
index 512b8a6db2..aff7ab9011 100644
--- a/tools/xenstored/lu.h
+++ b/tools/xenstored/lu.h
@@ -5,7 +5,6 @@
* Copyright (C) 2022 Juergen Gross, SUSE LLC
*/
-#ifndef NO_LIVE_UPDATE
struct live_update {
/* For verification the correct connection is acting. */
struct connection *conn;
@@ -32,6 +31,7 @@ struct live_update {
extern struct live_update *lu_status;
+#ifndef NO_LIVE_UPDATE
struct connection *lu_get_connection(void);
bool lu_is_pending(void);
void lu_read_state(void);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 4/7] tools/xenstored: add server feature support
2025-07-25 13:19 ` [PATCH v2 4/7] tools/xenstored: add server feature support Juergen Gross
@ 2025-07-25 13:38 ` Jason Andryuk
0 siblings, 0 replies; 13+ messages in thread
From: Jason Andryuk @ 2025-07-25 13:38 UTC (permalink / raw)
To: Juergen Gross, xen-devel; +Cc: Julien Grall, Anthony PERARD
On 2025-07-25 09:19, Juergen Gross wrote:
> Add per domain server features, which are initialized by the supported
> features at domain introduction, or by live update from the migration
> stream. This requires to add the DOMAIN_DATA record to the migration
> stream, but for now it will only contain the feature word.
>
> Advertise the Xenstore features to guests by setting the appropriate
> bits in the ring page.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
Thanks,
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 5/7] tools/xenstored: support SET/GET_FEATURE commands
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
` (3 preceding siblings ...)
2025-07-25 13:19 ` [PATCH v2 4/7] tools/xenstored: add server feature support Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-25 13:19 ` [PATCH v2 6/7] tools/xl: add available Xenstore features to xl info output Juergen Gross
2025-07-25 13:19 ` [PATCH v2 7/7] tools: allow to limit xenstore features via guest config Juergen Gross
6 siblings, 0 replies; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Julien Grall, Anthony PERARD, Jason Andryuk
Add support for XS_SET_FEATURE and XS_GET_FEATURE to xenstored.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xenstored/core.c | 4 +++
tools/xenstored/domain.c | 60 ++++++++++++++++++++++++++++++++++++++++
tools/xenstored/domain.h | 8 ++++++
3 files changed, 72 insertions(+)
diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 37e4dd5a5b..3022efdce1 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2031,6 +2031,10 @@ static struct {
{ "SET_TARGET", do_set_target, XS_FLAG_PRIV },
[XS_RESET_WATCHES] = { "RESET_WATCHES", do_reset_watches },
[XS_DIRECTORY_PART] = { "DIRECTORY_PART", send_directory_part },
+ [XS_GET_FEATURE] =
+ { "GET_FEATURE", do_get_feature, XS_FLAG_PRIV },
+ [XS_SET_FEATURE] =
+ { "SET_FEATURE", do_set_feature, XS_FLAG_PRIV },
};
static const char *sockmsg_string(enum xsd_sockmsg_type type)
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 24ee99cbc6..2362216a7a 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1243,6 +1243,66 @@ int do_reset_watches(const void *ctx, struct connection *conn,
return 0;
}
+int do_get_feature(const void *ctx, struct connection *conn,
+ struct buffered_data *in)
+{
+ const char *vec[1];
+ unsigned int n_args;
+ unsigned int domid;
+ const struct domain *domain;
+ unsigned int features;
+ char *result;
+
+ n_args = get_strings(in, vec, ARRAY_SIZE(vec));
+ if (n_args > 1)
+ return EINVAL;
+
+ if (n_args == 1) {
+ domid = atoi(vec[0]);
+ domain = find_or_alloc_existing_domain(domid);
+ if (!domain)
+ return ENOENT;
+ features = domain->features;
+ } else
+ features = XENSTORE_FEATURES;
+
+ result = talloc_asprintf(ctx, "%u", features);
+ if (!result)
+ return ENOMEM;
+
+ send_reply(conn, XS_GET_FEATURE, result, strlen(result) + 1);
+
+ return 0;
+}
+
+int do_set_feature(const void *ctx, struct connection *conn,
+ struct buffered_data *in)
+{
+ const char *vec[2];
+ unsigned int domid;
+ struct domain *domain;
+ unsigned int features;
+
+ if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec))
+ return EINVAL;
+
+ domid = atoi(vec[0]);
+ features = atoi(vec[1]);
+ domain = find_or_alloc_existing_domain(domid);
+ if (!domain)
+ return ENOENT;
+ if (domain->introduced)
+ return EBUSY;
+ if (features & ~XENSTORE_FEATURES)
+ return EINVAL;
+
+ domain->features = features;
+
+ send_ack(conn, XS_SET_FEATURE);
+
+ return 0;
+}
+
static int close_xgt_handle(void *_handle)
{
xengnttab_close(*(xengnttab_handle **)_handle);
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 8bfaca8f90..94481fdcc0 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -82,6 +82,14 @@ int do_get_domain_path(const void *ctx, struct connection *conn,
int do_reset_watches(const void *ctx, struct connection *conn,
struct buffered_data *in);
+/* Get global or per domain server features */
+int do_get_feature(const void *ctx, struct connection *conn,
+ struct buffered_data *in);
+
+/* Set per domain server features */
+int do_set_feature(const void *ctx, struct connection *conn,
+ struct buffered_data *in);
+
void domain_early_init(void);
void domain_init(int evtfd);
void dom0_init(void);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 6/7] tools/xl: add available Xenstore features to xl info output
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
` (4 preceding siblings ...)
2025-07-25 13:19 ` [PATCH v2 5/7] tools/xenstored: support SET/GET_FEATURE commands Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-30 16:02 ` Anthony PERARD
2025-07-25 13:19 ` [PATCH v2 7/7] tools: allow to limit xenstore features via guest config Juergen Gross
6 siblings, 1 reply; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel; +Cc: Juergen Gross, Anthony PERARD, Jason Andryuk
Add the Xenstore feature value to the output of "xl info" in order to
prepare for a future capability to limit Xenstore features visible by
a guest.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
tools/xl/Makefile | 3 ++-
tools/xl/xl_info.c | 22 ++++++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/xl/Makefile b/tools/xl/Makefile
index d742e96a5b..ad577cdd70 100644
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -13,6 +13,7 @@ LDFLAGS += $(PTHREAD_LDFLAGS)
CFLAGS_XL += $(CFLAGS_libxenlight)
CFLAGS_XL += $(CFLAGS_libxenutil)
+CFLAGS_XL += $(CFLAGS_libxenstore)
CFLAGS_XL += -Wshadow
XL_OBJS-$(CONFIG_X86) = xl_psr.o
@@ -32,7 +33,7 @@ $(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs i
all: xl
xl: $(XL_OBJS)
- $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) -lyajl $(APPEND_LDFLAGS)
+ $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) -lyajl $(APPEND_LDFLAGS)
.PHONY: install
install: all
diff --git a/tools/xl/xl_info.c b/tools/xl/xl_info.c
index 72e87eac46..eb019e3ee9 100644
--- a/tools/xl/xl_info.c
+++ b/tools/xl/xl_info.c
@@ -28,6 +28,7 @@
#include <libxl_utils.h>
#include <libxlutil.h>
#include <xen-tools/arm-arch-capabilities.h>
+#include <xenstore.h>
#include "xl.h"
#include "xl_utils.h"
@@ -333,6 +334,25 @@ static void output_topologyinfo(void)
return;
}
+static void output_xenstore_info(void)
+{
+ struct xs_handle *xsh;
+ unsigned int features = 0;
+
+ xsh = xs_open(0);
+ if (!xsh) {
+ fprintf(stderr, "xs_open failed.\n");
+ return;
+ }
+
+ /* Ignore error, default to "0" for features. */
+ xs_get_features_supported(xsh, &features);
+
+ maybe_printf("xenstore_features : 0x%08x\n", features);
+
+ xs_close(xsh);
+}
+
static void print_info(int numa)
{
output_nodeinfo();
@@ -345,6 +365,8 @@ static void print_info(int numa)
}
output_xeninfo();
+ output_xenstore_info();
+
maybe_printf("xend_config_format : 4\n");
return;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 7/7] tools: allow to limit xenstore features via guest config
2025-07-25 13:19 [PATCH v2 0/7] tools: add support for domain specific Xenstore features Juergen Gross
` (5 preceding siblings ...)
2025-07-25 13:19 ` [PATCH v2 6/7] tools/xl: add available Xenstore features to xl info output Juergen Gross
@ 2025-07-25 13:19 ` Juergen Gross
2025-07-25 14:33 ` Nick Rosbrook
2025-07-30 16:21 ` Anthony PERARD
6 siblings, 2 replies; 13+ messages in thread
From: Juergen Gross @ 2025-07-25 13:19 UTC (permalink / raw)
To: xen-devel
Cc: Juergen Gross, Anthony PERARD, Nick Rosbrook, George Dunlap,
Jason Andryuk
Add a guest config parameter "xenstore_feature_mask" allowing to limit
the Xenstore features the guest can see and use. This can be needed in
order to allow migrating a guest to a host running a Xenstore version
providing less features than the source host.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
V2:
- fix typo (Jason Andryuk)
---
docs/man/xl.cfg.5.pod.in | 36 ++++++++++++++++++++++++++++
tools/golang/xenlight/helpers.gen.go | 2 ++
tools/golang/xenlight/types.gen.go | 1 +
tools/include/libxl.h | 6 +++++
tools/libs/light/libxl_dom.c | 12 ++++++++++
tools/libs/light/libxl_types.idl | 1 +
tools/xl/xl_parse.c | 3 +++
7 files changed, 61 insertions(+)
diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 1d122982c6..4efe680960 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -714,6 +714,42 @@ If this option is not specified then it will default to B<false>.
=back
+=head3 Xenstore related settings
+
+=over 4
+
+=item B<xenstore_feature_mask=NUMBER>
+
+Specify which Xenstore features are visible for the guest.
+
+This might be needed when a guest should be able to be migrated to a host
+running a Xenstore implementation with less features than the one the guest
+is created on.
+
+The visible features are specified via a binary or of the following
+values:
+
+=over 4
+
+=item B<0x00000001>
+
+Xenstore is capable to reconnect to a guest.
+
+=item B<0x00000002>
+
+Xenstore will present an error value in case it disconnects due to an error
+condition.
+
+=back
+
+The features supported by the running Xenstore instance can be retrieved
+via the B<xl info> command in dom0.
+
+The default value is B<0xffffffff>, meaning that all possible Xenstore
+features are visible by the guest.
+
+=back
+
=head2 Devices
The following options define the paravirtual, emulated and physical
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index c45df1005f..429aee3950 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1174,6 +1174,7 @@ return fmt.Errorf("converting field Vpmu: %v", err)
if err := x.TrapUnmappedAccesses.fromC(&xc.trap_unmapped_accesses);err != nil {
return fmt.Errorf("converting field TrapUnmappedAccesses: %v", err)
}
+x.XenstoreFeatureMask = uint32(xc.xenstore_feature_mask)
return nil}
@@ -1708,6 +1709,7 @@ return fmt.Errorf("converting field Vpmu: %v", err)
if err := x.TrapUnmappedAccesses.toC(&xc.trap_unmapped_accesses); err != nil {
return fmt.Errorf("converting field TrapUnmappedAccesses: %v", err)
}
+xc.xenstore_feature_mask = C.uint32_t(x.XenstoreFeatureMask)
return nil
}
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index 61e322f20a..c9ba4d2844 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -607,6 +607,7 @@ Altp2M Altp2MMode
VmtraceBufKb int
Vpmu Defbool
TrapUnmappedAccesses Defbool
+XenstoreFeatureMask uint32
}
type DomainBuildInfoTypeUnion interface {
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index a8704e0268..1d4510506c 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -654,6 +654,12 @@
*/
#define LIBXL_HAVE_DT_OVERLAY_DOMAIN 1
+/*
+ * LIBXL_HAVE_XENSTORE_FEATURE_MASK indicates the presence of
+ * xenstore_feature_mask in struct libxl_domain_build_info.
+ */
+#define LIBXL_HAVE_XENSTORE_FEATURE_MASK 1
+
/*
* libxl memory management
*
diff --git a/tools/libs/light/libxl_dom.c b/tools/libs/light/libxl_dom.c
index a61085ca3b..2a7923533f 100644
--- a/tools/libs/light/libxl_dom.c
+++ b/tools/libs/light/libxl_dom.c
@@ -494,6 +494,18 @@ retry_transaction:
if (!xs_transaction_end(ctx->xsh, t, 0))
if (errno == EAGAIN)
goto retry_transaction;
+
+ if (info->xenstore_feature_mask != ~0U) {
+ unsigned int features;
+
+ if (xs_get_features_supported(ctx->xsh, &features) &&
+ !xs_set_features_domain(ctx->xsh, domid,
+ features & info->xenstore_feature_mask)) {
+ LOG(ERROR, "Failed to set Xenstore features");
+ return ERROR_FAIL;
+ }
+ }
+
xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port);
free(vm_path);
return 0;
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index a3a79d12b2..99ab2c3ebb 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -738,6 +738,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
("vpmu", libxl_defbool),
("trap_unmapped_accesses", libxl_defbool),
+ ("xenstore_feature_mask", uint32, {'init_val': '~0U'}),
], dir=DIR_IN,
copy_deprecated_fn="libxl__domain_build_info_copy_deprecated",
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 7e11c62ba0..aaeace1840 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1409,6 +1409,9 @@ void parse_config_data(const char *config_source,
if (!xlu_cfg_get_string (config, "pool", &buf, 0))
xlu_cfg_replace_string(config, "pool", &c_info->pool_name, 0);
+ if (!xlu_cfg_get_long (config, "xenstore_feature_mask", &l, 0))
+ b_info->xenstore_feature_mask = l;
+
libxl_domain_build_info_init_type(b_info, c_info->type);
if (b_info->type == LIBXL_DOMAIN_TYPE_PVH) {
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 7/7] tools: allow to limit xenstore features via guest config
2025-07-25 13:19 ` [PATCH v2 7/7] tools: allow to limit xenstore features via guest config Juergen Gross
@ 2025-07-25 14:33 ` Nick Rosbrook
2025-07-30 16:21 ` Anthony PERARD
1 sibling, 0 replies; 13+ messages in thread
From: Nick Rosbrook @ 2025-07-25 14:33 UTC (permalink / raw)
To: Juergen Gross
Cc: xen-devel, Anthony PERARD, Nick Rosbrook, George Dunlap,
Jason Andryuk
On Fri, Jul 25, 2025 at 9:20 AM Juergen Gross <jgross@suse.com> wrote:
>
> Add a guest config parameter "xenstore_feature_mask" allowing to limit
> the Xenstore features the guest can see and use. This can be needed in
> order to allow migrating a guest to a host running a Xenstore version
> providing less features than the source host.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
> ---
> V2:
> - fix typo (Jason Andryuk)
> ---
> docs/man/xl.cfg.5.pod.in | 36 ++++++++++++++++++++++++++++
> tools/golang/xenlight/helpers.gen.go | 2 ++
> tools/golang/xenlight/types.gen.go | 1 +
> tools/include/libxl.h | 6 +++++
> tools/libs/light/libxl_dom.c | 12 ++++++++++
> tools/libs/light/libxl_types.idl | 1 +
> tools/xl/xl_parse.c | 3 +++
> 7 files changed, 61 insertions(+)
>
For tools/golang:
Acked-by: Nick Rosbrook <enr0n@ubuntu.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 7/7] tools: allow to limit xenstore features via guest config
2025-07-25 13:19 ` [PATCH v2 7/7] tools: allow to limit xenstore features via guest config Juergen Gross
2025-07-25 14:33 ` Nick Rosbrook
@ 2025-07-30 16:21 ` Anthony PERARD
2025-07-30 18:23 ` Jürgen Groß
1 sibling, 1 reply; 13+ messages in thread
From: Anthony PERARD @ 2025-07-30 16:21 UTC (permalink / raw)
To: Juergen Gross
Cc: xen-devel, Anthony PERARD, Nick Rosbrook, George Dunlap,
Jason Andryuk
On Fri, Jul 25, 2025 at 03:19:28PM +0200, Juergen Gross wrote:
> diff --git a/tools/libs/light/libxl_dom.c b/tools/libs/light/libxl_dom.c
> index a61085ca3b..2a7923533f 100644
> --- a/tools/libs/light/libxl_dom.c
> +++ b/tools/libs/light/libxl_dom.c
> @@ -494,6 +494,18 @@ retry_transaction:
> if (!xs_transaction_end(ctx->xsh, t, 0))
> if (errno == EAGAIN)
> goto retry_transaction;
> +
> + if (info->xenstore_feature_mask != ~0U) {
> + unsigned int features;
> +
> + if (xs_get_features_supported(ctx->xsh, &features) &&
> + !xs_set_features_domain(ctx->xsh, domid,
> + features & info->xenstore_feature_mask)) {
> + LOG(ERROR, "Failed to set Xenstore features");
Surly xs_{get,set}* set errno on failure, and we know the domid, can you
use LOGED for the error message?
> + return ERROR_FAIL;
Unfortunately, this function does an allocation that isn't collected in
GC, `vm_path` is leaked. Could you replace that by `rc=ERROR_FAIL; goto
out;`, then place out: at the right place and return `rc` at the end of
the function?
> + }
> + }
> +
> xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port);
> free(vm_path);
> return 0;
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 7/7] tools: allow to limit xenstore features via guest config
2025-07-30 16:21 ` Anthony PERARD
@ 2025-07-30 18:23 ` Jürgen Groß
0 siblings, 0 replies; 13+ messages in thread
From: Jürgen Groß @ 2025-07-30 18:23 UTC (permalink / raw)
To: Anthony PERARD
Cc: xen-devel, Anthony PERARD, Nick Rosbrook, George Dunlap,
Jason Andryuk
[-- Attachment #1.1.1: Type: text/plain, Size: 1303 bytes --]
On 30.07.25 18:21, Anthony PERARD wrote:
> On Fri, Jul 25, 2025 at 03:19:28PM +0200, Juergen Gross wrote:
>> diff --git a/tools/libs/light/libxl_dom.c b/tools/libs/light/libxl_dom.c
>> index a61085ca3b..2a7923533f 100644
>> --- a/tools/libs/light/libxl_dom.c
>> +++ b/tools/libs/light/libxl_dom.c
>> @@ -494,6 +494,18 @@ retry_transaction:
>> if (!xs_transaction_end(ctx->xsh, t, 0))
>> if (errno == EAGAIN)
>> goto retry_transaction;
>> +
>> + if (info->xenstore_feature_mask != ~0U) {
>> + unsigned int features;
>> +
>> + if (xs_get_features_supported(ctx->xsh, &features) &&
>> + !xs_set_features_domain(ctx->xsh, domid,
>> + features & info->xenstore_feature_mask)) {
>> + LOG(ERROR, "Failed to set Xenstore features");
>
> Surly xs_{get,set}* set errno on failure, and we know the domid, can you
> use LOGED for the error message?
Okay.
>
>> + return ERROR_FAIL;
>
> Unfortunately, this function does an allocation that isn't collected in
> GC, `vm_path` is leaked. Could you replace that by `rc=ERROR_FAIL; goto
> out;`, then place out: at the right place and return `rc` at the end of
> the function?
Yes, of course.
Thanks,
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread