[PATCH v2 12/17] tools/manage: Expose domain capabilities

Jason Andryuk posted 17 patches 3 months, 2 weeks ago
[PATCH v2 12/17] tools/manage: Expose domain capabilities
Posted by Jason Andryuk 3 months, 2 weeks ago
Add an additional "caps" argument to the libxenmanage functions to
obtain a domains capabilities - control, hardware, and xenstore.

Update the xenstored callers at the same time.

Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
---
 tools/include/xenmanage.h | 14 ++++++++++++--
 tools/libs/manage/core.c  | 21 +++++++++++++++++----
 tools/xenstored/domain.c  |  8 ++++----
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/tools/include/xenmanage.h b/tools/include/xenmanage.h
index 956b7a0a44..6fc0d9fe24 100644
--- a/tools/include/xenmanage.h
+++ b/tools/include/xenmanage.h
@@ -45,6 +45,12 @@ int xenmanage_close(xenmanage_handle *hdl);
 #define XENMANAGE_GETDOMSTATE_STATE_DYING     0x0004  /* Domain dying. */
 #define XENMANAGE_GETDOMSTATE_STATE_DEAD      0x0008  /* Domain dead. */
 
+/* Control Domain capability. */
+#define XENMANAGE_GETDOMSTATE_CAP_CONTROL     0x0001
+/* Hardware Domain capability. */
+#define XENMANAGE_GETDOMSTATE_CAP_HARDWARE    0x0002
+/* Xenstore Domain capability. */
+#define XENMANAGE_GETDOMSTATE_CAP_XENSTORE    0x0004
 /*
  * Return state information of an existing domain.
  *
@@ -59,7 +65,8 @@ int xenmanage_close(xenmanage_handle *hdl);
  * Return value: 0 if information was stored, -1 else (errno is set)
  */
 int xenmanage_get_domain_info(xenmanage_handle *hdl, unsigned int domid,
-                              unsigned int *state, uint64_t *unique_id);
+                              unsigned int *state, unsigned int *caps,
+                              uint64_t *unique_id);
 
 /*
  * Return information of a domain having changed state recently.
@@ -73,12 +80,15 @@ int xenmanage_get_domain_info(xenmanage_handle *hdl, unsigned int domid,
  *   domid:     where to store the domid of the domain (not NULL)
  *   state:     where to store the state (XENMANAGE_GETDOMSTATE_STATE_ flags,
  *              nothing stored if NULL)
+ *   caps:      where to store the capabilities (XENMANAGE_GETDOMSTATE_CAP_
+ *              flags, nothing stored if NULL)
  *   unique_id: where to store the unique id of the domain (nothing stored if
  *              NULL)
  * Return value: 0 if information was stored, -1 else (errno is set)
  */
 int xenmanage_poll_changed_domain(xenmanage_handle *hdl, unsigned int *domid,
-                                  unsigned int *state, uint64_t *unique_id);
+                                  unsigned int *state, unsigned int *caps,
+                                  uint64_t *unique_id);
 #endif /* XENMANAGE_H */
 
 /*
diff --git a/tools/libs/manage/core.c b/tools/libs/manage/core.c
index 8fb421df41..2fabdecaab 100644
--- a/tools/libs/manage/core.c
+++ b/tools/libs/manage/core.c
@@ -92,6 +92,7 @@ static int xenmanage_do_domctl_get_domain_state(xenmanage_handle *hdl,
                                                 unsigned int domid_in,
                                                 unsigned int *domid_out,
                                                 unsigned int *state,
+                                                unsigned int *caps,
                                                 uint64_t *unique_id)
 {
     struct xen_domctl *buf;
@@ -130,6 +131,16 @@ static int xenmanage_do_domctl_get_domain_state(xenmanage_handle *hdl,
             if ( st->state & XEN_DOMCTL_GETDOMSTATE_STATE_DEAD )
                 *state |= XENMANAGE_GETDOMSTATE_STATE_DEAD;
         }
+        if ( caps )
+        {
+            *caps = 0;
+            if ( st->caps & XEN_DOMCTL_GETDOMSTATE_CAP_CONTROL )
+                *caps |= XENMANAGE_GETDOMSTATE_CAP_CONTROL;
+            if ( st->caps & XEN_DOMCTL_GETDOMSTATE_CAP_HARDWARE )
+                *caps |= XENMANAGE_GETDOMSTATE_CAP_HARDWARE;
+            if ( st->caps & XEN_DOMCTL_GETDOMSTATE_CAP_XENSTORE )
+                *caps |= XENMANAGE_GETDOMSTATE_CAP_XENSTORE;
+        }
         if ( unique_id )
             *unique_id = st->unique_id;
     }
@@ -142,7 +153,8 @@ static int xenmanage_do_domctl_get_domain_state(xenmanage_handle *hdl,
 }
 
 int xenmanage_get_domain_info(xenmanage_handle *hdl, unsigned int domid,
-                              unsigned int *state, uint64_t *unique_id)
+                              unsigned int *state, unsigned int *caps,
+                              uint64_t *unique_id)
 {
     if ( !hdl || domid >= DOMID_FIRST_RESERVED )
     {
@@ -150,12 +162,13 @@ int xenmanage_get_domain_info(xenmanage_handle *hdl, unsigned int domid,
         return -1;
     }
 
-    return xenmanage_do_domctl_get_domain_state(hdl, domid, NULL, state,
+    return xenmanage_do_domctl_get_domain_state(hdl, domid, NULL, state, caps,
                                                 unique_id);
 }
 
 int xenmanage_poll_changed_domain(xenmanage_handle *hdl, unsigned int *domid,
-                                  unsigned int *state, uint64_t *unique_id)
+                                  unsigned int *state, unsigned int *caps,
+                                  uint64_t *unique_id)
 {
     if ( !hdl || !domid )
     {
@@ -164,5 +177,5 @@ int xenmanage_poll_changed_domain(xenmanage_handle *hdl, unsigned int *domid,
     }
 
     return xenmanage_do_domctl_get_domain_state(hdl, DOMID_INVALID, domid,
-                                                state, unique_id);
+                                                state, caps, unique_id);
 }
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 94b2a1eaa7..d2b6fffa62 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -667,7 +667,7 @@ static int check_domain(const void *k, void *v, void *arg)
 	unsigned int state;
 	uint64_t unique_id;
 
-	if (xenmanage_get_domain_info(xm_handle, domain->domid, &state,
+	if (xenmanage_get_domain_info(xm_handle, domain->domid, &state, NULL,
 				      &unique_id)) {
 		unique_id = 0;
 		state = 0;
@@ -700,7 +700,7 @@ static void do_check_domains(void)
 	struct domain *domain;
 	bool notify = false;
 
-	while (!xenmanage_poll_changed_domain(xm_handle, &domid, &state,
+	while (!xenmanage_poll_changed_domain(xm_handle, &domid, &state, NULL,
 					      &unique_id)) {
 		domain = find_domain_struct(domid);
 		if (domain)
@@ -829,7 +829,7 @@ static struct domain *find_or_alloc_existing_domain(unsigned int domid)
 	domain = find_domain_struct(domid);
 	if (!domain || !domain->unique_id)
 		dom_valid = !xenmanage_get_domain_info(xm_handle, domid,
-						       NULL, &unique_id);
+						       NULL, NULL, &unique_id);
 
 	if (dom_valid) {
 		if (!domain)
@@ -1383,7 +1383,7 @@ int domain_alloc_permrefs(struct node_perms *perms)
 		domid = perms->p[i].id;
 		d = find_domain_struct(domid);
 		if (!d) {
-			if (xenmanage_get_domain_info(xm_handle, domid,
+			if (xenmanage_get_domain_info(xm_handle, domid, NULL,
 						      NULL, &unique_id))
 				perms->p[i].perms |= XS_PERM_IGNORE;
 			else if (!alloc_domain(NULL, domid, unique_id))
-- 
2.50.0
Re: [PATCH v2 12/17] tools/manage: Expose domain capabilities
Posted by Juergen Gross 3 months, 2 weeks ago
On 16.07.25 23:14, Jason Andryuk wrote:
> Add an additional "caps" argument to the libxenmanage functions to
> obtain a domains capabilities - control, hardware, and xenstore.
> 
> Update the xenstored callers at the same time.

Luckily the interface was only introduced in the current devel cycle,
so no need for playing "stable interface" games. :-)

> 
> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen
Re: [PATCH v2 12/17] tools/manage: Expose domain capabilities
Posted by Jason Andryuk 3 months, 2 weeks ago
On 2025-07-17 02:28, Juergen Gross wrote:
> On 16.07.25 23:14, Jason Andryuk wrote:
>> Add an additional "caps" argument to the libxenmanage functions to
>> obtain a domains capabilities - control, hardware, and xenstore.
>>
>> Update the xenstored callers at the same time.
> 
> Luckily the interface was only introduced in the current devel cycle,
> so no need for playing "stable interface" games. :-)

Yes :)

Having said that, for compatibility, will we need some way to query Xen 
for a mask of valid capability bits?  That way a caller can 
differentiate between "this domain doesn't have a capability" and "this 
hypervisor doesn't support a capability."

>>
>> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
> 
> Reviewed-by: Juergen Gross <jgross@suse.com>

Thanks,
Jason
Re: [PATCH v2 12/17] tools/manage: Expose domain capabilities
Posted by Jürgen Groß 3 months, 2 weeks ago
On 17.07.25 22:23, Jason Andryuk wrote:
> On 2025-07-17 02:28, Juergen Gross wrote:
>> On 16.07.25 23:14, Jason Andryuk wrote:
>>> Add an additional "caps" argument to the libxenmanage functions to
>>> obtain a domains capabilities - control, hardware, and xenstore.
>>>
>>> Update the xenstored callers at the same time.
>>
>> Luckily the interface was only introduced in the current devel cycle,
>> so no need for playing "stable interface" games. :-)
> 
> Yes :)
> 
> Having said that, for compatibility, will we need some way to query Xen for a 
> mask of valid capability bits?  That way a caller can differentiate between 
> "this domain doesn't have a capability" and "this hypervisor doesn't support a 
> capability."

Not for now, but in future this will probably be needed, whenever new states
and/or capabilities are added.


Juergen