]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
api: add virNodeDeviceUpdate()
authorBoris Fiuczynski <fiuczy@linux.ibm.com>
Thu, 22 Feb 2024 13:02:06 +0000 (14:02 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 26 Feb 2024 10:03:51 +0000 (11:03 +0100)
A public API method which allows to update or modify objects is
implemented for almost all other objects that have a concept of
persistent definition and activatability. Currently node devices of type
mdev can be persistent and active. This new method allows to update
defined and active node devices as well.

Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
12 files changed:
include/libvirt/libvirt-nodedev.h
src/access/viraccessperm.c
src/access/viraccessperm.h
src/conf/virnodedeviceobj.c
src/conf/virnodedeviceobj.h
src/driver-nodedev.h
src/libvirt-nodedev.c
src/libvirt_private.syms
src/libvirt_public.syms
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs

index f7ddbfa4ad6a25c1c05b4f1151d726bb07599680..ec26c7a5e1f0fd049a6b450fc7c5401e5f462e2b 100644 (file)
@@ -188,6 +188,24 @@ int virNodeDeviceIsPersistent(virNodeDevicePtr dev);
 
 int virNodeDeviceIsActive(virNodeDevicePtr dev);
 
+/**
+ * virNodeDeviceUpdateFlags:
+ *
+ * Flags to control options for virNodeDeviceUpdate()
+ *
+ * Since: 10.1.0
+ */
+typedef enum {
+    VIR_NODE_DEVICE_UPDATE_AFFECT_CURRENT = 0,      /* affect live if node device is active,
+                                                       config if it's not active (Since: 10.1.0) */
+    VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE    = 1 << 0, /* affect live state of node device only (Since: 10.1.0) */
+    VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG  = 1 << 1, /* affect persistent config only (Since: 10.1.0) */
+} virNodeDeviceUpdateFlags;
+
+int virNodeDeviceUpdate(virNodeDevicePtr dev,
+                        const char *xmlDesc,
+                        unsigned int flags);
+
 /**
  * VIR_NODE_DEVICE_EVENT_CALLBACK:
  *
index d4a0c98b9b294c427b4a019102f365e50b49d6af..702bee761d9030bf226bc39f1ca61d6f5bf56a40 100644 (file)
@@ -71,6 +71,7 @@ VIR_ENUM_IMPL(virAccessPermNodeDevice,
               "getattr", "read", "write",
               "start", "stop",
               "detach", "delete",
+              "save",
 );
 
 VIR_ENUM_IMPL(virAccessPermNWFilter,
index 2f04459ed96f60202e9a8fc97ad6c240b0a9a437..6cc2140c67ef8270ec84f11b59ae79d5d0547e29 100644 (file)
@@ -507,6 +507,12 @@ typedef enum {
      */
     VIR_ACCESS_PERM_NODE_DEVICE_DELETE,
 
+    /**
+     * @desc: Save node device
+     * @message: Saving node device driver requires authorization
+     */
+    VIR_ACCESS_PERM_NODE_DEVICE_SAVE,
+
     VIR_ACCESS_PERM_NODE_DEVICE_LAST
 } virAccessPermNodeDevice;
 
index 31ec4249d83fb20f875fef1e397f5d2f9d64047b..d0a6eab42b6f3caea8d1ca5523edfe2d6ca7b562 100644 (file)
@@ -1137,3 +1137,45 @@ virNodeDeviceObjListFind(virNodeDeviceObjList *devs,
                                       virNodeDeviceObjListFindHelper,
                                       &data);
 }
+
+
+/**
+ * virNodeDeviceObjUpdateModificationImpact:
+ * @obj: Pointer to node device object
+ * @flags: flags to update the modification impact on
+ *
+ * Resolves virNodeDeviceUpdateFlags flags in @flags so that they correctly
+ * apply to the actual state of @obj. @flags may be modified after call to this
+ * function.
+ *
+ * Returns 0 on success if @flags point to a valid combination for @obj or -1
+ * on error.
+ */
+int
+virNodeDeviceObjUpdateModificationImpact(virNodeDeviceObj *obj,
+                                         unsigned int *flags)
+{
+    bool isActive = virNodeDeviceObjIsActive(obj);
+
+    if ((*flags & (VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE | VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG)) ==
+        VIR_NODE_DEVICE_UPDATE_AFFECT_CURRENT) {
+        if (isActive)
+            *flags |= VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE;
+        else
+            *flags |= VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG;
+    }
+
+    if (!isActive && (*flags & VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("node device is not active"));
+        return -1;
+    }
+
+    if (!virNodeDeviceObjIsPersistent(obj) && (*flags & VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("transient node devices do not have any persistent config"));
+        return -1;
+    }
+
+    return 0;
+}
index ba2e424998b41dc4768ba5858af3e88140c3473e..43889b8dc84e661df1fc73ed267c6888be6b30a4 100644 (file)
@@ -159,3 +159,6 @@ virNodeDeviceObj *
 virNodeDeviceObjListFind(virNodeDeviceObjList *devs,
                          virNodeDeviceObjListPredicate callback,
                          void *opaque);
+
+int virNodeDeviceObjUpdateModificationImpact(virNodeDeviceObj *obj,
+                                             unsigned int *flags);
index 167a8166dd673a2dae6a7f44d61b5c0767eb687d..eff989706bcd4dd6d8bb26fe98a01785cd56bb27 100644 (file)
@@ -101,6 +101,11 @@ typedef int
 typedef int
 (*virDrvNodeDeviceIsActive)(virNodeDevicePtr dev);
 
