Add some functions allowing to retrieve and set Xenstore quota (either
global or domain specific).
Signed-off-by: Juergen Gross <jgross@suse.com>
---
tools/golang/xenlight/helpers.gen.go | 78 ++++++++++++++++++++
tools/golang/xenlight/types.gen.go | 9 +++
tools/include/libxl.h | 20 ++++++
tools/libs/light/Makefile | 1 +
tools/libs/light/libxl_types.idl | 9 +++
tools/libs/light/libxl_xsquota.c | 102 +++++++++++++++++++++++++++
6 files changed, 219 insertions(+)
create mode 100644 tools/libs/light/libxl_xsquota.c
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index 8909fe8a1b..6c9af904c5 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -998,6 +998,84 @@ xc.policy = C.libxl_rdm_reserve_policy(x.Policy)
return nil
}
+// NewXsQuotaItem returns an instance of XsQuotaItem initialized with defaults.
+func NewXsQuotaItem() (*XsQuotaItem, error) {
+var (
+x XsQuotaItem
+xc C.libxl_xs_quota_item)
+
+C.libxl_xs_quota_item_init(&xc)
+defer C.libxl_xs_quota_item_dispose(&xc)
+
+if err := x.fromC(&xc); err != nil {
+return nil, err }
+
+return &x, nil}
+
+func (x *XsQuotaItem) fromC(xc *C.libxl_xs_quota_item) error {
+ x.Name = C.GoString(xc.name)
+x.Val = uint32(xc.val)
+
+ return nil}
+
+func (x *XsQuotaItem) toC(xc *C.libxl_xs_quota_item) (err error){defer func(){
+if err != nil{
+C.libxl_xs_quota_item_dispose(xc)}
+}()
+
+if x.Name != "" {
+xc.name = C.CString(x.Name)}
+xc.val = C.uint32_t(x.Val)
+
+ return nil
+ }
+
+// NewXsQuotaSet returns an instance of XsQuotaSet initialized with defaults.
+func NewXsQuotaSet() (*XsQuotaSet, error) {
+var (
+x XsQuotaSet
+xc C.libxl_xs_quota_set)
+
+C.libxl_xs_quota_set_init(&xc)
+defer C.libxl_xs_quota_set_dispose(&xc)
+
+if err := x.fromC(&xc); err != nil {
+return nil, err }
+
+return &x, nil}
+
+func (x *XsQuotaSet) fromC(xc *C.libxl_xs_quota_set) error {
+ x.Quota = nil
+if n := int(xc.num_quota); n > 0 {
+cQuota := (*[1<<28]C.libxl_xs_quota_item)(unsafe.Pointer(xc.quota))[:n:n]
+x.Quota = make([]XsQuotaItem, n)
+for i, v := range cQuota {
+if err := x.Quota[i].fromC(&v); err != nil {
+return fmt.Errorf("converting field Quota: %v", err) }
+}
+}
+
+ return nil}
+
+func (x *XsQuotaSet) toC(xc *C.libxl_xs_quota_set) (err error){defer func(){
+if err != nil{
+C.libxl_xs_quota_set_dispose(xc)}
+}()
+
+if numQuota := len(x.Quota); numQuota > 0 {
+xc.quota = (*C.libxl_xs_quota_item)(C.malloc(C.ulong(numQuota)*C.sizeof_libxl_xs_quota_item))
+xc.num_quota = C.int(numQuota)
+cQuota := (*[1<<28]C.libxl_xs_quota_item)(unsafe.Pointer(xc.quota))[:numQuota:numQuota]
+for i,v := range x.Quota {
+if err := v.toC(&cQuota[i]); err != nil {
+return fmt.Errorf("converting field Quota: %v", err)
+}
+}
+}
+
+ return nil
+ }
+
// NewDomainBuildInfo returns an instance of DomainBuildInfo initialized with defaults.
func NewDomainBuildInfo(dtype DomainType) (*DomainBuildInfo, error) {
var (
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index ab9d4ca7b4..5393277190 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -543,6 +543,15 @@ Altp2MModeExternal Altp2MMode = 2
Altp2MModeLimited Altp2MMode = 3
)
+type XsQuotaItem struct {
+Name string
+Val uint32
+}
+
+type XsQuotaSet struct {
+Quota []XsQuotaItem
+}
+
type DomainBuildInfo struct {
MaxVcpus int
AvailVcpus Bitmap
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index bc35e412da..a70d9d347f 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -1537,6 +1537,18 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
*/
#define LIBXL_HAVE_XEN_PLATFORM_PCI_BAR_UC
+/*
+ * LIBXL_HAVE_XENSTORE_QUOTA
+ *
+ * If this is defined the Xenstore quota related functions
+ * libxl_xsquota_global_get()
+ * libxl_xsquota_global_set()
+ * libxl_xsquota_domain_get()
+ * libxl_xsquota_domain_set()
+ * are available.
+ */
+#define LIBXL_HAVE_XENSTORE_QUOTA
+
typedef char **libxl_string_list;
void libxl_string_list_dispose(libxl_string_list *sl);
int libxl_string_list_length(const libxl_string_list *sl);
@@ -3011,6 +3023,14 @@ static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
#define libxl_qemu_monitor_command libxl_qemu_monitor_command_0x041200
#endif
+/* Get/set global and per-domain Xenstore quota. */
+int libxl_xsquota_global_get(libxl_ctx *ctx, libxl_xs_quota_set *q);
+int libxl_xsquota_global_set(libxl_ctx *ctx, libxl_xs_quota_set *q);
+int libxl_xsquota_domain_get(libxl_ctx *ctx, uint32_t domid,
+ libxl_xs_quota_set *q);
+int libxl_xsquota_domain_set(libxl_ctx *ctx, uint32_t domid,
+ libxl_xs_quota_set *q);
+
#include <libxl_event.h>
/*
diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile
index bc60c46558..ca22a40c6c 100644
--- a/tools/libs/light/Makefile
+++ b/tools/libs/light/Makefile
@@ -106,6 +106,7 @@ OBJS-y += libxl_pvcalls.o
OBJS-y += libxl_vsnd.o
OBJS-y += libxl_vkb.o
OBJS-y += libxl_virtio.o
+OBJS-y += libxl_xsquota.o
OBJS-y += libxl_genid.o
OBJS-y += _libxl_types.o
OBJS-y += libxl_flask.o
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index d64a573ff3..c5ddc40f35 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -574,6 +574,15 @@ libxl_altp2m_mode = Enumeration("altp2m_mode", [
(3, "limited"),
], init_val = "LIBXL_ALTP2M_MODE_DISABLED")
+libxl_xs_quota_item = Struct("xs_quota_item", [
+ ("name", string),
+ ("val", uint32),
+ ])
+
+libxl_xs_quota_set = Struct("xs_quota_set", [
+ ("quota", Array(libxl_xs_quota_item, "num_quota"))
+ ])
+
libxl_domain_build_info = Struct("domain_build_info",[
("max_vcpus", integer),
("avail_vcpus", libxl_bitmap),
diff --git a/tools/libs/light/libxl_xsquota.c b/tools/libs/light/libxl_xsquota.c
new file mode 100644
index 0000000000..b9afa1c914
--- /dev/null
+++ b/tools/libs/light/libxl_xsquota.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Xenstore quota handling functions. */
+
+#include "libxl_internal.h"
+
+static int get_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_set *q,
+ bool (func)(struct xs_handle *h, unsigned int domid,
+ char *quota, unsigned int *value))
+{
+ char **names;
+ unsigned int num, i;
+ int rc = 0;
+ GC_INIT(ctx);
+
+ names = xs_get_quota_names(ctx->xsh, &num);
+ if (!names) {
+ /* Xenstore quota support is optional! */
+ if (errno != ENOSYS)
+ rc = ERROR_FAIL;
+ q->num_quota = 0;
+ goto out;
+ }
+
+ q->num_quota = num;
+ q->quota = libxl__calloc(NOGC, num, sizeof(*q->quota));
+ for (i = 0; i < num; i++) {
+ q->quota[i].name = libxl__strdup(NOGC, names[i]);
+ if (!func(ctx->xsh, domid, q->quota[i].name, &q->quota[i].val)) {
+ libxl_xs_quota_set_dispose(q);
+ rc = ERROR_FAIL;
+ break;
+ }
+ }
+
+ free(names);
+
+ out:
+ GC_FREE;
+ return rc;
+}
+
+static int set_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_set *q,
+ bool (func)(struct xs_handle *h, unsigned int domid,
+ char *quota, unsigned int value))
+{
+ unsigned int i;
+ int rc = 0;
+ GC_INIT(ctx);
+
+ for (i = 0; i < q->num_quota; i++) {
+ if (!func(ctx->xsh, domid, q->quota[i].name, q->quota[i].val)) {
+ rc = ERROR_FAIL;
+ break;
+ }
+ }
+
+ GC_FREE;
+ return rc;
+}
+
+static bool get_global_quota(struct xs_handle *h, unsigned int domid,
+ char *quota, unsigned int *value)
+{
+ return xs_get_global_quota(h, quota, value);
+}
+
+int libxl_xsquota_global_get(libxl_ctx *ctx, libxl_xs_quota_set *q)
+{
+ return get_quota(ctx, 0, q, get_global_quota);
+}
+
+static bool set_global_quota(struct xs_handle *h, unsigned int domid,
+ char *quota, unsigned int value)
+{
+ return xs_set_global_quota(h, quota, value);
+}
+
+int libxl_xsquota_global_set(libxl_ctx *ctx, libxl_xs_quota_set *q)
+{
+ return set_quota(ctx, 0, q, set_global_quota);;
+}
+
+int libxl_xsquota_domain_get(libxl_ctx *ctx, uint32_t domid,
+ libxl_xs_quota_set *q)
+{
+ return get_quota(ctx, domid, q, xs_get_domain_quota);
+}
+
+int libxl_xsquota_domain_set(libxl_ctx *ctx, uint32_t domid,
+ libxl_xs_quota_set *q)
+{
+ return set_quota(ctx, domid, q, xs_set_domain_quota);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.53.0
On Thu, Mar 05, 2026 at 02:52:05PM +0100, Juergen Gross wrote:
> diff --git a/tools/include/libxl.h b/tools/include/libxl.h
> index bc35e412da..a70d9d347f 100644
> --- a/tools/include/libxl.h
> +++ b/tools/include/libxl.h
> @@ -1537,6 +1537,18 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
> */
> #define LIBXL_HAVE_XEN_PLATFORM_PCI_BAR_UC
>
> +/*
> + * LIBXL_HAVE_XENSTORE_QUOTA
> + *
> + * If this is defined the Xenstore quota related functions
> + * libxl_xsquota_global_get()
> + * libxl_xsquota_global_set()
> + * libxl_xsquota_domain_get()
> + * libxl_xsquota_domain_set()
> + * are available.
> + */
> +#define LIBXL_HAVE_XENSTORE_QUOTA
> +
> typedef char **libxl_string_list;
> void libxl_string_list_dispose(libxl_string_list *sl);
> int libxl_string_list_length(const libxl_string_list *sl);
> @@ -3011,6 +3023,14 @@ static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
> #define libxl_qemu_monitor_command libxl_qemu_monitor_command_0x041200
> #endif
>
> +/* Get/set global and per-domain Xenstore quota. */
> +int libxl_xsquota_global_get(libxl_ctx *ctx, libxl_xs_quota_set *q);
Could you rename the second arg as "q_r" or "q_out" ?
> +int libxl_xsquota_global_set(libxl_ctx *ctx, libxl_xs_quota_set *q);
> +int libxl_xsquota_domain_get(libxl_ctx *ctx, uint32_t domid,
> + libxl_xs_quota_set *q);
Same here.
> +int libxl_xsquota_domain_set(libxl_ctx *ctx, uint32_t domid,
> + libxl_xs_quota_set *q);
Could we prefix them all with "libxl_xs_quota_" ? I would rather that we
only use "xs_quota" or "xsquota".
> +
> #include <libxl_event.h>
>
> /*
> diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile
> index bc60c46558..ca22a40c6c 100644
> --- a/tools/libs/light/Makefile
> +++ b/tools/libs/light/Makefile
> @@ -106,6 +106,7 @@ OBJS-y += libxl_pvcalls.o
> OBJS-y += libxl_vsnd.o
> OBJS-y += libxl_vkb.o
> OBJS-y += libxl_virtio.o
> +OBJS-y += libxl_xsquota.o
> OBJS-y += libxl_genid.o
> OBJS-y += _libxl_types.o
> OBJS-y += libxl_flask.o
> diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
> index d64a573ff3..c5ddc40f35 100644
> --- a/tools/libs/light/libxl_types.idl
> +++ b/tools/libs/light/libxl_types.idl
> @@ -574,6 +574,15 @@ libxl_altp2m_mode = Enumeration("altp2m_mode", [
> (3, "limited"),
> ], init_val = "LIBXL_ALTP2M_MODE_DISABLED")
>
> +libxl_xs_quota_item = Struct("xs_quota_item", [
> + ("name", string),
> + ("val", uint32),
> + ])
> +
> +libxl_xs_quota_set = Struct("xs_quota_set", [
Could you use "_list" as a suffix instead? It's a bit confusing to have
the word "set" as a double meaning, with a _set() function that takes a
set.
> + ("quota", Array(libxl_xs_quota_item, "num_quota"))
> + ])
> +
> libxl_domain_build_info = Struct("domain_build_info",[
> ("max_vcpus", integer),
> ("avail_vcpus", libxl_bitmap),
> diff --git a/tools/libs/light/libxl_xsquota.c b/tools/libs/light/libxl_xsquota.c
> new file mode 100644
> index 0000000000..b9afa1c914
> --- /dev/null
> +++ b/tools/libs/light/libxl_xsquota.c
> @@ -0,0 +1,102 @@
> +/* SPDX-License-Identifier: LGPL-2.1-only */
> +
> +/* Xenstore quota handling functions. */
> +
> +#include "libxl_internal.h"
> +
> +static int get_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_set *q,
> + bool (func)(struct xs_handle *h, unsigned int domid,
> + char *quota, unsigned int *value))
> +{
> + char **names;
> + unsigned int num, i;
> + int rc = 0;
We don't init `rc` variable in libxl function. Set `rc` to 0 just before
the "out" label.
> + GC_INIT(ctx);
> +
> + names = xs_get_quota_names(ctx->xsh, &num);
> + if (!names) {
> + /* Xenstore quota support is optional! */
> + if (errno != ENOSYS)
> + rc = ERROR_FAIL;
> + q->num_quota = 0;
It feels wrong to make changes to the output argument on error, if we
can avoid it. And here, I don't see any reason to change `q`.
> + goto out;
> + }
> +
Can you call libxl_xs_quota_set_init() first? As you call _dispose()
later.
> + q->num_quota = num;
> + q->quota = libxl__calloc(NOGC, num, sizeof(*q->quota));
> + for (i = 0; i < num; i++) {
> + q->quota[i].name = libxl__strdup(NOGC, names[i]);
> + if (!func(ctx->xsh, domid, q->quota[i].name, &q->quota[i].val)) {
Could you store the return value of `func()` in `ok`, and test `ok` in the
if instead?
> + libxl_xs_quota_set_dispose(q);
> + rc = ERROR_FAIL;
> + break;
This can be `goto out` once free(names) is moved to the out label.
> + }
> + }
> +
> + free(names);
Could you do that after the "out" label? And init `names` to NULL.
> +
> + out:
> + GC_FREE;
> + return rc;
> +}
> +
> +static int set_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_set *q,
> + bool (func)(struct xs_handle *h, unsigned int domid,
> + char *quota, unsigned int value))
> +{
> + unsigned int i;
> + int rc = 0;
> + GC_INIT(ctx);
> +
> + for (i = 0; i < q->num_quota; i++) {
> + if (!func(ctx->xsh, domid, q->quota[i].name, q->quota[i].val)) {
> + rc = ERROR_FAIL;
> + break;
It would be better to write `goto out` instead.
> + }
> + }
> +
> + GC_FREE;
> + return rc;
> +}
Thanks,
--
| Vates
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
On 19.03.26 10:11, Anthony PERARD wrote:
> On Thu, Mar 05, 2026 at 02:52:05PM +0100, Juergen Gross wrote:
>> diff --git a/tools/include/libxl.h b/tools/include/libxl.h
>> index bc35e412da..a70d9d347f 100644
>> --- a/tools/include/libxl.h
>> +++ b/tools/include/libxl.h
>> @@ -1537,6 +1537,18 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
>> */
>> #define LIBXL_HAVE_XEN_PLATFORM_PCI_BAR_UC
>>
>> +/*
>> + * LIBXL_HAVE_XENSTORE_QUOTA
>> + *
>> + * If this is defined the Xenstore quota related functions
>> + * libxl_xsquota_global_get()
>> + * libxl_xsquota_global_set()
>> + * libxl_xsquota_domain_get()
>> + * libxl_xsquota_domain_set()
>> + * are available.
>> + */
>> +#define LIBXL_HAVE_XENSTORE_QUOTA
>> +
>> typedef char **libxl_string_list;
>> void libxl_string_list_dispose(libxl_string_list *sl);
>> int libxl_string_list_length(const libxl_string_list *sl);
>> @@ -3011,6 +3023,14 @@ static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
>> #define libxl_qemu_monitor_command libxl_qemu_monitor_command_0x041200
>> #endif
>>
>> +/* Get/set global and per-domain Xenstore quota. */
>> +int libxl_xsquota_global_get(libxl_ctx *ctx, libxl_xs_quota_set *q);
>
> Could you rename the second arg as "q_r" or "q_out" ?
>
>> +int libxl_xsquota_global_set(libxl_ctx *ctx, libxl_xs_quota_set *q);
>> +int libxl_xsquota_domain_get(libxl_ctx *ctx, uint32_t domid,
>> + libxl_xs_quota_set *q);
>
> Same here.
>
>> +int libxl_xsquota_domain_set(libxl_ctx *ctx, uint32_t domid,
>> + libxl_xs_quota_set *q);
>
> Could we prefix them all with "libxl_xs_quota_" ? I would rather that we
> only use "xs_quota" or "xsquota".
>
>> +
>> #include <libxl_event.h>
>>
>> /*
>> diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile
>> index bc60c46558..ca22a40c6c 100644
>> --- a/tools/libs/light/Makefile
>> +++ b/tools/libs/light/Makefile
>> @@ -106,6 +106,7 @@ OBJS-y += libxl_pvcalls.o
>> OBJS-y += libxl_vsnd.o
>> OBJS-y += libxl_vkb.o
>> OBJS-y += libxl_virtio.o
>> +OBJS-y += libxl_xsquota.o
>> OBJS-y += libxl_genid.o
>> OBJS-y += _libxl_types.o
>> OBJS-y += libxl_flask.o
>> diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
>> index d64a573ff3..c5ddc40f35 100644
>> --- a/tools/libs/light/libxl_types.idl
>> +++ b/tools/libs/light/libxl_types.idl
>> @@ -574,6 +574,15 @@ libxl_altp2m_mode = Enumeration("altp2m_mode", [
>> (3, "limited"),
>> ], init_val = "LIBXL_ALTP2M_MODE_DISABLED")
>>
>> +libxl_xs_quota_item = Struct("xs_quota_item", [
>> + ("name", string),
>> + ("val", uint32),
>> + ])
>> +
>> +libxl_xs_quota_set = Struct("xs_quota_set", [
>
> Could you use "_list" as a suffix instead? It's a bit confusing to have
> the word "set" as a double meaning, with a _set() function that takes a
> set.
>
>> + ("quota", Array(libxl_xs_quota_item, "num_quota"))
>> + ])
>> +
>> libxl_domain_build_info = Struct("domain_build_info",[
>> ("max_vcpus", integer),
>> ("avail_vcpus", libxl_bitmap),
>> diff --git a/tools/libs/light/libxl_xsquota.c b/tools/libs/light/libxl_xsquota.c
>> new file mode 100644
>> index 0000000000..b9afa1c914
>> --- /dev/null
>> +++ b/tools/libs/light/libxl_xsquota.c
>> @@ -0,0 +1,102 @@
>> +/* SPDX-License-Identifier: LGPL-2.1-only */
>> +
>> +/* Xenstore quota handling functions. */
>> +
>> +#include "libxl_internal.h"
>> +
>> +static int get_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_set *q,
>> + bool (func)(struct xs_handle *h, unsigned int domid,
>> + char *quota, unsigned int *value))
>> +{
>> + char **names;
>> + unsigned int num, i;
>> + int rc = 0;
>
> We don't init `rc` variable in libxl function. Set `rc` to 0 just before
> the "out" label.
>
>> + GC_INIT(ctx);
>> +
>> + names = xs_get_quota_names(ctx->xsh, &num);
>> + if (!names) {
>> + /* Xenstore quota support is optional! */
>> + if (errno != ENOSYS)
>> + rc = ERROR_FAIL;
>> + q->num_quota = 0;
>
> It feels wrong to make changes to the output argument on error, if we
> can avoid it. And here, I don't see any reason to change `q`.
>
>> + goto out;
>> + }
>> +
>
> Can you call libxl_xs_quota_set_init() first? As you call _dispose()
> later.
>
>> + q->num_quota = num;
>> + q->quota = libxl__calloc(NOGC, num, sizeof(*q->quota));
>> + for (i = 0; i < num; i++) {
>> + q->quota[i].name = libxl__strdup(NOGC, names[i]);
>> + if (!func(ctx->xsh, domid, q->quota[i].name, &q->quota[i].val)) {
>
> Could you store the return value of `func()` in `ok`, and test `ok` in the
> if instead?
>
>> + libxl_xs_quota_set_dispose(q);
>> + rc = ERROR_FAIL;
>> + break;
>
> This can be `goto out` once free(names) is moved to the out label.
>
>> + }
>> + }
>> +
>> + free(names);
>
> Could you do that after the "out" label? And init `names` to NULL.
>
>> +
>> + out:
>> + GC_FREE;
>> + return rc;
>> +}
>> +
>> +static int set_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_set *q,
>> + bool (func)(struct xs_handle *h, unsigned int domid,
>> + char *quota, unsigned int value))
>> +{
>> + unsigned int i;
>> + int rc = 0;
>> + GC_INIT(ctx);
>> +
>> + for (i = 0; i < q->num_quota; i++) {
>> + if (!func(ctx->xsh, domid, q->quota[i].name, q->quota[i].val)) {
>> + rc = ERROR_FAIL;
>> + break;
>
> It would be better to write `goto out` instead.
>
>> + }
>> + }
>> +
>> + GC_FREE;
>> + return rc;
>> +}
To all your remarks: yes, will do.
Thanks,
Juergen
On Thu, Mar 5, 2026 at 8:52 AM Juergen Gross <jgross@suse.com> wrote:
>
> Add some functions allowing to retrieve and set Xenstore quota (either
> global or domain specific).
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
> tools/golang/xenlight/helpers.gen.go | 78 ++++++++++++++++++++
> tools/golang/xenlight/types.gen.go | 9 +++
> tools/include/libxl.h | 20 ++++++
> tools/libs/light/Makefile | 1 +
> tools/libs/light/libxl_types.idl | 9 +++
> tools/libs/light/libxl_xsquota.c | 102 +++++++++++++++++++++++++++
> 6 files changed, 219 insertions(+)
> create mode 100644 tools/libs/light/libxl_xsquota.c
>
> diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
> index 8909fe8a1b..6c9af904c5 100644
> --- a/tools/golang/xenlight/helpers.gen.go
> +++ b/tools/golang/xenlight/helpers.gen.go
> @@ -998,6 +998,84 @@ xc.policy = C.libxl_rdm_reserve_policy(x.Policy)
> return nil
> }
>
> +// NewXsQuotaItem returns an instance of XsQuotaItem initialized with defaults.
> +func NewXsQuotaItem() (*XsQuotaItem, error) {
> +var (
> +x XsQuotaItem
> +xc C.libxl_xs_quota_item)
> +
> +C.libxl_xs_quota_item_init(&xc)
> +defer C.libxl_xs_quota_item_dispose(&xc)
> +
> +if err := x.fromC(&xc); err != nil {
> +return nil, err }
> +
> +return &x, nil}
> +
> +func (x *XsQuotaItem) fromC(xc *C.libxl_xs_quota_item) error {
> + x.Name = C.GoString(xc.name)
> +x.Val = uint32(xc.val)
> +
> + return nil}
> +
> +func (x *XsQuotaItem) toC(xc *C.libxl_xs_quota_item) (err error){defer func(){
> +if err != nil{
> +C.libxl_xs_quota_item_dispose(xc)}
> +}()
> +
> +if x.Name != "" {
> +xc.name = C.CString(x.Name)}
> +xc.val = C.uint32_t(x.Val)
> +
> + return nil
> + }
> +
> +// NewXsQuotaSet returns an instance of XsQuotaSet initialized with defaults.
> +func NewXsQuotaSet() (*XsQuotaSet, error) {
> +var (
> +x XsQuotaSet
> +xc C.libxl_xs_quota_set)
> +
> +C.libxl_xs_quota_set_init(&xc)
> +defer C.libxl_xs_quota_set_dispose(&xc)
> +
> +if err := x.fromC(&xc); err != nil {
> +return nil, err }
> +
> +return &x, nil}
> +
> +func (x *XsQuotaSet) fromC(xc *C.libxl_xs_quota_set) error {
> + x.Quota = nil
> +if n := int(xc.num_quota); n > 0 {
> +cQuota := (*[1<<28]C.libxl_xs_quota_item)(unsafe.Pointer(xc.quota))[:n:n]
> +x.Quota = make([]XsQuotaItem, n)
> +for i, v := range cQuota {
> +if err := x.Quota[i].fromC(&v); err != nil {
> +return fmt.Errorf("converting field Quota: %v", err) }
> +}
> +}
> +
> + return nil}
> +
> +func (x *XsQuotaSet) toC(xc *C.libxl_xs_quota_set) (err error){defer func(){
> +if err != nil{
> +C.libxl_xs_quota_set_dispose(xc)}
> +}()
> +
> +if numQuota := len(x.Quota); numQuota > 0 {
> +xc.quota = (*C.libxl_xs_quota_item)(C.malloc(C.ulong(numQuota)*C.sizeof_libxl_xs_quota_item))
> +xc.num_quota = C.int(numQuota)
> +cQuota := (*[1<<28]C.libxl_xs_quota_item)(unsafe.Pointer(xc.quota))[:numQuota:numQuota]
> +for i,v := range x.Quota {
> +if err := v.toC(&cQuota[i]); err != nil {
> +return fmt.Errorf("converting field Quota: %v", err)
> +}
> +}
> +}
> +
> + return nil
> + }
> +
> // NewDomainBuildInfo returns an instance of DomainBuildInfo initialized with defaults.
> func NewDomainBuildInfo(dtype DomainType) (*DomainBuildInfo, error) {
> var (
> diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
> index ab9d4ca7b4..5393277190 100644
> --- a/tools/golang/xenlight/types.gen.go
> +++ b/tools/golang/xenlight/types.gen.go
> @@ -543,6 +543,15 @@ Altp2MModeExternal Altp2MMode = 2
> Altp2MModeLimited Altp2MMode = 3
> )
>
> +type XsQuotaItem struct {
> +Name string
> +Val uint32
> +}
> +
> +type XsQuotaSet struct {
> +Quota []XsQuotaItem
> +}
> +
> type DomainBuildInfo struct {
> MaxVcpus int
> AvailVcpus Bitmap
For the golang stuff:
Acked-by: Nick Rosbrook <enr0n@ubuntu.com
© 2016 - 2026 Red Hat, Inc.