[libvirt] [PATCH v5 0/2] Add support for qcow2 cache
by Liu Qing
Qcow2 small IO random write performance will drop dramatically if the l2
cache table could not cover the whole disk. This will be a lot of l2
cache table RW operations if cache miss happens frequently.
This patch exports the qcow2 driver parameter
l2-cache-size/refcount-cache-size, first added in Qemu 2.2, and
cache-clean-interval, first added in Qemu 2.5, in libvirt.
change since v4: updated doc and did code adjustment based on John
Ferlan's review.
Liu Qing (2):
conf, docs: Add qcow2 cache configuration support
qemu: add capability checking for qcow2 cache configuration
docs/formatdomain.html.in | 41 +++++++++
docs/schemas/domaincommon.rng | 35 ++++++++
src/conf/domain_conf.c | 96 ++++++++++++++++++++--
src/qemu/qemu_capabilities.c | 11 +++
src/qemu/qemu_capabilities.h | 5 ++
src/qemu/qemu_command.c | 33 ++++++++
src/qemu/qemu_driver.c | 5 ++
src/util/virstoragefile.c | 3 +
src/util/virstoragefile.h | 6 ++
tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 3 +
.../caps_2.6.0-gicv2.aarch64.xml | 3 +
.../caps_2.6.0-gicv3.aarch64.xml | 3 +
tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 3 +
tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 3 +
tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 3 +
tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 3 +
tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 3 +
tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 3 +
tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 3 +
tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 3 +
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 3 +
.../qemuxml2argv-disk-drive-qcow2-cache.args | 28 +++++++
.../qemuxml2argv-disk-drive-qcow2-cache.xml | 43 ++++++++++
tests/qemuxml2argvtest.c | 4 +
.../qemuxml2xmlout-disk-drive-qcow2-cache.xml | 43 ++++++++++
tests/qemuxml2xmltest.c | 1 +
26 files changed, 385 insertions(+), 5 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml
--
1.8.3.1
7 years, 2 months
[libvirt] [PATCH 0/2] [V2] Implement LVM volume resize via lvresize
by apolyakov@beget.ru
From: Alexander Polyakov <apolyakov(a)beget.com>
Includes suggestions by John Ferlan & Peter Krempa
Alexander Polyakov (2):
logical: implement volume resize
news: Document lvm volume resize
docs/news.xml | 8 ++++++++
m4/virt-storage-lvm.m4 | 4 ++++
src/storage/storage_backend_logical.c | 37 +++++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+)
--
2.13.5
7 years, 2 months
[libvirt] [PATCH] apparmor: cater for new AAVMF image location
by Guido Günther
Things moved again, sigh.
---
src/security/virt-aa-helper.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 55a686a59c..0b43c8e391 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -516,7 +516,8 @@ valid_path(const char *path, const bool readonly)
"/usr/share/OVMF/", /* for OVMF images */
"/usr/share/ovmf/", /* for OVMF images */
"/usr/share/AAVMF/", /* for AAVMF images */
- "/usr/share/qemu-efi/" /* for AAVMF images */
+ "/usr/share/qemu-efi/", /* for AAVMF images */
+ "/usr/share/qemu-efi-aarch64/" /* for AAVMF images */
};
/* override the above with these */
const char * const override[] = {
--
2.14.1
7 years, 2 months
[libvirt] [PATCH] apparmor: add attach_disconnected
by Guido Günther
Otherwise we fail to reconnect to /dev/net/tun opened by libvirtd
like
[ 8144.507756] audit: type=1400 audit(1505488162.386:38069121): apparmor="DENIED" operation="file_perm" info="Failed name lookup - disconnected path" error=-13 profile="libvirt-5dfcc8a7-b79a-4fa9-a41f-f6271651934c" name="dev/net/tun" pid=9607 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=117 ouid=0
---
I do wonder why we didn't see this earlier though.
examples/apparmor/TEMPLATE.lxc | 2 +-
examples/apparmor/TEMPLATE.qemu | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/examples/apparmor/TEMPLATE.lxc b/examples/apparmor/TEMPLATE.lxc
index 7b64885a1c..f1005dc575 100644
--- a/examples/apparmor/TEMPLATE.lxc
+++ b/examples/apparmor/TEMPLATE.lxc
@@ -4,7 +4,7 @@
#include <tunables/global>
-profile LIBVIRT_TEMPLATE {
+profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
#include <abstractions/libvirt-lxc>
# Globally allows everything to run under this profile
diff --git a/examples/apparmor/TEMPLATE.qemu b/examples/apparmor/TEMPLATE.qemu
index 008a221244..a327315d92 100644
--- a/examples/apparmor/TEMPLATE.qemu
+++ b/examples/apparmor/TEMPLATE.qemu
@@ -4,6 +4,6 @@
#include <tunables/global>
-profile LIBVIRT_TEMPLATE {
+profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
#include <abstractions/libvirt-qemu>
}
--
2.14.1
7 years, 2 months
[libvirt] [PATCHv2] nodedev: add switchdev to NIC capabilities
by Edan David
Adding functionality to libvirt that will allow querying the interface
for the availability of switchdev Offloading NIC capabilities.
The switchdev mode was introduced in kernel 4.8, the iproute2-devlink
command to retrieve the swtichdev NIC feature,
Command example: devlink dev eswitch show pci/0000:03:00.0
This feature is needed for Openstack so we can do a scheduling decision
if the NIC is in Hardware Offload (switchdev) or regular SR-IOV (legacy) mode.
And select the appropriate hypervisors with the requested capability see [1].
[1] - https://specs.openstack.org/openstack/nova-specs/specs/pike/approved/enab...
---
configure.ac | 13 ++
docs/formatnode.html.in | 1 +
src/util/virnetdev.c | 187 +++++++++++++++++++++-
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, 203 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index b12b7fa..c089798 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 4d935b5..29244a8 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 51a6e42..fc7c961 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
@@ -2481,7 +2485,8 @@ VIR_ENUM_IMPL(virNetDevFeature,
"ntuple",
"rxhash",
"rdma",
- "txudptnl")
+ "txudptnl",
+ "switchdev")
#ifdef __linux__
int
@@ -2936,6 +2941,7 @@ int virNetDevGetRxFilter(const char *ifname,
return ret;
}
+
#if defined(SIOCETHTOOL) && defined(HAVE_STRUCT_IFREQ)
/**
@@ -3115,6 +3121,182 @@ virNetDevGetEthtoolFeatures(virBitmapPtr bitmap,
}
+#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.
+ *
+ * @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 uint32_t
+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;
+ }
+
+ if (!(gmsgh = virNetDevPutExtraHeader(nlmsg_hdr(nl_msg), sizeof(struct genlmsghdr))))
+ 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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ goto cleanup;
+ }
+
+ 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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ goto cleanup;
+ }
+
+ if (tb[CTRL_ATTR_FAMILY_ID] == NULL)
+ goto cleanup;
+
+ family_id = *(uint32_t *)RTA_DATA(tb[CTRL_ATTR_FAMILY_ID]);
+
+ cleanup:
+ nlmsg_free(nl_msg);
+ VIR_FREE(resp);
+ return family_id;
+}
+
+
+/**
+ * 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 is_vf = -1;
+ int ret = -1;
+ uint32_t family_id;
+
+ if ((family_id = virNetDevGetFamilyId(DEVLINK_GENL_NAME)) <= 0)
+ return ret;
+
+ if ((is_vf = virNetDevIsVirtualFunction(ifname)) < 0)
+ return ret;
+
+ if (is_vf == 1 && virNetDevGetPhysicalFunction(ifname, &pfname) < 0)
+ goto cleanup;
+
+ if (!(nl_msg = nlmsg_alloc_simple(family_id,
+ NLM_F_REQUEST | NLM_F_ACK))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (!(gmsgh = virNetDevPutExtraHeader(nlmsg_hdr(nl_msg), sizeof(struct genlmsghdr))))
+ goto cleanup;
+
+ gmsgh->cmd = DEVLINK_CMD_ESWITCH_GET;
+ gmsgh->version = DEVLINK_GENL_VERSION;
+
+ pci_device_ptr = pfname ? virNetDevGetPCIDevice(pfname) :
+ virNetDevGetPCIDevice(ifname);
+ if (pci_device_ptr == NULL)
+ goto cleanup;
+
+ pci_name = virPCIDeviceGetName(pci_device_ptr);
+
+ if (nla_put(nl_msg, DEVLINK_ATTR_BUS_NAME, strlen("pci")+1, "pci") < 0 ||
+ nla_put(nl_msg, DEVLINK_ATTR_DEV_NAME, strlen(pci_name)+1, pci_name) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("allocated netlink buffer is too small"));
+ goto cleanup;
+ }
+
+ 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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ goto cleanup;
+ }
+
+ 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);
+ VIR_FREE(pfname);
+ return ret;
+}
+#else
+static int
+virNetDevSwitchdevFeature(const char *ifname ATTRIBUTE_UNUSED,
+ virBitmapPtr *out ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+#endif
+
+
# if HAVE_DECL_ETHTOOL_GFEATURES
/**
* virNetDevGFeatureAvailable
@@ -3315,6 +3497,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 9205c0e..71eaf45 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, 2 months
[libvirt] [PATCH v2 0/3] Be more selective when determining cdrom for taint messaging
by John Ferlan
v1: https://www.redhat.com/archives/libvir-list/2017-September/msg00103.html
Changes since v1:
Split into 3 parts... The first patch would be the bare minimum using
STRPREFIX instead of STREQ type comparisons for the incoming path to
be "/dev/cdrom[N]" or "/dev/srN" (or resolved to that).
This would "work" for the most part, but then since it's possible to
make even more checks let's check against the collected node device
data. Patch 2 therefore will "tag" the already collected cdrom data
with a capability. This allows patch3 to find any/all CDROM's on the
host and compare the resolved path to that list of devices returning
"true" if something matches a node device declared physical CDROM.
I split things up mainly to make it easier to decide whether patch 1
is sufficient or not. If patch2 and patch3 are OK, I would also add
a release note indicating the improvement to find CDROM by node device
capability. It's a separate "improvement" on it's own as well. Whether
it's truly useful or not, is a different question...
John Ferlan (3):
qemu: Be more selective when determining cdrom for taint messaging
nodedev: Add capability bit to detect 'cdrom' devices
qemu: Add inquiry to nodedev for cdrom taint checking
include/libvirt/libvirt-nodedev.h | 1 +
src/conf/node_device_conf.c | 6 ++-
src/conf/node_device_conf.h | 5 ++-
src/conf/virnodedeviceobj.c | 21 ++++++++--
src/node_device/node_device_driver.c | 1 +
src/node_device/node_device_udev.c | 2 +
src/qemu/qemu_domain.c | 78 +++++++++++++++++++++++++++++++++++-
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_driver.c | 4 +-
src/qemu/qemu_process.c | 2 +-
tools/virsh-nodedev.c | 3 ++
tools/virsh.pod | 2 +-
12 files changed, 116 insertions(+), 11 deletions(-)
--
2.9.5
7 years, 2 months
[libvirt] [PATCH v3 0/6] Work around the kernel mdev uevent race in nodedev
by Erik Skultety
v2 here: https://www.redhat.com/archives/libvir-list/2017-July/msg01268.html
Since v2:
- added patch 4/6 that fixes the issue with the handler thread spamming logs
with "udev_monitor_receive_device returned NULL"
-> the event loop callback now disables polling on the udev monitor's fd
every time there's a new event, leaving the responsibility for re-enabling
it back to the handler thread once it had removed the corresponding data
from the socket.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1463285
Erik Skultety (6):
nodedev: Introduce udevCheckMonitorFD helper function
udev: Split udevEventHandleCallback in two functions
udev: Convert udevEventHandleThread to an actual thread routine
nodedev: Disable/re-enable polling on the udev fd
util: Introduce virFileWaitForAccess
nodedev: Work around the uevent race by hooking up
virFileWaitForAccess
src/libvirt_private.syms | 1 +
src/node_device/node_device_udev.c | 208 ++++++++++++++++++++++++++++++++-----
src/util/virfile.c | 29 ++++++
src/util/virfile.h | 2 +
4 files changed, 214 insertions(+), 26 deletions(-)
--
2.13.3
7 years, 2 months
[libvirt] [PATCH go-xml] Add support for domain hostdev and test code
by zhenwei.pi
Signed-off-by: zhenwei.pi <zhenwei.pi(a)youruncloud.com>
---
domain.go | 36 ++++++++++++++++++++++++++++++++++++
domain_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/domain.go b/domain.go
index bead49a..1bcc9cc 100644
--- a/domain.go
+++ b/domain.go
@@ -407,6 +407,29 @@ type DomainRNG struct {
Backend *DomainRNGBackend `xml:"backend"`
}
+type DomainHostdevAdapter struct {
+ Name string `xml:"name,attr,omitempty"`
+}
+
+type DomainHostdevSource struct {
+ Protocol string `xml:"protocol,attr,omitempty"`
+ Name string `xml:"name,attr,omitempty"`
+ Wwpn string `xml:"wwpn,attr,omitempty"`
+ Adapter *DomainHostdevAdapter `xml:"adapter"`
+ Address *DomainAddress `xml:"address"`
+}
+
+type DomainHostdev struct {
+ XMLName xml.Name `xml:"hostdev"`
+ Mode string `xml:"mode,attr"`
+ Type string `xml:"type,attr"`
+ Sgio string `xml:"sgio,attr,omitempty"`
+ Rawio string `xml:"rawio,attr,omitempty"`
+ Managed string `xml:"managed,attr,omitempty"`
+ Source *DomainHostdevSource `xml:"source"`
+ Address *DomainAddress `xml:"address"`
+}
+
type DomainDeviceList struct {
Emulator string `xml:"emulator,omitempty"`
Controllers []DomainController `xml:"controller"`
@@ -422,6 +445,7 @@ type DomainDeviceList struct {
MemBalloon *DomainMemBalloon `xml:"memballoon"`
Sounds []DomainSound `xml:"sound"`
RNGs []DomainRNG `xml:"rng"`
+ Hostdevs []DomainHostdev `xml:"hostdev"`
}
type DomainMemory struct {
@@ -794,6 +818,18 @@ func (d *DomainRNG) Marshal() (string, error) {
return string(doc), nil
}
+func (d *DomainHostdev) Unmarshal(doc string) error {
+ return xml.Unmarshal([]byte(doc), d)
+}
+
+func (d *DomainHostdev) Marshal() (string, error) {
+ doc, err := xml.MarshalIndent(d, "", " ")
+ if err != nil {
+ return "", err
+ }
+ return string(doc), nil
+}
+
type HexUint uint
func (h *HexUint) UnmarshalXMLAttr(attr xml.Attr) error {
diff --git a/domain_test.go b/domain_test.go
index d1b107d..73dd47b 100644
--- a/domain_test.go
+++ b/domain_test.go
@@ -37,6 +37,13 @@ type Address struct {
Function HexUint
}
+type ScsiAddress struct {
+ Controller uint
+ Bus HexUint
+ Target uint
+ Unit uint
+}
+
var uhciIndex uint = 0
var uhciAddr = Address{0, 0, 1, 2}
@@ -46,6 +53,7 @@ var videoAddr = Address{0, 0, 5, 0}
var fsAddr = Address{0, 0, 6, 0}
var balloonAddr = Address{0, 0, 7, 0}
var duplexAddr = Address{0, 0, 8, 0}
+var hostdevScsi = ScsiAddress{0, 0, 3, 0}
var serialPort uint = 0
var tabletBus HexUint = 0
@@ -1457,6 +1465,42 @@ var domainTestData = []struct {
`</rng>`,
},
},
+ {
+ Object: &DomainHostdev{
+ Mode: "subsystem",
+ Type: "scsi",
+ Sgio: "unfiltered",
+ Rawio: "yes",
+ Source: &DomainHostdevSource{
+ Adapter: &DomainHostdevAdapter{
+ Name: "scsi_host0",
+ },
+ Address: &DomainAddress{
+ Type: "scsi",
+ Bus: &hostdevScsi.Bus,
+ Target: &hostdevScsi.Target,
+ Unit: &hostdevScsi.Unit,
+ },
+ },
+ Address: &DomainAddress{
+ Type: "drive",
+ Controller: &hostdevScsi.Controller,
+ Bus: &hostdevScsi.Bus,
+ Target: &hostdevScsi.Target,
+ Unit: &hostdevScsi.Unit,
+ },
+ },
+
+ Expected: []string{
+ `<hostdev mode="subsystem" type="scsi" sgio="unfiltered" rawio="yes">`,
+ ` <source>`,
+ ` <adapter name="scsi_host0"></adapter>`,
+ ` <address type="scsi" bus="0" target="3" unit="0"></address>`,
+ ` </source>`,
+ ` <address type="drive" controller="0" bus="0" target="3" unit="0"></address>`,
+ `</hostdev>`,
+ },
+ },
}
func TestDomain(t *testing.T) {
--
2.7.4
7 years, 2 months
[libvirt] Questions about function virPCIDeviceIsBehindSwitchLackingACS in virpci.c
by Wuzongyong (Euler Dept)
In function virPCIDeviceIsBehindSwitchLackingACS, I noticed that(line 8):
1 if (virPCIDeviceGetParent(dev, &parent) < 0)
2 return -1;
3 if (!parent) {
4 /* if we have no parent, and this is the root bus, ACS doesn't come
5 * into play since devices on the root bus can't P2P without going
6 * through the root IOMMU.
7 */
8 if (dev->address.bus == 0) {
9 return 0;
10 } else {
11 virReportError(VIR_ERR_INTERNAL_ERROR,
12 _("Failed to find parent device for %s"),
13 dev->name);
14 return -1;
15 }
16 }
Why we just return 0 only if device's bus is 0?
In my server, I can see a root bus which bus number is greater than 0, see the
results(just a part) after I run lspci -t:
+-[0000:80]-+-02.0-[81-83]--+-00.0
| | \-00.1
| +-05.0
| +-05.1
| +-05.2
| \-05.4
+-[0000:7f]-+-08.0
| +-08.2
| +-08.3
| + . . .
| \-1f.2
\-[0000:00]-+-00.0
+-01.0-[01]----00.0
+-02.0-[02]--+-00.0
| +-00.1
| +-00.2
| \-00.3
+-02.2-[03]--
+-03.0-[04-0b]----00.0-[05-0b]--+-08.0-[06-08]----00.0
| \-10.0-[09-0b]----00.0
+-05.0
+-05.1
+-05.2
+-05.4
+-11.0
+-11.4
+-16.0
+-16.1
+-1a.0
If I assign the device 0000:81:00.0 to a VM, I get "Failed to find parent device".
I think I should get no error with return value 0 just like bus number is 0, because
bus 80 is the root bus as well in my case.
In the <<Intel C610 Series Chipset and Intel X99 Chipset Platform Controller Hub(PCH)>>
Datasheet, I found that(Chapter 9.1):
For some server platforms, it may be desirable to have multiple PCHs in the system
Which means some PCH's may reside on a bus greater than 0.
So, is this a bug?
Thanks,
Zongyong Wu
7 years, 2 months
[libvirt] [PATCH python] Skip sparseRecvAll / sparseSendAll in sanity test
by Daniel P. Berrange
The sanity test check aims to ensure that every function listed in
the Python code maps to a corresponding C function. The Sparse
send/recv methods are special though - we're never calling the
corresponding C APIs, instead we have a pure python impl.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
sanitytest.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sanitytest.py b/sanitytest.py
index deec200..a5cb01b 100644
--- a/sanitytest.py
+++ b/sanitytest.py
@@ -351,7 +351,8 @@ for klass in gotfunctions:
for func in sorted(gotfunctions[klass]):
# These are pure python methods with no C APi
if func in ["connect", "getConnect", "domain", "getDomain",
- "virEventInvokeFreeCallback"]:
+ "virEventInvokeFreeCallback",
+ "sparseRecvAll", "sparseSendAll"]:
continue
key = "%s.%s" % (klass, func)
--
2.13.5
7 years, 2 months