From: Michal Privoznik <mprivozn(a)redhat.com>
change from previous version: modified to be the same code style as other
libvirt public API functions.
---
src/libvirt.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 180 insertions(+), 2 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index ff16c48..f850665 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -8143,7 +8143,18 @@ error:
* @xml: the XML description for the interface, preferably in UTF-8
* @flags: and OR'ed set of extraction flags, not used yet
*
- * Define an interface (or modify existing interface configuration)
+
+ * Define an interface (or modify existing interface configuration).
+ *
+ * Normally this change in the interface configuration is immediately
+ * permanent/persistent, but if virInterfaceChangeBegin() has been
+ * previously called (i.e. if an interface config transaction is
+ * open), the new interface definition will only become permanent if
+ * virInterfaceChangeCommit() is called prior to the next reboot of
+ * the system running libvirtd. Prior to that time, it can be
+ * explicitly removed using virInterfaceChangeRollback(), or will be
+ * automatically removed during the next reboot of the system running
+ * libvirtd.
*
* Returns NULL in case of error, a pointer to the interface otherwise
*/
@@ -8190,6 +8201,16 @@ error:
* Undefine an interface, ie remove it from the config.
* This does not free the associated virInterfacePtr object.
*
+ * Normally this change in the interface configuration is
+ * permanent/persistent, but if virInterfaceChangeBegin() has been
+ * previously called (i.e. if an interface config transaction is
+ * open), the removal of the interface definition will only become
+ * permanent if virInterfaceChangeCommit() is called prior to the next
+ * reboot of the system running libvirtd. Prior to that time, the
+ * definition can be explicitly restored using
+ * virInterfaceChangeRollback(), or will be automatically restored
+ * during the next reboot of the system running libvirtd.
+ *
* Returns 0 in case of success, -1 in case of error
*/
int
@@ -8230,8 +8251,13 @@ error:
* @iface: pointer to a defined interface
* @flags: and OR'ed set of extraction flags, not used yet
*
- * Activate an interface (ie call "ifup")
+ * Activate an interface (i.e. call "ifup").
*
+ * If there was an open network config transaction at the time this
+ * interface was defined (that is, if virInterfaceChangeBegin() had
+ * been called), the interface will be brought back down (and then
+ * undefined) if virInterfaceChangeRollback() is called.
+p *
* Returns 0 in case of success, -1 in case of error
*/
int
@@ -8277,6 +8303,13 @@ error:
* This does not remove the interface from the config, and
* does not free the associated virInterfacePtr object.
*
+
+ * If there is an open network config transaction at the time this
+ * interface is destroyed (that is, if virInterfaceChangeBegin() had
+ * been called), and if the interface is later undefined and then
+ * virInterfaceChangeRollback() is called, the restoral of the
+ * interface definition will also bring the interface back up.
+ *
* Returns 0 in case of success and -1 in case of failure.
*/
int
@@ -8374,6 +8407,151 @@ virInterfaceFree(virInterfacePtr iface)
return 0;
}
+/**
+ * virInterfaceChangeBegin:
+ * @conn: pointer to hypervisor connection
+ * @flags: flags, not used yet
+ *
+ * This functions creates a restore point to which one can return
+ * later by calling virInterfaceChangeRollback(). This function should
+ * be called before any transaction with interface configuration.
+ * Once knowing, new configuration works, it can be commited via
+ * virInterfaceChangeCommit(), which frees the restore point.
+ *
+ * If virInterfaceChangeBegin() is called when a transaction is
+ * already opened, this function will fail, and a
+ * VIR_ERR_INVALID_OPERATION will be logged.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virInterfaceChangeBegin(virConnectPtr conn, unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, flags=%d", conn, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceChangeBegin) {
+ int ret;
+ ret = conn->interfaceDriver->interfaceChangeBegin(conn, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virInterfaceChangeCommit:
+ * @conn: pointer to hypervisor connection
+ * @flags: flags, not used yet
+ *
+ * This commits the changes made to interfaces and frees the restore point
+ * created by virInterfaceChangeBegin().
+ *
+ * If virInterfaceChangeCommit() is called when a transaction is not
+ * opened, this function will fail, and a VIR_ERR_INVALID_OPERATION
+ * will be logged.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virInterfaceChangeCommit(virConnectPtr conn, unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, flags=%d", conn, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceChangeCommit) {
+ int ret;
+ ret = conn->interfaceDriver->interfaceChangeCommit(conn, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virInterfaceChangeRollback:
+ * @conn: pointer to hypervisor connection
+ * @flags: flags, not used yet
+ *
+ * This cancels changes made to interfaces settings by restoring previous
+ * state created by virInterfaceChangeBegin().
+ *
+ * If virInterfaceChangeRollback() is called when a transaction is not
+ * opened, this function will fail, and a VIR_ERR_INVALID_OPERATION
+ * will be logged.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virInterfaceChangeRollback(virConnectPtr conn, unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, flags=%d", conn, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibInterfaceError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
+ conn->interfaceDriver->interfaceChangeRollback) {
+ int ret;
+ ret = conn->interfaceDriver->interfaceChangeRollback(conn, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
/**
* virStoragePoolGetConnect:
--
1.7.3.4