[libvirt] [PATCH] conf: do not count per-device boot elements when parsing <os><boot>
by Ján Tomko
When parsing bootable devices, we maintain a bitmap of used
<boot order=""> elements. Use it in the post-parse function
to figure out whether the user tried to mix per-device and
per-domain boot elements.
This removes the need to count them twice.
---
src/conf/domain_conf.c | 46 ++++++++++++++++++++-----------------------
src/conf/domain_conf.h | 3 ++-
src/lxc/lxc_native.c | 2 +-
src/qemu/qemu_driver.c | 6 +++---
src/qemu/qemu_parse_command.c | 2 +-
src/qemu/qemu_process.c | 2 +-
src/vmx/vmx.c | 2 +-
src/xenconfig/xen_sxpr.c | 2 +-
src/xenconfig/xen_xl.c | 2 +-
src/xenconfig/xen_xm.c | 2 +-
10 files changed, 33 insertions(+), 36 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6f0f038b7..355da1478 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4784,7 +4784,8 @@ virDomainDefPostParseCPU(virDomainDefPtr def)
static int
virDomainDefPostParseInternal(virDomainDefPtr def,
- struct virDomainDefPostParseDeviceIteratorData *data)
+ struct virDomainDefPostParseDeviceIteratorData *data,
+ virHashTablePtr bootHash)
{
/* verify init path for container based domains */
if (def->os.type == VIR_DOMAIN_OSTYPE_EXE && !def->os.init) {
@@ -4793,6 +4794,20 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
return -1;
}
+ if (def->os.type == VIR_DOMAIN_OSTYPE_HVM && bootHash) {
+ if (def->os.nBootDevs > 0 && virHashSize(bootHash) > 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("per-device boot elements cannot be used"
+ " together with os/boot elements"));
+ return -1;
+ }
+
+ if (def->os.nBootDevs == 0 && virHashSize(bootHash) == 0) {
+ def->os.nBootDevs = 1;
+ def->os.bootDevs[0] = VIR_DOMAIN_BOOT_DISK;
+ }
+ }
+
if (virDomainVcpuDefPostParse(def) < 0)
return -1;
@@ -4861,7 +4876,8 @@ virDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt,
- void *parseOpaque)
+ void *parseOpaque,
+ virHashTablePtr bootHash)
{
int ret = -1;
bool localParseOpaque = false;
@@ -4917,7 +4933,7 @@ virDomainDefPostParse(virDomainDefPtr def,
if (virDomainDefPostParseCheckFailure(def, parseFlags, ret) < 0)
goto cleanup;
- if ((ret = virDomainDefPostParseInternal(def, &data)) < 0)
+ if ((ret = virDomainDefPostParseInternal(def, &data, bootHash)) < 0)
goto cleanup;
if (xmlopt->config.assignAddressesCallback) {
@@ -16135,28 +16151,11 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
int n;
char *tmp = NULL;
int ret = -1;
- unsigned long deviceBoot;
-
- if (virXPathULong("count(./devices/disk[boot]"
- "|./devices/interface[boot]"
- "|./devices/hostdev[boot]"
- "|./devices/redirdev[boot])", ctxt, &deviceBoot) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot count boot devices"));
- goto cleanup;
- }
/* analysis of the boot devices */
if ((n = virXPathNodeSet("./os/boot", ctxt, &nodes)) < 0)
goto cleanup;
- if (n > 0 && deviceBoot) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("per-device boot elements cannot be used"
- " together with os/boot elements"));
- goto cleanup;
- }
-
for (i = 0; i < n && i < VIR_DOMAIN_BOOT_LAST; i++) {
int val;
char *dev = virXMLPropString(nodes[i], "dev");
@@ -16175,10 +16174,6 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
VIR_FREE(dev);
def->os.bootDevs[def->os.nBootDevs++] = val;
}
- if (def->os.nBootDevs == 0 && !deviceBoot) {
- def->os.nBootDevs = 1;
- def->os.bootDevs[0] = VIR_DOMAIN_BOOT_DISK;
- }
if ((node = virXPathNode("./os/bootmenu[1]", ctxt))) {
tmp = virXMLPropString(node, "enable");
@@ -18947,7 +18942,8 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error;
/* callback to fill driver specific domain aspects */
- if (virDomainDefPostParse(def, caps, flags, xmlopt, parseOpaque) < 0)
+ if (virDomainDefPostParse(def, caps, flags, xmlopt, parseOpaque,
+ bootHash) < 0)
goto error;
/* valdiate configuration */
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1f1dc1de0..2fe7e545d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2643,7 +2643,8 @@ int virDomainDefPostParse(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt,
- void *parseOpaque);
+ void *parseOpaque,
+ virHashTablePtr bootHash);
int virDomainDefValidate(virDomainDefPtr def,
virCapsPtr caps,
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c
index 5fc6e7cda..1542eda11 100644
--- a/src/lxc/lxc_native.c
+++ b/src/lxc/lxc_native.c
@@ -1095,7 +1095,7 @@ lxcParseConfigString(const char *config,
lxcSetCapDrop(vmdef, properties);
if (virDomainDefPostParse(vmdef, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
- xmlopt, NULL) < 0)
+ xmlopt, NULL, NULL) < 0)
goto cleanup;
goto cleanup;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e9f07c6e7..f2cc1ee34 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7916,7 +7916,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
return -1;
}
- if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
+ if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL, NULL) < 0)
return -1;
return 0;
@@ -8082,7 +8082,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
return -1;
}
- if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
+ if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL, NULL) < 0)
return -1;
return 0;
@@ -8169,7 +8169,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
return -1;
}
- if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL) < 0)
+ if (virDomainDefPostParse(vmdef, caps, parse_flags, xmlopt, NULL, NULL) < 0)
return -1;
return 0;
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index ee7112775..345d31e6a 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -2639,7 +2639,7 @@ qemuParseCommandLine(virCapsPtr caps,
VIR_FREE(nics);
- if (virDomainDefPostParse(def, caps, 0, xmlopt, NULL) < 0)
+ if (virDomainDefPostParse(def, caps, 0, xmlopt, NULL, NULL) < 0)
goto error;
if (cmd->num_args || cmd->num_env) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 589d0ed2c..d0e1ad6f7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4696,7 +4696,7 @@ qemuProcessInit(virQEMUDriverPtr driver,
if (vm->def->postParseFailed) {
VIR_DEBUG("re-running the post parse callback");
- if (virDomainDefPostParse(vm->def, caps, 0, driver->xmlopt, NULL) < 0)
+ if (virDomainDefPostParse(vm->def, caps, 0, driver->xmlopt, NULL, NULL) < 0)
goto cleanup;
}
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 3e2f4c3e1..822ba1230 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1819,7 +1819,7 @@ virVMXParseConfig(virVMXContext *ctx,
}
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
- xmlopt, NULL) < 0)
+ xmlopt, NULL, NULL) < 0)
goto cleanup;
success = true;
diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c
index fefa61ac2..ea19ca0bf 100644
--- a/src/xenconfig/xen_sxpr.c
+++ b/src/xenconfig/xen_sxpr.c
@@ -1458,7 +1458,7 @@ xenParseSxpr(const struct sexpr *root,
}
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
- xmlopt, NULL) < 0)
+ xmlopt, NULL, NULL) < 0)
goto error;
return def;
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index d168d3fa4..11eb1a2e6 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -882,7 +882,7 @@ xenParseXL(virConfPtr conf,
goto cleanup;
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
- xmlopt, NULL) < 0)
+ xmlopt, NULL, NULL) < 0)
goto cleanup;
return def;
diff --git a/src/xenconfig/xen_xm.c b/src/xenconfig/xen_xm.c
index 8ef68bbc0..5f4572b84 100644
--- a/src/xenconfig/xen_xm.c
+++ b/src/xenconfig/xen_xm.c
@@ -461,7 +461,7 @@ xenParseXM(virConfPtr conf,
goto cleanup;
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
- xmlopt, NULL) < 0)
+ xmlopt, NULL, NULL) < 0)
goto cleanup;
return def;
--
2.13.0
7 years, 3 months
[libvirt] [PATCH] conf: useserial: drop useless check for serial devices
by Ján Tomko
Since its introduction in commit 874e65aa, if someone requests:
<os><bios useserial="yes"/><os/>
we report an error if we cannot successfully count the number
of serial devices via an XPath query.
Instead of fixing the check (and moving it to the validation phase,
to prevent existing domains from disappearing), drop it completely.
For QEMU, the number of serials is checked when building the command
line.
---
src/conf/domain_conf.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3bef5bed3..e563007ba 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16127,7 +16127,7 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
int n;
char *tmp = NULL;
int ret = -1;
- unsigned long deviceBoot, serialPorts;
+ unsigned long deviceBoot;
if (virXPathULong("count(./devices/disk[boot]"
"|./devices/interface[boot]"
@@ -16204,18 +16204,10 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
if ((node = virXPathNode("./os/bios[1]", ctxt))) {
tmp = virXMLPropString(node, "useserial");
if (tmp) {
- if (STREQ(tmp, "yes")) {
- if (virXPathULong("count(./devices/serial)",
- ctxt, &serialPorts) < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("need at least one serial port "
- "for useserial"));
- goto cleanup;
- }
+ if (STREQ(tmp, "yes"))
def->os.bios.useserial = VIR_TRISTATE_BOOL_YES;
- } else {
+ else
def->os.bios.useserial = VIR_TRISTATE_BOOL_NO;
- }
VIR_FREE(tmp);
}
--
2.13.0
7 years, 3 months
[libvirt] [PATCH] Doc fix of /etc/libvirt/libvirt-guests
by Lily Zhu
As in previous doc, it may cause confusion about whether parallel_shutdown would
take effect when guests are asked to suspend on host shutdown. Hence, changed the
doc of parallel_shutdown, make it more clear.
Signed-off-by: Lily Zhu <lizhu(a)redhat.com>
---
tools/libvirt-guests.sysconf | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/libvirt-guests.sysconf b/tools/libvirt-guests.sysconf
index 2770056..785c3c0 100644
--- a/tools/libvirt-guests.sysconf
+++ b/tools/libvirt-guests.sysconf
@@ -24,8 +24,10 @@
# value suitable for your guests.
#ON_SHUTDOWN=suspend
-# If set to non-zero, shutdown will suspend guests concurrently. Number of
-# guests on shutdown at any time will not exceed number set in this variable.
+# Number of guests will be shutdown concurrently, taking effect when
+# "ON_SHUTDOWN" is set to "shutdown". If Set to 0, guests will be
+# shutdown one after another. Number of guests on shutdown at any
+# time will not exceed number set in this variable.
#PARALLEL_SHUTDOWN=0
# Number of seconds we're willing to wait for a guest to shut down. If parallel
--
1.8.3.1
7 years, 3 months
[libvirt] [PATCH] docs: Improve PCI topology and hotplug guidelines
by Andrea Bolognani
Address some minor flaws in the original document that
were pointed out during review.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
docs/pci-hotplug.html.in | 46 ++++++++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/docs/pci-hotplug.html.in b/docs/pci-hotplug.html.in
index 809e36f5d..a90d47bc3 100644
--- a/docs/pci-hotplug.html.in
+++ b/docs/pci-hotplug.html.in
@@ -13,10 +13,12 @@
<p>
The reason for this apparent limitation is the fact that each
hotplugged PCI device might require additional PCI controllers to
- be added to the guest, and libvirt has no way of knowing in advance
- how many devices will be hotplugged during the guest's lifetime,
- thus making it impossible to automatically provide the right amount
- of PCI controllers: any arbitrary number would end up being too big
+ be added to the guest. Since most PCI controllers can't be
+ hotplugged, they need to be added before the guest is started;
+ however, libvirt has no way of knowing in advance how many devices
+ will be hotplugged during the guest's lifetime, thus making it
+ impossible to automatically provide the right amount of PCI
+ controllers: any arbitrary number would end up being too big
for some users, and too small for others.
</p>
<p>
@@ -53,6 +55,14 @@
emulated or assigned from the host.
</p>
<p>
+ If you have a very specialized use case, such as the appliances
+ used by <a href="http://libguestfs.org/">libguestfs</a> behind
+ the scenes to access disk images, and this automatically-added
+ <code>pcie-root-port</code> controller ends up being a nuisance,
+ you can prevent libvirt from adding it by manually managing PCI
+ controllers and addresses according to you needs.
+ </p>
+ <p>
Slots on the <code>pcie-root</code> controller do not support
hotplug, so the device will be hotplugged into the
<code>pcie-root-port</code> controller. If you plan to hotplug
@@ -73,6 +83,12 @@
remaining details automatically.
</p>
<p>
+ Note that if you're adding PCI controllers to a guest at the
+ same time you're also adding PCI devices, some of the
+ controllers will be used for the newly-added devices and won't
+ be available for hotplug once the guest has been started.
+ </p>
+ <p>
If you expect to hotplug legacy PCI devices, then you will need
specialized controllers, since all those mentioned above are
intended for PCI Express devices only: add
@@ -84,7 +100,8 @@
<p>
and you'll be able to hotplug up to 31 legacy PCI devices,
- either emulated or assigned from the host.
+ either emulated or assigned from the host, in the slots
+ from 0x01 to 0x1f of the <code>pci-bridge</code> controller.
</p>
<h3><a name="x86_64-i440fx">i440fx (pc) machine type</a></h3>
@@ -98,9 +115,10 @@
<controller type='pci' index='0' model='pci-root'/></pre>
<p>
- where each of the 31 slots on the <code>pci-root</code>
- controller is hotplug capable and can accept a legacy PCI
- device, either emulated or assigned from the guest.
+ where each of the 31 slots (from 0x01 to 0x1f) on the
+ <code>pci-root</code> controller is hotplug capable and
+ can accept a legacy PCI device, either emulated or
+ assigned from the guest.
</p>
<h2><a name="ppc64">ppc64 architecture</a></h2>
@@ -119,12 +137,12 @@
</controller></pre>
<p>
- The 31 slots on a <code>pci-root</code> controller are all
- hotplug capable and, despite the name suggesting otherwise,
- starting with QEMU 2.9 all of them can accept PCI Express
- devices in addition to legacy PCI devices; however,
- libvirt will only place emulated devices on the default
- <code>pci-root</code> controller.
+ The 31 slots, from 0x01 to 0x1f, on a <code>pci-root</code>
+ controller are all hotplug capable and, despite the name
+ suggesting otherwise, starting with QEMU 2.9 all of them
+ can accept PCI Express devices in addition to legacy PCI
+ devices; however, libvirt will only place emulated devices
+ on the default <code>pci-root</code> controller.
</p>
<p>
In order to take advantage of improved error reporting and
--
2.13.5
7 years, 3 months
[libvirt] [PATCH] virsh: Honour --readonly with cmdConnect and no name
by Martin Kletzander
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
tools/virsh.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 94bb7ff6c93a..9883e87df2b5 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -218,7 +218,13 @@ virshReconnect(vshControl *ctl, const char *name, bool readonly, bool force)
{
bool connected = false;
virshControlPtr priv = ctl->privData;
- bool ro = name ? readonly : priv->readonly;
+
+ /* If the flag was not specified, then it depends on whether we are
+ * reconnecting to the default URI (in which case we want to keep the
+ * readonly flag as it was) or to a specified URI in which case it
+ * should stay false */
+ if (!readonly && !name)
+ readonly = priv->readonly;
if (priv->conn) {
int ret;
@@ -233,7 +239,7 @@ virshReconnect(vshControl *ctl, const char *name, bool readonly, bool force)
"disconnect from the hypervisor"));
}
- priv->conn = virshConnect(ctl, name ? name : ctl->connname, ro);
+ priv->conn = virshConnect(ctl, name ? name : ctl->connname, readonly);
if (!priv->conn) {
if (disconnected)
--
2.14.1
7 years, 3 months
[libvirt] [PATCH] nodedev: add switchdev to NIC capabilities
by Edan David
Adding functionality to libvirt that will allow it query the interface
for the availability of switchdev Offloading NIC capabilities
---
configure.ac | 13 ++
docs/formatnode.html.in | 1 +
src/util/virnetdev.c | 204 +++++++++++++++++++++-
src/util/virnetdev.h | 1 +
tests/nodedevschemadata/net_00_13_02_b9_f9_d3.xml | 1 +
tests/nodedevschemadata/net_00_15_58_2f_e9_55.xml | 1 +
6 files changed, 220 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index afacf40..a050b99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -627,6 +627,19 @@ if test "$with_linux" = "yes"; then
AC_CHECK_HEADERS([linux/btrfs.h])
fi
+dnl
+dnl check for kernel headers required by devlink
+dnl
+if test "$with_linux" = "yes"; then
+ AC_CHECK_HEADERS([linux/devlink.h])
+ AC_CHECK_DECLS([DEVLINK_GENL_VERSION, DEVLINK_GENL_NAME, DEVLINK_ATTR_MAX, DEVLINK_CMD_ESWITCH_GET, DEVLINK_ATTR_BUS_NAME, DEVLINK_ATTR_DEV_NAME, DEVLINK_ATTR_ESWITCH_MODE, DEVLINK_ESWITCH_MODE_SWITCHDEV],
+ [AC_DEFINE([HAVE_DECL_DEVLINK],
+ [1],
+ [whether devlink declarations is available])],
+ [],
+ [[#include <linux/devlink.h>]])
+fi
+
dnl Allow perl/python overrides
AC_PATH_PROGS([PYTHON], [python2 python])
if test -z "$PYTHON"; then
diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in
index 32451d5..e7b30ea 100644
--- a/docs/formatnode.html.in
+++ b/docs/formatnode.html.in
@@ -227,6 +227,7 @@
<dt><code>rxhash</code></dt><dd>receive-hashing</dd>
<dt><code>rdma</code></dt><dd>remote-direct-memory-access</dd>
<dt><code>txudptnl</code></dt><dd>tx-udp-tunnel-segmentation</dd>
+ <dt><code>switchdev</code></dt><dd>kernel-forward-plane-offload</dd>
</dl>
</dd>
<dt><code>capability</code></dt>
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 90b7bee..084fb41 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -59,6 +59,10 @@
# include <net/if_dl.h>
#endif
+#if HAVE_DECL_DEVLINK
+# include <linux/devlink.h>
+#endif
+
#ifndef IFNAMSIZ
# define IFNAMSIZ 16
#endif
@@ -95,6 +99,7 @@ VIR_LOG_INIT("util.netdev");
(FEATURE_WORD(blocks, index, field) & FEATURE_FIELD_FLAG(index))
#endif
+
typedef enum {
VIR_MCAST_TYPE_INDEX_TOKEN,
VIR_MCAST_TYPE_NAME_TOKEN,
@@ -2396,7 +2401,8 @@ VIR_ENUM_IMPL(virNetDevFeature,
"ntuple",
"rxhash",
"rdma",
- "txudptnl")
+ "txudptnl",
+ "switchdev")
#ifdef __linux__
int
@@ -2851,6 +2857,199 @@ int virNetDevGetRxFilter(const char *ifname,
return ret;
}
+
+
+#if HAVE_DECL_DEVLINK
+/**
+ * virNetDevPutExtraHeader
+ * reserve and prepare room for an extra header
+ * This function sets to zero the room that is required to put the extra
+ * header after the initial Netlink header. This function also increases
+ * the nlmsg_len field. You have to invoke mnl_nlmsg_put_header() before
+ * you call this function. This function returns a pointer to the extra
+ * header.
+ *
+ * @nlh: pointer to Netlink header
+ * @size: size of the extra header that we want to put
+ *
+ * Returns pointer to the start of the extended header
+ */
+static void *
+virNetDevPutExtraHeader(struct nlmsghdr *nlh, size_t size)
+{
+ char *ptr = (char *)nlh + nlh->nlmsg_len;
+ size_t len = NLMSG_ALIGN(size);
+ nlh->nlmsg_len += len;
+ memset(ptr, 0, len);
+ return ptr;
+}
+
+
+/**
+ * virNetDevGetFamilyId:
+ * This function supplies the devlink family id
+ *
+ * @family_name: the name of the family to query
+ *
+ * Returns family id or 0 on failure.
+ */
+static int
+virNetDevGetFamilyId(const char *family_name)
+{
+ struct nl_msg *nl_msg = NULL;
+ struct nlmsghdr *resp = NULL;
+ struct genlmsghdr* gmsgh = NULL;
+ struct nlattr *tb[CTRL_ATTR_MAX + 1] = {NULL, };
+ unsigned int recvbuflen;
+ uint32_t family_id = 0;
+
+ if (!(nl_msg = nlmsg_alloc_simple(GENL_ID_CTRL,
+ NLM_F_REQUEST | NLM_F_ACK))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ gmsgh = virNetDevPutExtraHeader(nlmsg_hdr(nl_msg), sizeof(struct genlmsghdr));
+ if (!gmsgh)
+ goto cleanup;
+
+ gmsgh->cmd = CTRL_CMD_GETFAMILY;
+ gmsgh->version = DEVLINK_GENL_VERSION;
+
+ if (nla_put_string(nl_msg, CTRL_ATTR_FAMILY_NAME, family_name) < 0)
+ goto buffer_too_small;
+
+ if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0, NETLINK_GENERIC, 0) < 0)
+ goto cleanup;
+
+ if (nlmsg_parse(resp, sizeof(struct nlmsghdr), tb, CTRL_CMD_MAX, NULL) < 0)
+ goto malformed_resp;
+
+ if (tb[CTRL_ATTR_FAMILY_ID] == NULL)
+ goto cleanup;
+
+ family_id = *(int *)RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]);
+
+ cleanup:
+ nlmsg_free(nl_msg);
+ VIR_FREE(resp);
+ return family_id;
+
+ malformed_resp:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ goto cleanup;
+
+ buffer_too_small:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ goto cleanup;
+}
+
+
+/**
+ * virNetDevSwitchdevFeature
+ * This function checks for the availability of Switchdev feature
+ * and add it to bitmap
+ *
+ * @ifname: name of the interface
+ * @out: add Switchdev feature if exist to bitmap
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int
+virNetDevSwitchdevFeature(const char *ifname,
+ virBitmapPtr *out)
+{
+ struct nl_msg *nl_msg = NULL;
+ struct nlmsghdr *resp = NULL;
+ unsigned int recvbuflen;
+ struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {NULL, };
+ virPCIDevicePtr pci_device_ptr = NULL;
+ struct genlmsghdr* gmsgh = NULL;
+ const char *pci_name;
+ char *pfname = NULL;
+ int func_ret_val = -1;
+ int ret = -1;
+
+ int family_id = virNetDevGetFamilyId(DEVLINK_GENL_NAME);
+ if (family_id == 0)
+ goto cleanup;
+
+ func_ret_val = virNetDevIsVirtualFunction(ifname);
+ if (func_ret_val == 1) {
+ if (virNetDevGetPhysicalFunction(ifname, &pfname) < 0)
+ goto cleanup;
+ }
+ else if (func_ret_val < 0)
+ goto cleanup;
+
+ if (!(nl_msg = nlmsg_alloc_simple(family_id,
+ NLM_F_REQUEST | NLM_F_ACK))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ pci_device_ptr = pfname ? virNetDevGetPCIDevice(pfname) :
+ virNetDevGetPCIDevice(ifname);
+ if (!pci_device_ptr)
+ goto cleanup;
+
+ pci_name = virPCIDeviceGetName(pci_device_ptr);
+
+ gmsgh = virNetDevPutExtraHeader(nlmsg_hdr(nl_msg), sizeof(struct genlmsghdr));
+ if (!gmsgh)
+ goto cleanup;
+
+ gmsgh->cmd = DEVLINK_CMD_ESWITCH_GET;
+ gmsgh->version = DEVLINK_GENL_VERSION;
+
+ if (nla_put(nl_msg, DEVLINK_ATTR_BUS_NAME, strlen("pci")+1, "pci") < 0)
+ goto buffer_too_small;
+
+ if (nla_put(nl_msg, DEVLINK_ATTR_DEV_NAME, strlen(pci_name)+1, pci_name) < 0)
+ goto buffer_too_small;
+
+ if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
+ NETLINK_GENERIC, 0) < 0)
+ goto cleanup;
+
+ if (nlmsg_parse(resp, sizeof(struct genlmsghdr), tb, DEVLINK_ATTR_MAX, NULL) < 0)
+ goto malformed_resp;
+
+ if (tb[DEVLINK_ATTR_ESWITCH_MODE] &&
+ *(int *)RTA_DATA(tb[DEVLINK_ATTR_ESWITCH_MODE]) == DEVLINK_ESWITCH_MODE_SWITCHDEV) {
+ ignore_value(virBitmapSetBit(*out, VIR_NET_DEV_FEAT_SWITCHDEV));
+ }
+
+ ret = 0;
+
+ cleanup:
+ nlmsg_free(nl_msg);
+ virPCIDeviceFree(pci_device_ptr);
+ VIR_FREE(resp);
+ return ret;
+
+ malformed_resp:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ goto cleanup;
+
+ buffer_too_small:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ goto cleanup;
+}
+# else
+static int
+virNetDevSwitchdevFeature(const char *ifname,
+ virBitmapPtr *out)
+{
+ return 0;
+}
+# endif
+
+
#if defined(SIOCETHTOOL) && defined(HAVE_STRUCT_IFREQ)
/**
@@ -3230,6 +3429,9 @@ virNetDevGetFeatures(const char *ifname,
if (virNetDevRDMAFeature(ifname, out) < 0)
goto cleanup;
+ if (virNetDevSwitchdevFeature(ifname, out) < 0)
+ goto cleanup;
+
ret = 0;
cleanup:
VIR_FORCE_CLOSE(fd);
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index 2e9a9c4..8fd6036 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -112,6 +112,7 @@ typedef enum {
VIR_NET_DEV_FEAT_RXHASH,
VIR_NET_DEV_FEAT_RDMA,
VIR_NET_DEV_FEAT_TXUDPTNL,
+ VIR_NET_DEV_FEAT_SWITCHDEV,
VIR_NET_DEV_FEAT_LAST
} virNetDevFeature;
diff --git a/tests/nodedevschemadata/net_00_13_02_b9_f9_d3.xml b/tests/nodedevschemadata/net_00_13_02_b9_f9_d3.xml
index d4c96e8..88252e6 100644
--- a/tests/nodedevschemadata/net_00_13_02_b9_f9_d3.xml
+++ b/tests/nodedevschemadata/net_00_13_02_b9_f9_d3.xml
@@ -15,6 +15,7 @@
<feature name='rxhash'/>
<feature name='rdma'/>
<feature name='txudptnl'/>
+ <feature name='switchdev'/>
<capability type='80211'/>
</capability>
</device>
diff --git a/tests/nodedevschemadata/net_00_15_58_2f_e9_55.xml b/tests/nodedevschemadata/net_00_15_58_2f_e9_55.xml
index 71bf90e..f77dfcc 100644
--- a/tests/nodedevschemadata/net_00_15_58_2f_e9_55.xml
+++ b/tests/nodedevschemadata/net_00_15_58_2f_e9_55.xml
@@ -15,6 +15,7 @@
<feature name='rxhash'/>
<feature name='rdma'/>
<feature name='txudptnl'/>
+ <feature name='switchdev'/>
<capability type='80203'/>
</capability>
</device>
--
2.1.4
7 years, 3 months
[libvirt] [PATCH 0/3] tests: Make hash table mocking arch independent
by Peter Krempa
Plus one fix.
Peter Krempa (3):
util: hash: Include stdbool.h in the header file
util: hash: Make virHashCodeGen mockable
tests: deterministichash: Make hash tables arch-independent
src/libvirt_private.syms | 4 ++++
src/util/virhash.h | 1 +
src/util/virhashcode.h | 3 ++-
.../qemumonitorjson-nodename-relative.result | 24 +++++++++++-----------
.../qemumonitorjson-nodename-same-backing.result | 24 +++++++++++-----------
tests/virdeterministichashmock.c | 17 +++++++++++----
tests/virmacmaptestdata/simple2.json | 12 +++++------
7 files changed, 50 insertions(+), 35 deletions(-)
--
2.13.2
7 years, 3 months
[libvirt] [PATCH] qemu: don't check whether offline migration is safe
by Pavel Hrdina
Offline migration transfers only the domain definition.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1449715
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_migration.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 056c051b3e..ca1f67146b 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1946,7 +1946,7 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
if (!qemuMigrationIsAllowed(driver, vm, true, flags))
goto cleanup;
- if (!(flags & VIR_MIGRATE_UNSAFE) &&
+ if (!(flags & (VIR_MIGRATE_UNSAFE | VIR_MIGRATE_OFFLINE)) &&
!qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks, flags))
goto cleanup;
@@ -4809,7 +4809,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver,
if (!qemuMigrationIsAllowed(driver, vm, true, flags))
goto endjob;
- if (!(flags & VIR_MIGRATE_UNSAFE) &&
+ if (!(flags & (VIR_MIGRATE_UNSAFE | VIR_MIGRATE_OFFLINE)) &&
!qemuMigrationIsSafe(vm->def, nmigrate_disks, migrate_disks, flags))
goto endjob;
--
2.13.5
7 years, 3 months
[libvirt] [PATCH v2 0/3] conf: Use the correct limit for the number of PHBs
by Andrea Bolognani
Andrea Bolognani (3):
tests: Improve target index validation coverage
conf: Move target index validation
conf: Use the correct limit for the number of PHBs
src/conf/domain_conf.c | 40 +++++++++++++---------
...ml2argv-pseries-phb-invalid-target-index-1.xml} | 4 ---
...ml2argv-pseries-phb-invalid-target-index-2.xml} | 6 +---
...ml2argv-pseries-phb-invalid-target-index-3.xml} | 11 +++---
tests/qemuxml2argvtest.c | 4 ++-
5 files changed, 32 insertions(+), 33 deletions(-)
copy tests/qemuxml2argvdata/{qemuxml2argv-pseries-phb-wrong-target-index.xml => qemuxml2argv-pseries-phb-invalid-target-index-1.xml} (79%)
copy tests/qemuxml2argvdata/{qemuxml2argv-pseries-phb-wrong-target-index.xml => qemuxml2argv-pseries-phb-invalid-target-index-2.xml} (68%)
rename tests/qemuxml2argvdata/{qemuxml2argv-pseries-phb-wrong-target-index.xml => qemuxml2argv-pseries-phb-invalid-target-index-3.xml} (57%)
--
2.13.5
7 years, 3 months