|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] tools: Introduce a non-truncating xc_xenver_extraversion()
commit 504ea442e35a29b8de4660873b7ebafc12386531
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Jan 16 16:56:17 2023 +0000
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Dec 20 22:44:42 2024 +0000
tools: Introduce a non-truncating xc_xenver_extraversion()
... which uses XENVER_extraversion2.
In order to do this sensibly, use manual hypercall buffer handling. Not
only
does this avoid an extra bounce buffer (we need to strip the xen_varbuf_t
header anyway), it's also shorter and easlier to follow.
Update libxl and the ocaml stubs to match. No API/ABI change in either.
With this change made, `xl info` can now correctly access a >15 char
extraversion:
# xl info xen_version
4.18-unstable+REALLY LONG EXTRAVERSION
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Acked-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
Acked-by: Christian Lindig <christian.lindig@xxxxxxxxxx>
---
tools/include/xenctrl.h | 6 +++
tools/libs/ctrl/xc_version.c | 75 +++++++++++++++++++++++++++++++++++++
tools/libs/light/libxl.c | 4 +-
tools/ocaml/libs/xc/xenctrl_stubs.c | 9 +++--
4 files changed, 87 insertions(+), 7 deletions(-)
diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index b08e438ea8..879b626614 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -1573,6 +1573,12 @@ long xc_memory_op(xc_interface *xch, unsigned int cmd,
void *arg, size_t len);
int xc_version(xc_interface *xch, int cmd, void *arg);
+/*
+ * Wrappers around XENVER_* subops. Callers must pass the returned pointer to
+ * free().
+ */
+char *xc_xenver_extraversion(xc_interface *xch);
+
int xc_flask_op(xc_interface *xch, xen_flask_op_t *op);
/*
diff --git a/tools/libs/ctrl/xc_version.c b/tools/libs/ctrl/xc_version.c
index 60e107dcee..2c14474fee 100644
--- a/tools/libs/ctrl/xc_version.c
+++ b/tools/libs/ctrl/xc_version.c
@@ -81,3 +81,78 @@ int xc_version(xc_interface *xch, int cmd, void *arg)
return rc;
}
+
+/*
+ * Raw hypercall wrapper, letting us pass NULL and things which aren't of
+ * xc_hypercall_buffer_t *.
+ */
+static int do_xen_version_raw(xc_interface *xch, int cmd, void *hbuf)
+{
+ return xencall2(xch->xcall, __HYPERVISOR_xen_version,
+ cmd, (unsigned long)hbuf);
+}
+
+/*
+ * Issues a xen_varbuf_t subop, using manual hypercall buffer handling to
+ * avoid unnecessary buffering.
+ *
+ * On failure, returns NULL. errno probably useful.
+ * On success, returns a pointer which must be freed with
xencall_free_buffer().
+ */
+static xen_varbuf_t *varbuf_op(xc_interface *xch, unsigned int subop)
+{
+ xen_varbuf_t *hbuf = NULL;
+ ssize_t sz;
+
+ sz = do_xen_version_raw(xch, subop, NULL);
+ if ( sz < 0 )
+ return NULL;
+
+ hbuf = xencall_alloc_buffer(xch->xcall, sizeof(*hbuf) + sz);
+ if ( !hbuf )
+ return NULL;
+
+ hbuf->len = sz;
+
+ sz = do_xen_version_raw(xch, subop, hbuf);
+ if ( sz < 0 )
+ {
+ xencall_free_buffer(xch->xcall, hbuf);
+ return NULL;
+ }
+
+ hbuf->len = sz;
+ return hbuf;
+}
+
+/*
+ * Wrap varbuf_op() to obtain a simple string. Copy out of the hypercall
+ * buffer, stripping the xen_varbuf_t header and appending a NUL terminator.
+ *
+ * On failure, returns NULL, errno probably useful.
+ * On success, returns a pointer which must be free()'d.
+ */
+static char *varbuf_simple_string(xc_interface *xch, unsigned int subop)
+{
+ xen_varbuf_t *hbuf = varbuf_op(xch, subop);
+ char *res;
+
+ if ( !hbuf )
+ return NULL;
+
+ res = malloc(hbuf->len + 1);
+ if ( res )
+ {
+ memcpy(res, hbuf->buf, hbuf->len);
+ res[hbuf->len] = '\0';
+ }
+
+ xencall_free_buffer(xch->xcall, hbuf);
+
+ return res;
+}
+
+char *xc_xenver_extraversion(xc_interface *xch)
+{
+ return varbuf_simple_string(xch, XENVER_extraversion2);
+}
diff --git a/tools/libs/light/libxl.c b/tools/libs/light/libxl.c
index 175d6dde0b..f91f7271d5 100644
--- a/tools/libs/light/libxl.c
+++ b/tools/libs/light/libxl.c
@@ -582,7 +582,6 @@ const libxl_version_info* libxl_get_version_info(libxl_ctx
*ctx)
{
GC_INIT(ctx);
union {
- xen_extraversion_t xen_extra;
xen_compile_info_t xen_cc;
xen_changeset_info_t xen_chgset;
xen_capabilities_info_t xen_caps;
@@ -601,8 +600,7 @@ const libxl_version_info* libxl_get_version_info(libxl_ctx
*ctx)
info->xen_version_major = xen_version >> 16;
info->xen_version_minor = xen_version & 0xFF;
- xc_version(ctx->xch, XENVER_extraversion, &u.xen_extra);
- info->xen_version_extra = libxl__strdup(NOGC, u.xen_extra);
+ info->xen_version_extra = xc_xenver_extraversion(ctx->xch);
xc_version(ctx->xch, XENVER_compile_info, &u.xen_cc);
info->compiler = libxl__strdup(NOGC, u.xen_cc.compiler);
diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
b/tools/ocaml/libs/xc/xenctrl_stubs.c
index c78191f95a..1dd12081e9 100644
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
@@ -985,9 +985,8 @@ CAMLprim value stub_xc_version_version(value xch_val)
CAMLparam1(xch_val);
CAMLlocal1(result);
xc_interface *xch = xch_of_val(xch_val);
- xen_extraversion_t extra;
+ char *extra;
long packed;
- int retval;
caml_enter_blocking_section();
packed = xc_version(xch, XENVER_version, NULL);
@@ -997,10 +996,10 @@ CAMLprim value stub_xc_version_version(value xch_val)
failwith_xc(xch);
caml_enter_blocking_section();
- retval = xc_version(xch, XENVER_extraversion, &extra);
+ extra = xc_xenver_extraversion(xch);
caml_leave_blocking_section();
- if (retval)
+ if (!extra)
failwith_xc(xch);
result = caml_alloc_tuple(3);
@@ -1009,6 +1008,8 @@ CAMLprim value stub_xc_version_version(value xch_val)
Store_field(result, 1, Val_int(packed & 0xffff));
Store_field(result, 2, caml_copy_string(extra));
+ free(extra);
+
CAMLreturn(result);
}
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |