[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 |