+typedef int
+(*virDrvNodeDeviceUpdate)(virNodeDevicePtr dev,
+                          const char *xmlDesc,
+                          unsigned int flags);
+
 typedef int
 (*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
                                            virNodeDevicePtr dev,
@@ -146,4 +151,5 @@ struct _virNodeDeviceDriver {
     virDrvNodeDeviceGetAutostart nodeDeviceGetAutostart;
     virDrvNodeDeviceIsPersistent nodeDeviceIsPersistent;
     virDrvNodeDeviceIsActive nodeDeviceIsActive;
+    virDrvNodeDeviceUpdate nodeDeviceUpdate;
 };
index c683b2eef945a65fda5302e72c0fb243feee7f29..b97c199a3a7a97bace64efa3f3147adedae29b03 100644 (file)
@@ -1174,3 +1174,48 @@ int virNodeDeviceIsActive(virNodeDevicePtr dev)
     virDispatchError(dev->conn);
     return -1;
 }
+
+
+/**
+ * virNodeDeviceUpdate:
+ * @dev: pointer to the node device object
+ * @xmlDesc: string containing an XML description of the device to be defined
+ * @flags: bitwise OR of virNodeDeviceUpdateFlags
+ *
+ * Update the definition of an existing node device, either its live running
+ * configuration, its persistent configuration, or both.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ *
+ * Since: 10.1.0
+ */
+int
+virNodeDeviceUpdate(virNodeDevicePtr dev,
+                    const char *xmlDesc,
+                    unsigned int flags)
+{
+    VIR_DEBUG("nodeDevice=%p, xmlDesc=%s, flags=0x%x",
+              dev, NULLSTR(xmlDesc), flags);
+
+    virResetLastError();
+
+    virCheckNodeDeviceReturn(dev, -1);
+
+    virCheckReadOnlyGoto(dev->conn->flags, error);
+    virCheckNonNullArgGoto(xmlDesc, error);
+
+    if (dev->conn->nodeDeviceDriver &&
+        dev->conn->nodeDeviceDriver->nodeDeviceUpdate) {
+        int retval = dev->conn->nodeDeviceDriver->nodeDeviceUpdate(dev, xmlDesc, flags);
+        if (retval < 0)
+            goto error;
+
+        return 0;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(dev->conn);
+    return -1;
+}
index 396bd80844776f61bd13423038d3861c3eb8b547..887659784a6734ded0aaf221c110202e1cd60b06 100644 (file)
@@ -1373,6 +1373,7 @@ virNodeDeviceObjListRemoveLocked;
 virNodeDeviceObjSetActive;
 virNodeDeviceObjSetAutostart;
 virNodeDeviceObjSetPersistent;
+virNodeDeviceObjUpdateModificationImpact;
 
 
 # conf/virnwfilterbindingdef.h
index bd1e916d2a4e536c4df89429530c73740a838430..0304b8f8244ec71f4ac81dba5e85f5fb8e27844b 100644 (file)
@@ -938,4 +938,9 @@ LIBVIRT_9.7.0 {
         virNetworkSetMetadata;
 } LIBVIRT_9.0.0;
 
+LIBVIRT_10.1.0 {
+    global:
+        virNodeDeviceUpdate;
+} LIBVIRT_9.7.0;
+
 # .... define new API here using predicted next version number ....
index bedf2cb833f2e7072c454ab8735207749573995a..f156475bd28c9f8295e3996556cc0b374e0ed476 100644 (file)
@@ -7983,6 +7983,7 @@ static virNodeDeviceDriver node_device_driver = {
     .nodeDeviceSetAutostart = remoteNodeDeviceSetAutostart, /* 7.8.0 */
     .nodeDeviceIsPersistent = remoteNodeDeviceIsPersistent, /* 7.8.0 */
     .nodeDeviceIsActive = remoteNodeDeviceIsActive, /* 7.8.0 */
+    .nodeDeviceUpdate = remoteNodeDeviceUpdate, /* 10.1.0 */
 };
 
 static virNWFilterDriver nwfilter_driver = {
index e295b0acc3591b994c8d303d043e2969214aa9c9..ffe865965d69e4f143edf6e7060e7be5125bc983 100644 (file)
@@ -2237,6 +2237,12 @@ struct remote_node_device_is_active_ret {
     int active;
 };
 
+struct remote_node_device_update_args {
+    remote_nonnull_string name;
+    remote_nonnull_string xml_desc;
+    unsigned int flags;
+};
+
 
 /*
  * Events Register/Deregister:
@@ -7021,5 +7027,14 @@ enum remote_procedure {
      * @generate: both
      * @acl: none
      */
-    REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446
+    REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: node_device:write
+     * @acl: node_device:save:!VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG|VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE
+     * @acl: node_device:save:VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG
+     */
+    REMOTE_PROC_NODE_DEVICE_UPDATE = 447
 };
index 924ca418254edd2b2ed03aa50b74671c28d91392..ee2ec3e6fa283a573f4b80834b053a40ae66451a 100644 (file)
@@ -1673,6 +1673,11 @@ struct remote_node_device_is_active_args {
 struct remote_node_device_is_active_ret {
         int                        active;
 };
+struct remote_node_device_update_args {
+        remote_nonnull_string      name;
+        remote_nonnull_string      xml_desc;
+        u_int                      flags;
+};
 struct remote_connect_domain_event_register_ret {
         int                        cb_registered;
 };
@@ -3743,4 +3748,5 @@ enum remote_procedure {
         REMOTE_PROC_NETWORK_SET_METADATA = 444,
         REMOTE_PROC_NETWORK_GET_METADATA = 445,
         REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446,
+        REMOTE_PROC_NODE_DEVICE_UPDATE = 447,
 };