[PATCH v2] network: add modify-or-add feature to net-update
by Abhiram Tilak
The current way of updating a network configuration uses `virsh
net-update` to add, delete or modify entries. But with such a mechansim
one should know if an entry with current info already exists. Adding
modify-or-add option automatically performs either modify or add
depending on the current state.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/363
Signed-off-by: Abhiram Tilak <atp.exp(a)gmail.com>
---
Changes in v2:
- Removed the modify-or-add functionality for sections
where modify is not applicable.
- Changed the existing implementation of `UpdateIPDHCPHost`,
to avoid code duplication.
- Changed the implementation of modify-or-delete to reassign
the `command` variable instead of using multiple nested conditions.
docs/manpages/virsh.rst | 5 +-
include/libvirt/libvirt-network.h | 12 +--
src/conf/network_conf.c | 134 +++++++++++++++++++++---------
tools/virsh-network.c | 6 +-
4 files changed, 110 insertions(+), 47 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 115b802c45..0da3827f6b 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5908,7 +5908,10 @@ changes optionally taking effect immediately, without needing to
destroy and re-start the network.
*command* is one of "add-first", "add-last", "add" (a synonym for
-add-last), "delete", or "modify".
+add-last), "delete", "modify", "modify-or-add" (modify + add-last), or
+"modify-or-add-first". The 'modify-or-add*' commands perform modify or
+add operation depending on the given state, and can be useful for
+scripting.
*section* is one of "bridge", "domain", "ip", "ip-dhcp-host",
"ip-dhcp-range", "forward", "forward-interface", "forward-pf",
diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h
index 58591be7ac..bb4468b160 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -176,11 +176,13 @@ int virNetworkUndefine (virNetworkPtr network);
* Since: 0.10.2
*/
typedef enum {
- VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST = 5, /* conditionally modify or add an element at end (Since: 10.4.0) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST = 6, /* conditionally modify or add an element at start (Since: 10.4.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_NETWORK_UPDATE_COMMAND_LAST /* (Since: 0.10.2) */
# endif
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index cc92ed0b03..a7c3dea163 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2720,6 +2720,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
virNetworkIPDef *ipdef = virNetworkIPDefByIndex(def, parentIndex);
virNetworkDHCPHostDef host = { 0 };
bool partialOkay = (command == VIR_NETWORK_UPDATE_COMMAND_DELETE);
+ int foundMatchedEntry = -1, foundExactEntry = -1;
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -2740,22 +2741,47 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
}
- if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
+ /* check if the entry already exsits */
+ for (i = 0; i < ipdef->nhosts; i++) {
- /* search for the entry with this (ip|mac|name),
- * and update the IP+(mac|name) */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
- break;
- }
+ /* try to match any of (ip|mac|name) attributes */
+ if ((host.mac && ipdef->hosts[i].mac &&
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
+ (VIR_SOCKET_ADDR_VALID(&host.ip) &&
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
+ (host.name &&
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
+ foundMatchedEntry = i;
+ }
+
+ /* find exact entry - all specified attributes must match */
+ if ((!host.mac || !ipdef->hosts[i].mac ||
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
+ (!host.name ||
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
+ (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
+ foundExactEntry = i;
+ break;
}
+ }
+
+ /* modify-or-add: convert command to add or modify based on foundEntry */
+ if (foundEntry == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundEntry >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
- if (i == ipdef->nhosts) {
+ /* log error if no such entry exists to be modified */
+ if (foundMatchedEntry == -1) {
g_autofree char *ip = virSocketAddrFormat(&host.ip);
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate an existing dhcp host entry with \"mac='%1$s'\" \"name='%2$s'\" \"ip='%3$s'\" in network '%4$s'"),
@@ -2779,21 +2805,13 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
/* log error if an entry with same name/address/ip already exists */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- g_autofree char *ip = virSocketAddrFormat(&host.ip);
+ if (foundMatchedEntry >= 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
+ def->name, host.mac ? host.mac : _("unknown"),
+ host.name, ip ? ip : _("unknown"));
+ goto cleanup;
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
- def->name, host.mac ? host.mac : _("unknown"),
- host.name, ip ? ip : _("unknown"));
- goto cleanup;
- }
}
/* add to beginning/end of list */
@@ -2804,18 +2822,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
- /* find matching entry - all specified attributes must match */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((!host.mac || !ipdef->hosts[i].mac ||
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
- (!host.name ||
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
- (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- break;
- }
- }
- if (i == ipdef->nhosts) {
+ /* log error if there is no entry with exact match*/
+ if (foundExactEntry == -1) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate a matching dhcp host entry in network '%1$s'"),
def->name);
@@ -2865,6 +2873,14 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDef *def,
return -1;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("dhcp ranges cannot be modified, use add command instead of modify-or-add"));
+ return -1;
+ }
+
if (virNetworkDHCPRangeDefParseXML(def->name, ipdef, ctxt->node, &range) < 0)
return -1;
@@ -2964,6 +2980,13 @@ virNetworkDefUpdateForwardInterface(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("forward interface entries cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
/* parsing this is so simple that it doesn't have its own function */
iface.type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
if (!(iface.device.dev = virXMLPropString(ctxt->node, "dev"))) {
@@ -3085,6 +3108,18 @@ virNetworkDefUpdatePortGroup(virNetworkDef *def,
goto cleanup;
}
+ /* modify-or-add: convert command to add or modify based on foundName */
+ if (foundName == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundName >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
/* if there is already a different default, we can't make this
* one the default.
*/
@@ -3153,6 +3188,13 @@ virNetworkDefUpdateDNSHost(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS HOST records cannot be modified, use add instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -3249,6 +3291,13 @@ virNetworkDefUpdateDNSSrv(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS SRV records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0)
goto cleanup;
@@ -3330,6 +3379,13 @@ virNetworkDefUpdateDNSTxt(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS TXT records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "txt") < 0)
goto cleanup;
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 597e3d4530..d7dc5df5a8 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -1231,7 +1231,8 @@ static const vshCmdOptDef opts_network_update[] = {
.positional = true,
.required = true,
.completer = virshNetworkUpdateCommandCompleter,
- .help = N_("type of update (add-first, add-last (add), delete, or modify)")
+ .help = N_("type of update (add-first, add-last (add), delete, modify,"
+ "modify-or-add, or modify-or-add-first)")
},
{.name = "section",
.type = VSH_OT_STRING,
@@ -1260,7 +1261,8 @@ static const vshCmdOptDef opts_network_update[] = {
VIR_ENUM_IMPL(virshNetworkUpdateCommand,
VIR_NETWORK_UPDATE_COMMAND_LAST,
- "none", "modify", "delete", "add-last", "add-first");
+ "none", "modify", "delete", "add-last", "add-first", "modify-or-add",
+ "modify-or-add-first");
VIR_ENUM_IMPL(virshNetworkSection,
VIR_NETWORK_SECTION_LAST,
--
2.42.1
5 months, 2 weeks
[PATCH v3] network: add modify-or-add feature to net-update
by Abhiram Tilak
The current way of updating a network configuration uses `virsh
net-update` to add, delete or modify entries. But with such a mechansim
one should know if an entry with current info already exists. Adding
modify-or-add option automatically performs either modify or add
depending on the current state.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/363
Signed-off-by: Abhiram Tilak <atp.exp(a)gmail.com>
---
Changes in v3:
- Changed the indexes used to delete or modify instead of `i`.
Changes in v2:
- Removed the modify-or-add functionality for sections
where modify is not applicable.
- Changed the existing implementation of `UpdateIPDHCPHost`,
to avoid code duplication.
- Changed the implementation of modify-or-delete to reassign
the `command` variable instead of using multiple nested conditions.
docs/manpages/virsh.rst | 5 +-
include/libvirt/libvirt-network.h | 12 +--
src/conf/network_conf.c | 142 +++++++++++++++++++++---------
tools/virsh-network.c | 6 +-
4 files changed, 114 insertions(+), 51 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index fa038e4547..918e6db30c 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5906,7 +5906,10 @@ changes optionally taking effect immediately, without needing to
destroy and re-start the network.
*command* is one of "add-first", "add-last", "add" (a synonym for
-add-last), "delete", or "modify".
+add-last), "delete", "modify", "modify-or-add" (modify + add-last), or
+"modify-or-add-first". The 'modify-or-add*' commands perform modify or
+add operation depending on the given state, and can be useful for
+scripting.
*section* is one of "bridge", "domain", "ip", "ip-dhcp-host",
"ip-dhcp-range", "forward", "forward-interface", "forward-pf",
diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h
index 58591be7ac..bb4468b160 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -176,11 +176,13 @@ int virNetworkUndefine (virNetworkPtr network);
* Since: 0.10.2
*/
typedef enum {
- VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
- VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_NONE = 0, /* invalid (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY = 1, /* modify an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_DELETE = 2, /* delete an existing element (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_LAST = 3, /* add an element at end of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST = 4, /* add an element at start of list (Since: 0.10.2) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST = 5, /* conditionally modify or add an element at end (Since: 10.4.0) */
+ VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST = 6, /* conditionally modify or add an element at start (Since: 10.4.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_NETWORK_UPDATE_COMMAND_LAST /* (Since: 0.10.2) */
# endif
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index cc92ed0b03..4f76257d06 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2720,6 +2720,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
virNetworkIPDef *ipdef = virNetworkIPDefByIndex(def, parentIndex);
virNetworkDHCPHostDef host = { 0 };
bool partialOkay = (command == VIR_NETWORK_UPDATE_COMMAND_DELETE);
+ int foundMatchedEntry = -1, foundExactEntry = -1;
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -2740,22 +2741,47 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
}
- if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
+ /* check if the entry already exsits */
+ for (i = 0; i < ipdef->nhosts; i++) {
- /* search for the entry with this (ip|mac|name),
- * and update the IP+(mac|name) */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
- break;
- }
+ /* try to match any of (ip|mac|name) attributes */
+ if ((host.mac && ipdef->hosts[i].mac &&
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
+ (VIR_SOCKET_ADDR_VALID(&host.ip) &&
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip)) ||
+ (host.name &&
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name))) {
+ foundMatchedEntry = i;
+ }
+
+ /* find exact entry - all attributes must match if they exist */
+ if ((!host.mac || !ipdef->hosts[i].mac ||
+ !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
+ (!host.name ||
+ STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
+ (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
+ virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
+ foundExactEntry = i;
+ break;
}
+ }
+
+ /* modify-or-add: convert command to add or modify based on foundEntry */
+ if (foundEntry == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundEntry >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
- if (i == ipdef->nhosts) {
+ /* log error if no such entry exists to be modified */
+ if (foundMatchedEntry == -1) {
g_autofree char *ip = virSocketAddrFormat(&host.ip);
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate an existing dhcp host entry with \"mac='%1$s'\" \"name='%2$s'\" \"ip='%3$s'\" in network '%4$s'"),
@@ -2768,8 +2794,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
* then clear out the extra copy to get rid of the duplicate pointers
* to its data (mac and name strings).
*/
- virNetworkDHCPHostDefClear(&ipdef->hosts[i]);
- ipdef->hosts[i] = host;
+ virNetworkDHCPHostDefClear(&ipdef->hosts[foundMatchedEntry]);
+ ipdef->hosts[foundMatchedEntry] = host;
memset(&host, 0, sizeof(host));
} else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
@@ -2779,21 +2805,13 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
/* log error if an entry with same name/address/ip already exists */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((host.mac && ipdef->hosts[i].mac &&
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) ||
- (host.name &&
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) ||
- (VIR_SOCKET_ADDR_VALID(&host.ip) &&
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- g_autofree char *ip = virSocketAddrFormat(&host.ip);
+ if (foundMatchedEntry >= 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
+ def->name, host.mac ? host.mac : _("unknown"),
+ host.name, ip ? ip : _("unknown"));
+ goto cleanup;
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("there is an existing dhcp host entry in network '%1$s' that matches \"<host mac='%2$s' name='%3$s' ip='%4$s'/>\""),
- def->name, host.mac ? host.mac : _("unknown"),
- host.name, ip ? ip : _("unknown"));
- goto cleanup;
- }
}
/* add to beginning/end of list */
@@ -2804,18 +2822,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
goto cleanup;
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
- /* find matching entry - all specified attributes must match */
- for (i = 0; i < ipdef->nhosts; i++) {
- if ((!host.mac || !ipdef->hosts[i].mac ||
- !virMacAddrCompare(host.mac, ipdef->hosts[i].mac)) &&
- (!host.name ||
- STREQ_NULLABLE(host.name, ipdef->hosts[i].name)) &&
- (!VIR_SOCKET_ADDR_VALID(&host.ip) ||
- virSocketAddrEqual(&host.ip, &ipdef->hosts[i].ip))) {
- break;
- }
- }
- if (i == ipdef->nhosts) {
+ /* log error if there is no entry with exact match*/
+ if (foundExactEntry == -1) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate a matching dhcp host entry in network '%1$s'"),
def->name);
@@ -2823,8 +2831,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDef *def,
}
/* remove it */
- virNetworkDHCPHostDefClear(&ipdef->hosts[i]);
- VIR_DELETE_ELEMENT(ipdef->hosts, i, ipdef->nhosts);
+ virNetworkDHCPHostDefClear(&ipdef->hosts[foundExactEntry]);
+ VIR_DELETE_ELEMENT(ipdef->hosts, foundExactEntry, ipdef->nhosts);
} else {
virNetworkDefUpdateUnknownCommand(command);
@@ -2865,6 +2873,14 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDef *def,
return -1;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("dhcp ranges cannot be modified, use add command instead of modify-or-add"));
+ return -1;
+ }
+
if (virNetworkDHCPRangeDefParseXML(def->name, ipdef, ctxt->node, &range) < 0)
return -1;
@@ -2964,6 +2980,13 @@ virNetworkDefUpdateForwardInterface(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("forward interface entries cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
/* parsing this is so simple that it doesn't have its own function */
iface.type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
if (!(iface.device.dev = virXMLPropString(ctxt->node, "dev"))) {
@@ -3085,6 +3108,18 @@ virNetworkDefUpdatePortGroup(virNetworkDef *def,
goto cleanup;
}
+ /* modify-or-add: convert command to add or modify based on foundName */
+ if (foundName == -1) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST;
+ else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_ADD_LAST;
+ } else if (foundName >= 0) {
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST)
+ command = VIR_NETWORK_UPDATE_COMMAND_MODIFY;
+ }
+
/* if there is already a different default, we can't make this
* one the default.
*/
@@ -3153,6 +3188,13 @@ virNetworkDefUpdateDNSHost(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS HOST records cannot be modified, use add instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "host") < 0)
goto cleanup;
@@ -3249,6 +3291,13 @@ virNetworkDefUpdateDNSSrv(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS SRV records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0)
goto cleanup;
@@ -3330,6 +3379,13 @@ virNetworkDefUpdateDNSTxt(virNetworkDef *def,
goto cleanup;
}
+ if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_FIRST ||
+ command == VIR_NETWORK_UPDATE_COMMAND_MODIFY_ADD_LAST) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("DNS TXT records cannot be modified, use add command instead of modify-or-add"));
+ goto cleanup;
+ }
+
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "txt") < 0)
goto cleanup;
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 6fcc7fd8ee..88eb673482 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -1215,7 +1215,8 @@ static const vshCmdOptDef opts_network_update[] = {
.positional = true,
.required = true,
.completer = virshNetworkUpdateCommandCompleter,
- .help = N_("type of update (add-first, add-last (add), delete, or modify)")
+ .help = N_("type of update (add-first, add-last (add), delete, modify,"
+ "modify-or-add, or modify-or-add-first)")
},
{.name = "section",
.type = VSH_OT_STRING,
@@ -1245,7 +1246,8 @@ static const vshCmdOptDef opts_network_update[] = {
VIR_ENUM_IMPL(virshNetworkUpdateCommand,
VIR_NETWORK_UPDATE_COMMAND_LAST,
- "none", "modify", "delete", "add-last", "add-first");
+ "none", "modify", "delete", "add-last", "add-first", "modify-or-add",
+ "modify-or-add-first");
VIR_ENUM_IMPL(virshNetworkSection,
VIR_NETWORK_SECTION_LAST,
--
2.39.2
5 months, 2 weeks
[PATCH] docs: Fix broken links
by Han Han
For the links of drvinterface, drvnetwork, drvnwfilter, and Nagios-virt,
there are no alternative docs. Just remove them directly.
Signed-off-by: Han Han <hhan(a)redhat.com>
---
docs/apps.rst | 10 ++--------
docs/kbase/live_full_disk_backup.rst | 2 +-
docs/manpages/virt-sanlock-cleanup.rst | 2 +-
docs/manpages/virtinterfaced.rst | 1 -
docs/manpages/virtnetworkd.rst | 1 -
docs/manpages/virtnwfilterd.rst | 1 -
docs/manpages/virtstoraged.rst | 2 +-
docs/manpages/virtvzd.rst | 2 +-
docs/windows.rst | 2 +-
9 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/docs/apps.rst b/docs/apps.rst
index b7d19e15d5..443c888c4d 100644
--- a/docs/apps.rst
+++ b/docs/apps.rst
@@ -35,7 +35,7 @@ virsh
machine to be cloned to form a new virtual machine. It automates
copying of data across to new disk images, and updates the UUID, MAC
address, and name in the configuration.
-`virt-df <https://people.redhat.com/rjones/virt-df/>`__
+`virt-df <https://libguestfs.org/virt-df.1.html>`__
Examine the utilization of each filesystem in a virtual machine from
the comfort of the host machine. This tool peeks into the guest disks
and determines how much space is used. It can cope with common Linux
@@ -235,13 +235,7 @@ Monitoring
The plugins provided by Guido G��nther allow to monitor various things
like network and block I/O with
`Munin <https://munin-monitoring.org/>`__.
-`Nagios-virt <https://people.redhat.com/rjones/nagios-virt/>`__
- Nagios-virt is a configuration tool to add monitoring of your
- virtualised domains to `Nagios <https://www.nagios.org/>`__. You can
- use this tool to either set up a new Nagios installation for your Xen
- or QEMU/KVM guests, or to integrate with your existing Nagios
- installation.
-`PCP <https://pcp.io/man/man1/pmdalibvirt.1.html>`__
+`PCP <https://man7.org/linux/man-pages/man1/pmdalibvirt.1.html>`__
The PCP libvirt PMDA (plugin) is part of the
`PCP <https://pcp.io/>`__ toolkit and provides hypervisor and guest
information and complete set of guest performance metrics. It
diff --git a/docs/kbase/live_full_disk_backup.rst b/docs/kbase/live_full_disk_backup.rst
index 562a9e87b0..f20169e314 100644
--- a/docs/kbase/live_full_disk_backup.rst
+++ b/docs/kbase/live_full_disk_backup.rst
@@ -12,7 +12,7 @@ space requirements. The following outlines an efficient method to do
that using libvirt's APIs. This method involves concepts: the notion of
`backing chains <https://libvirt.org/kbase/backing_chains.html>`_,
`QCOW2 overlays
-<https://qemu.readthedocs.io/en/latest/interop/live-block-operations.html#...>`_,
+<https://www.qemu.org/docs/master/interop/live-block-operations.html#disk-...>`_,
and a special operation called "active block-commit", which allows
live-merging an overlay disk image into its backing file.
diff --git a/docs/manpages/virt-sanlock-cleanup.rst b/docs/manpages/virt-sanlock-cleanup.rst
index 3ad70ce683..bf3ef6742b 100644
--- a/docs/manpages/virt-sanlock-cleanup.rst
+++ b/docs/manpages/virt-sanlock-cleanup.rst
@@ -75,5 +75,5 @@ PURPOSE
SEE ALSO
========
-virsh(1), `online instructions <https://libvirt.org/locking.html>`_,
+virsh(1), `online instructions <https://libvirt.org/kbase/locking.html>`_,
`https://libvirt.org/ <https://libvirt.org/>`_
diff --git a/docs/manpages/virtinterfaced.rst b/docs/manpages/virtinterfaced.rst
index 247a8c4009..ef63f4c278 100644
--- a/docs/manpages/virtinterfaced.rst
+++ b/docs/manpages/virtinterfaced.rst
@@ -211,4 +211,3 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvinterface.html <https://libvirt.org/drvinterface.html>`_
diff --git a/docs/manpages/virtnetworkd.rst b/docs/manpages/virtnetworkd.rst
index 22b3fc0f2d..3bd1dd3221 100644
--- a/docs/manpages/virtnetworkd.rst
+++ b/docs/manpages/virtnetworkd.rst
@@ -211,4 +211,3 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvnetwork.html <https://libvirt.org/drvnetwork.html>`_
diff --git a/docs/manpages/virtnwfilterd.rst b/docs/manpages/virtnwfilterd.rst
index b1fc45e7a2..1ec11c247f 100644
--- a/docs/manpages/virtnwfilterd.rst
+++ b/docs/manpages/virtnwfilterd.rst
@@ -211,4 +211,3 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvnwfilter.html <https://libvirt.org/drvnwfilter.html>`_
diff --git a/docs/manpages/virtstoraged.rst b/docs/manpages/virtstoraged.rst
index 70863282d1..fe966f3123 100644
--- a/docs/manpages/virtstoraged.rst
+++ b/docs/manpages/virtstoraged.rst
@@ -211,4 +211,4 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvstorage.html <https://libvirt.org/drvstorage.html>`_
+`https://libvirt.org/storage.html <https://libvirt.org/drvstorage.html>`_
diff --git a/docs/manpages/virtvzd.rst b/docs/manpages/virtvzd.rst
index aa44885d46..52aac2259c 100644
--- a/docs/manpages/virtvzd.rst
+++ b/docs/manpages/virtvzd.rst
@@ -211,4 +211,4 @@ SEE ALSO
virsh(1), libvirtd(8),
`https://libvirt.org/daemons.html <https://libvirt.org/daemons.html>`_,
-`https://libvirt.org/drvvz.html <https://libvirt.org/drvvz.html>`_
+`https://libvirt.org/drvopenvz.html <https://libvirt.org/drvopenvz.html>`_
diff --git a/docs/windows.rst b/docs/windows.rst
index b9aa5626cf..ee3caef41a 100644
--- a/docs/windows.rst
+++ b/docs/windows.rst
@@ -13,7 +13,7 @@ Installation packages
Users who need pre-built Windows DLLs of libvirt are advised to use the `Virt
Viewer <https://virt-manager.org>`__ pre-compiled `Windows MSI
-packages <https://virt-manager.org/download/>`__
+packages <https://virt-manager.org/download.html>`__
These installers include the libvirt, gtk-vnc and spice-gtk DLLs along with any
of their pre-requisite supporting DLLs, the virsh command line tool and the
--
2.45.1
5 months, 2 weeks
[PATCH] virt-host-validate: Improve translatability of messages printed by 'virHostMsgCheck()'
by Peter Krempa
Move the word 'Checking' into the appropriate formatting strings and
mark all outstanding ones for translation.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/637
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
tools/virt-host-validate-bhyve.c | 2 +-
tools/virt-host-validate-ch.c | 2 +-
tools/virt-host-validate-common.c | 18 +++++++++---------
tools/virt-host-validate-qemu.c | 4 ++--
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tools/virt-host-validate-bhyve.c b/tools/virt-host-validate-bhyve.c
index db1cdd8e2c..adb5ae1717 100644
--- a/tools/virt-host-validate-bhyve.c
+++ b/tools/virt-host-validate-bhyve.c
@@ -28,7 +28,7 @@
#include "virt-host-validate-common.h"
#define MODULE_STATUS(mod, err_msg, err_code) \
- virHostMsgCheck("BHYVE", _("for %1$s module"), #mod); \
+ virHostMsgCheck("BHYVE", _("Checking for %1$s module"), #mod); \
if (mod ## _loaded) { \
virHostMsgPass(); \
} else { \
diff --git a/tools/virt-host-validate-ch.c b/tools/virt-host-validate-ch.c
index 9d235ed7ab..3f96423836 100644
--- a/tools/virt-host-validate-ch.c
+++ b/tools/virt-host-validate-ch.c
@@ -57,7 +57,7 @@ int virHostValidateCh(void)
}
if (hasVirtFlag) {
- virHostMsgCheck("CH", "%s", _("for hardware virtualization"));
+ virHostMsgCheck("CH", "%s", _("Checking for hardware virtualization"));
if (hasHwVirt) {
virHostMsgPass();
} else {
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index c8a23e2e99..58d8dbbaa1 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -66,7 +66,7 @@ void virHostMsgCheck(const char *prefix,
msg = g_strdup_vprintf(format, args);
va_end(args);
- fprintf(stdout, _("%1$6s: Checking %2$-60s: "), prefix, msg);
+ fprintf(stdout, "%1$6s: %2$-60s: ", prefix, msg);
}
static bool virHostMsgWantEscape(void)
@@ -137,7 +137,7 @@ int virHostValidateDeviceExists(const char *hvname,
virHostValidateLevel level,
const char *hint)
{
- virHostMsgCheck(hvname, "if device %s exists", dev_name);
+ virHostMsgCheck(hvname, _("Checking if device '%1$s' exists"), dev_name);
if (access(dev_name, F_OK) < 0) {
virHostMsgFail(level, "%s", hint);
@@ -154,7 +154,7 @@ int virHostValidateDeviceAccessible(const char *hvname,
virHostValidateLevel level,
const char *hint)
{
- virHostMsgCheck(hvname, "if device %s is accessible", dev_name);
+ virHostMsgCheck(hvname, _("Checking if device '%1$s' is accessible"), dev_name);
if (access(dev_name, R_OK|W_OK) < 0) {
virHostMsgFail(level, "%s", hint);
@@ -173,7 +173,7 @@ int virHostValidateNamespace(const char *hvname,
{
char nspath[100];
- virHostMsgCheck(hvname, "for namespace %s", ns_name);
+ virHostMsgCheck(hvname, _("Checking for namespace '%1$s'"), ns_name);
g_snprintf(nspath, sizeof(nspath), "/proc/self/ns/%s", ns_name);
@@ -256,7 +256,7 @@ int virHostValidateLinuxKernel(const char *hvname,
uname(&uts);
- virHostMsgCheck(hvname, _("for Linux >= %1$d.%2$d.%3$d"),
+ virHostMsgCheck(hvname, _("Checking for Linux >= %1$d.%2$d.%3$d"),
((version >> 16) & 0xff),
((version >> 8) & 0xff),
(version & 0xff));
@@ -302,7 +302,7 @@ int virHostValidateCGroupControllers(const char *hvname,
if (!(controllers & flag))
continue;
- virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name);
+ virHostMsgCheck(hvname, _("Checking for cgroup '%1$s' controller support"), cg_name);
if (!virCgroupHasController(group, i)) {
ret = VIR_HOST_VALIDATE_FAILURE(level);
@@ -337,7 +337,7 @@ int virHostValidateIOMMU(const char *hvname,
struct dirent *dent;
int rc;
- virHostMsgCheck(hvname, "%s", _("for device assignment IOMMU support"));
+ virHostMsgCheck(hvname, "%s", _("Checking for device assignment IOMMU support"));
flags = virHostValidateGetCPUFlags();
@@ -423,7 +423,7 @@ int virHostValidateIOMMU(const char *hvname,
if (!S_ISDIR(sb.st_mode))
return 0;
- virHostMsgCheck(hvname, "%s", _("if IOMMU is enabled by kernel"));
+ virHostMsgCheck(hvname, "%s", _("Checking if IOMMU is enabled by kernel"));
if (sb.st_nlink <= 2) {
if (bootarg)
virHostMsgFail(level,
@@ -483,7 +483,7 @@ int virHostValidateSecureGuests(const char *hvname,
else if (flags && virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_SEV))
hasAMDSev = true;
- virHostMsgCheck(hvname, "%s", _("for secure guest support"));
+ virHostMsgCheck(hvname, "%s", _("Checking for secure guest support"));
if (ARCH_IS_S390(arch)) {
if (hasFac158) {
if (!virFileIsDir("/sys/firmware/uv")) {
diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c
index 3eeee516d3..b685fa01ba 100644
--- a/tools/virt-host-validate-qemu.c
+++ b/tools/virt-host-validate-qemu.c
@@ -64,7 +64,7 @@ int virHostValidateQEMU(void)
}
if (hasVirtFlag) {
- virHostMsgCheck("QEMU", "%s", _("for hardware virtualization"));
+ virHostMsgCheck("QEMU", "%s", _("Checking for hardware virtualization"));
if (hasHwVirt) {
virHostMsgPass();
} else {
@@ -86,7 +86,7 @@ int virHostValidateQEMU(void)
}
if (arch == VIR_ARCH_PPC64 || arch == VIR_ARCH_PPC64LE) {
- virHostMsgCheck("QEMU", "%s", _("for PowerPC KVM module loaded"));
+ virHostMsgCheck("QEMU", "%s", _("Checking for PowerPC KVM module loaded"));
if (!virHostKernelModuleIsLoaded("kvm_hv"))
virHostMsgFail(VIR_HOST_VALIDATE_WARN,
--
2.45.0
5 months, 2 weeks
[PATCH] Сheck snapshot disk is not NULL when searching it in the VM config
by Fima Shevrin
When creating a snapshot of a VM with multiple hard disks,
the snapshot takes into account the presence of all disks
in the system. If, over time, one of the disks is deleted,
the snapshot will continue to store knowledge of the deleted disk.
This results in the fact that at the moment of deleting the snapshot,
at the validation stage, a disk from the snapshot will be searched which
is not in the VM configuration. As a result, vmdisk variable will
be equal to NULL. Dereferencing a null pointer at the time of calling
virStorageSourceIsSameLocation(vmdisk->src, disk->src) will result in SIGSEGV.
Signed-off-by: Fima Shevrin <efim.shevrin(a)virtuozzo.com>
---
src/qemu/qemu_snapshot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 09ec959f10..bf93cd485e 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3806,7 +3806,7 @@ qemuSnapshotDeleteValidate(virDomainObj *vm,
vmdisk = qemuDomainDiskByName(vm->def, snapDisk->name);
disk = qemuDomainDiskByName(snapdef->parent.dom, snapDisk->name);
- if (!virStorageSourceIsSameLocation(vmdisk->src, disk->src)) {
+ if (vmdisk != NULL && !virStorageSourceIsSameLocation(vmdisk->src, disk->src)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("disk image '%1$s' for internal snapshot '%2$s' is not the same as disk image currently used by VM"),
snapDisk->name, snap->def->name);
--
2.34.1
5 months, 2 weeks
Plans for 10.4.0 release (freeze on Tuesday 28 May)
by Jiri Denemark
We are getting close to 10.4.0 release of libvirt. To aim for the
release on Monday 03 Jun I suggest entering the freeze on Tuesday 28
May and tagging RC2 on Thursday 30 May.
I hope this works for everyone.
Jirka
5 months, 2 weeks
[PATCH] rpc: avoid leak of GSource in use for interrupting main loop
by Daniel P. Berrangé
We never release the reference on the GSource created for
interrupting the main loop, nor do we remove it from the
main context if our thread is woken up prior to the wakeup
callback firing.
This can result in a leak of GSource objects, along with an
ever growing list of GSources attached to the main context,
which will gradually slow down execution of the loop, as
several operations are O(N) for the number of attached GSource
objects.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/rpc/virnetclient.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 147b0d661a..6d424eb599 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1946,7 +1946,7 @@ static int virNetClientIO(virNetClient *client,
/* Check to see if another thread is dispatching */
if (client->haveTheBuck) {
/* Force other thread to wakeup from poll */
- GSource *wakeup = g_idle_source_new();
+ g_autoptr(GSource) wakeup = g_idle_source_new();
g_source_set_callback(wakeup, virNetClientIOWakeup, client->eventLoop, NULL);
g_source_attach(wakeup, client->eventCtx);
@@ -1968,6 +1968,7 @@ static int virNetClientIO(virNetClient *client,
return -1;
}
+ g_source_destroy(wakeup);
VIR_DEBUG("Woken up from sleep head=%p call=%p",
client->waitDispatch, thiscall);
/* Three reasons we can be woken up
--
2.43.0
5 months, 2 weeks
[PATCH] qemu: fix qemu command for pci hostdevs and ramfb='off'
by Jonathon Jongsma
There was no test for this and we mistakenly used 'B' rather than 'T'
when constructing the json value for this parameter. Thus, a value of
'off' was VIR_TRISTATE_SWITCH_OFF=2, which was translated to a boolean
value of 'true'.
Signed-off-by: Jonathon Jongsma <jjongsma(a)redhat.com>
---
src/qemu/qemu_command.c | 2 +-
.../hostdev-pci-display-ramfb.x86_64-latest.args | 1 +
.../hostdev-pci-display-ramfb.x86_64-latest.xml | 6 ++++++
tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml | 5 +++++
4 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 63bfeb790e..2d0eddc79e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4798,7 +4798,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
"p:bootindex", dev->info->effectiveBootIndex,
"S:failover_pair_id", failover_pair_id,
"S:display", qemuOnOffAuto(pcisrc->display),
- "B:ramfb", pcisrc->ramfb,
+ "T:ramfb", pcisrc->ramfb,
NULL) < 0)
return NULL;
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
index 6a3bfbe6fb..e6e538ef1c 100644
--- a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
@@ -29,5 +29,6 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.config \
-audiodev '{"id":"audio1","driver":"none"}' \
-vnc 127.0.0.1:0,audiodev=audio1 \
-device '{"driver":"vfio-pci-nohotplug","host":"0000:06:12.5","id":"hostdev0","display":"on","ramfb":true,"bus":"pci.0","addr":"0x2"}' \
+-device '{"driver":"vfio-pci","host":"0000:06:13.6","id":"hostdev1","display":"off","ramfb":false,"bus":"pci.0","addr":"0x3"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
index 16e8a1dee2..18b9bfb5bf 100644
--- a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
@@ -39,6 +39,12 @@
</source>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</hostdev>
+ <hostdev mode='subsystem' type='pci' managed='no' display='off' ramfb='off'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x13' function='0x6'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </hostdev>
<memballoon model='none'/>
</devices>
</domain>
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml
index 39c84da7e1..d263342b1d 100644
--- a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml
@@ -25,6 +25,11 @@
<address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
</source>
</hostdev>
+ <hostdev mode='subsystem' type='pci' display='off' ramfb='off'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x13' function='0x6'/>
+ </source>
+ </hostdev>
<video>
<model type='none'/>
</video>
--
2.45.0
5 months, 2 weeks
[PATCH 0/2] Add support for hotplugging evdev input devices
by Rayhan Faizel
This patch series extends the current evdev device implementation to allow
hotplugging, including live attachment and detachment.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/529
Rayhan Faizel (2):
qemu: Implement support for hotplugging evdev input devices
qemuhotplugtest: Add testcases for hotplugging evdev input devices
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_command.h | 3 +
src/qemu/qemu_hotplug.c | 95 +++++++++++++------
tests/qemuhotplugtest.c | 5 +
.../qemuhotplug-input-evdev.xml | 3 +
.../qemuhotplug-base-live+input-evdev.xml | 58 +++++++++++
6 files changed, 137 insertions(+), 29 deletions(-)
create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-input-evdev.xml
create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+input-evdev.xml
--
2.34.1
5 months, 2 weeks