[libvirt] [PATCH v3] pci: Use virPCIDeviceAddress in virPCIDevice
by Andrea Bolognani
Instead of replicating the information (domain, bus, slot, function)
inside the virPCIDevice structure, use the already-existing
virPCIDeviceAddress structure.
For users of the module, this means that the object returned by
virPCIDeviceGetAddress() can no longer be NULL and must no longer
be freed by the caller.
---
Changes in v3:
* don't check the return value of virPCIDeviceGetAddress(), it can no
longer be NULL
* don't use a variable to store the device address if it's only going
to be used a single time
Changes in v2:
* use virPCIDeviceAddress instead of virPCIDeviceAddressPtr to avoid
extra allocations
src/util/virhostdev.c | 20 ++---------
src/util/virpci.c | 97 +++++++++++++++++++++++----------------------------
2 files changed, 47 insertions(+), 70 deletions(-)
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index de029a0..4065535 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -585,15 +585,12 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
goto cleanup;
}
- VIR_FREE(devAddr);
- if (!(devAddr = virPCIDeviceGetAddress(dev)))
- goto cleanup;
-
/* The device is in use by other active domain if
* the dev is in list activePCIHostdevs. VFIO devices
* belonging to same iommu group can't be shared
* across guests.
*/
+ devAddr = virPCIDeviceGetAddress(dev);
if (usesVfio) {
if (virPCIDeviceAddressIOMMUGroupIterate(devAddr,
virHostdevIsPCINodeDeviceUsed,
@@ -728,7 +725,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
virObjectUnlock(hostdev_mgr->activePCIHostdevs);
virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
virObjectUnref(pcidevs);
- VIR_FREE(devAddr);
return ret;
}
@@ -1558,7 +1554,6 @@ int
virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
virPCIDevicePtr pci)
{
- virPCIDeviceAddressPtr devAddr = NULL;
struct virHostdevIsPCINodeDeviceUsedData data = { hostdev_mgr, NULL,
false };
int ret = -1;
@@ -1566,10 +1561,7 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
virObjectLock(hostdev_mgr->activePCIHostdevs);
virObjectLock(hostdev_mgr->inactivePCIHostdevs);
- if (!(devAddr = virPCIDeviceGetAddress(pci)))
- goto out;
-
- if (virHostdevIsPCINodeDeviceUsed(devAddr, &data))
+ if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
goto out;
if (virPCIDeviceDetach(pci, hostdev_mgr->activePCIHostdevs,
@@ -1581,7 +1573,6 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
out:
virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
virObjectUnlock(hostdev_mgr->activePCIHostdevs);
- VIR_FREE(devAddr);
return ret;
}
@@ -1589,7 +1580,6 @@ int
virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
virPCIDevicePtr pci)
{
- virPCIDeviceAddressPtr devAddr = NULL;
struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, NULL,
false};
int ret = -1;
@@ -1597,10 +1587,7 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
virObjectLock(hostdev_mgr->activePCIHostdevs);
virObjectLock(hostdev_mgr->inactivePCIHostdevs);
- if (!(devAddr = virPCIDeviceGetAddress(pci)))
- goto out;
-
- if (virHostdevIsPCINodeDeviceUsed(devAddr, &data))
+ if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
goto out;
virPCIDeviceReattachInit(pci);
@@ -1613,7 +1600,6 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
out:
virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
virObjectUnlock(hostdev_mgr->activePCIHostdevs);
- VIR_FREE(devAddr);
return ret;
}
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 7ca3fef..6f0cb8c 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -56,10 +56,7 @@ VIR_ENUM_IMPL(virPCIELinkSpeed, VIR_PCIE_LINK_SPEED_LAST,
"", "2.5", "5", "8")
struct _virPCIDevice {
- unsigned int domain;
- unsigned int bus;
- unsigned int slot;
- unsigned int function;
+ virPCIDeviceAddress address;
char name[PCI_ADDR_LEN]; /* domain:bus:slot.function */
char id[PCI_ID_LEN]; /* product vendor */
@@ -655,10 +652,10 @@ virPCIDeviceSharesBusWithActive(virPCIDevicePtr dev, virPCIDevicePtr check, void
virPCIDeviceList *inactiveDevs = data;
/* Different domain, different bus, or simply identical device */
- if (dev->domain != check->domain ||
- dev->bus != check->bus ||
- (dev->slot == check->slot &&
- dev->function == check->function))
+ if (dev->address.domain != check->address.domain ||
+ dev->address.bus != check->address.bus ||
+ (dev->address.slot == check->address.slot &&
+ dev->address.function == check->address.function))
return 0;
/* same bus, but inactive, i.e. about to be assigned to guest */
@@ -689,7 +686,7 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
int ret = 0;
int fd;
- if (dev->domain != check->domain)
+ if (dev->address.domain != check->address.domain)
return 0;
if ((fd = virPCIDeviceConfigOpen(check, false)) < 0)
@@ -713,7 +710,7 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
/* if the secondary bus exactly equals the device's bus, then we found
* the direct parent. No further work is necessary
*/
- if (dev->bus == secondary) {
+ if (dev->address.bus == secondary) {
ret = 1;
goto cleanup;
}
@@ -722,10 +719,12 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
* In this case, what we need to do is look for the "best" match; i.e.
* the most restrictive match that still satisfies all of the conditions.
*/
- if (dev->bus > secondary && dev->bus <= subordinate) {
+ if (dev->address.bus > secondary && dev->address.bus <= subordinate) {
if (*best == NULL) {
- *best = virPCIDeviceNew(check->domain, check->bus, check->slot,
- check->function);
+ *best = virPCIDeviceNew(check->address.domain,
+ check->address.bus,
+ check->address.slot,
+ check->address.function);
if (*best == NULL) {
ret = -1;
goto cleanup;
@@ -745,8 +744,10 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
if (secondary > best_secondary) {
virPCIDeviceFree(*best);
- *best = virPCIDeviceNew(check->domain, check->bus, check->slot,
- check->function);
+ *best = virPCIDeviceNew(check->address.domain,
+ check->address.bus,
+ check->address.slot,
+ check->address.function);
if (*best == NULL) {
ret = -1;
goto cleanup;
@@ -970,7 +971,7 @@ virPCIDeviceReset(virPCIDevicePtr dev,
ret = virPCIDeviceTryPowerManagementReset(dev, fd);
/* Bus reset is not an option with the root bus */
- if (ret < 0 && dev->bus != 0)
+ if (ret < 0 && dev->address.bus != 0)
ret = virPCIDeviceTrySecondaryBusReset(dev, fd, inactiveDevs);
if (ret < 0) {
@@ -1483,8 +1484,8 @@ virPCIDeviceWaitForCleanup(virPCIDevicePtr dev, const char *matcher)
virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0 || *tmp != '\n')
continue;
- if (domain != dev->domain || bus != dev->bus || slot != dev->slot ||
- function != dev->function)
+ if (domain != dev->address.domain || bus != dev->address.bus ||
+ slot != dev->address.slot || function != dev->address.function)
continue;
in_matching_device = true;
match_depth = strspn(line, " ");
@@ -1560,17 +1561,16 @@ virPCIDeviceNew(unsigned int domain,
if (VIR_ALLOC(dev) < 0)
return NULL;
- dev->domain = domain;
- dev->bus = bus;
- dev->slot = slot;
- dev->function = function;
+ dev->address.domain = domain;
+ dev->address.bus = bus;
+ dev->address.slot = slot;
+ dev->address.function = function;
if (snprintf(dev->name, sizeof(dev->name), "%.4x:%.2x:%.2x.%.1x",
- dev->domain, dev->bus, dev->slot,
- dev->function) >= sizeof(dev->name)) {
+ domain, bus, slot, function) >= sizeof(dev->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("dev->name buffer overflow: %.4x:%.2x:%.2x.%.1x"),
- dev->domain, dev->bus, dev->slot, dev->function);
+ domain, bus, slot, function);
goto error;
}
if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config",
@@ -1661,25 +1661,14 @@ virPCIDeviceFree(virPCIDevicePtr dev)
* @dev: device to get address from
*
* Take a PCI device on input and return its PCI address. The
- * caller must free the returned value when no longer needed.
+ * returned object is owned by the device and must not be freed.
*
- * Returns NULL on failure, the device address on success.
+ * Returns: a pointer to the address, which can never be NULL.
*/
virPCIDeviceAddressPtr
virPCIDeviceGetAddress(virPCIDevicePtr dev)
{
-
- virPCIDeviceAddressPtr pciAddrPtr;
-
- if (!dev || (VIR_ALLOC(pciAddrPtr) < 0))
- return NULL;
-
- pciAddrPtr->domain = dev->domain;
- pciAddrPtr->bus = dev->bus;
- pciAddrPtr->slot = dev->slot;
- pciAddrPtr->function = dev->function;
-
- return pciAddrPtr;
+ return &(dev->address);
}
const char *
@@ -1890,12 +1879,14 @@ virPCIDeviceListFindIndex(virPCIDeviceListPtr list, virPCIDevicePtr dev)
{
size_t i;
- for (i = 0; i < list->count; i++)
- if (list->devs[i]->domain == dev->domain &&
- list->devs[i]->bus == dev->bus &&
- list->devs[i]->slot == dev->slot &&
- list->devs[i]->function == dev->function)
+ for (i = 0; i < list->count; i++) {
+ virPCIDevicePtr other = list->devs[i];
+ if (other->address.domain == dev->address.domain &&
+ other->address.bus == dev->address.bus &&
+ other->address.slot == dev->address.slot &&
+ other->address.function == dev->address.function)
return i;
+ }
return -1;
}
@@ -1910,10 +1901,11 @@ virPCIDeviceListFindByIDs(virPCIDeviceListPtr list,
size_t i;
for (i = 0; i < list->count; i++) {
- if (list->devs[i]->domain == domain &&
- list->devs[i]->bus == bus &&
- list->devs[i]->slot == slot &&
- list->devs[i]->function == function)
+ virPCIDevicePtr other = list->devs[i];
+ if (other->address.domain == domain &&
+ other->address.bus == bus &&
+ other->address.slot == slot &&
+ other->address.function == function)
return list->devs[i];
}
return NULL;
@@ -1944,7 +1936,8 @@ int virPCIDeviceFileIterate(virPCIDevicePtr dev,
int direrr;
if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
- dev->domain, dev->bus, dev->slot, dev->function) < 0)
+ dev->address.domain, dev->address.bus,
+ dev->address.slot, dev->address.function) < 0)
goto cleanup;
if (!(dir = opendir(pcidir))) {
@@ -2074,13 +2067,11 @@ virPCIDeviceListPtr
virPCIDeviceGetIOMMUGroupList(virPCIDevicePtr dev)
{
virPCIDeviceListPtr groupList = virPCIDeviceListNew();
- virPCIDeviceAddress devAddr = { dev->domain, dev->bus,
- dev->slot, dev->function };
if (!groupList)
goto error;
- if (virPCIDeviceAddressIOMMUGroupIterate(&devAddr,
+ if (virPCIDeviceAddressIOMMUGroupIterate(&(dev->address),
virPCIDeviceGetIOMMUGroupAddOne,
groupList) < 0)
goto error;
@@ -2294,7 +2285,7 @@ virPCIDeviceIsBehindSwitchLackingACS(virPCIDevicePtr dev)
* into play since devices on the root bus can't P2P without going
* through the root IOMMU.
*/
- if (dev->bus == 0) {
+ if (dev->address.bus == 0) {
return 0;
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
--
2.5.0
8 years, 11 months
[libvirt] [PATCH v3 0/8] libxl: domain statistics support
by Joao Martins
Hey,
[ Apologies for resending this series before receiving comments, but I
found two issues (namely on patch 3 and 4) and thus I am reposting it
as v3 having those fixed. ]
This series bring support for various statistics about domains
regarding CPU, Memory, Network Interfaces, Block and Jobs. Not all of
the statistics are implemented: qdisk support is missing in this series
and some of the memory statistics aren't available.
With this series we further implement 7 more functions of libvirt APIs.
It is organized as follows:
* Patch 1, 2: implements cpu/memory statistics.
* Patch 3: implements network statistics
* Patch 4: adds helper method virDiskNameParse as an extension
to virDiskNameToIndex (New)
* Patch 5: VBD block statistics. QDisk will follow up in a separate
series regarding QEMU monitor integration.
* Patch 6: implement fetching all domain statistics
* Patch 7, 8: implements Job information statistics.
Overall it looks big but 70% of the patch is due to #5 and #6 but doesn't
add necessarily more complexity to the driver I believe. Patch #7 and #8
are of special importance because GetJobInfo and GetJobStats are now used
in Openstack Kilo to monitor live-migration progress. These two patches
together with the p2p migration I sent earlier let us sucessfully
live-migrate with Openstack Kilo. Furthermore with this series we get to
support nova diagnostics.
Tested this series on 4.4.3 and 4.5 setups plus Openstack Kilo.
Individual patches contain the changelog and comments addressed since v1.
Thanks!
Joao Martins (8):
libxl: implement virDomainGetCPUStats
libxl: implement virDomainMemorystats
libxl: implement virDomainInterfaceStats
util: add virDiskNameParse to handle disk and partition idx
libxl: implement virDomainBlockStats
libxl: implement virConnectGetAllDomainStats
libxl: implement virDomainGetJobInfo
libxl: implement virDomainGetJobStats
configure.ac | 2 +-
src/libvirt_private.syms | 1 +
src/libxl/libxl_domain.c | 54 +++
src/libxl/libxl_domain.h | 6 +
src/libxl/libxl_driver.c | 960 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/virutil.c | 41 +-
src/util/virutil.h | 1 +
tests/utiltest.c | 56 +++
8 files changed, 1116 insertions(+), 5 deletions(-)
--
2.1.4
8 years, 11 months
[libvirt] [PATCH v2] pci: Use virPCIDeviceAddress in virPCIDevice
by Andrea Bolognani
Instead of replicating the information (domain, bus, slot, function)
inside the virPCIDevice structure, use the already-existing
virPCIDeviceAddress structure.
Outside of the module, the only visible change is that the return value
of virPCIDeviceGetAddress() must no longer be freed by the caller.
---
Changes in v2:
* use virPCIDeviceAddress instead of virPCIDeviceAddressPtr to avoid
extra allocations
src/util/virhostdev.c | 4 ---
src/util/virpci.c | 95 +++++++++++++++++++++++----------------------------
2 files changed, 43 insertions(+), 56 deletions(-)
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index de029a0..173ac58 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -585,7 +585,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
goto cleanup;
}
- VIR_FREE(devAddr);
if (!(devAddr = virPCIDeviceGetAddress(dev)))
goto cleanup;
@@ -728,7 +727,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
virObjectUnlock(hostdev_mgr->activePCIHostdevs);
virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
virObjectUnref(pcidevs);
- VIR_FREE(devAddr);
return ret;
}
@@ -1581,7 +1579,6 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
out:
virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
virObjectUnlock(hostdev_mgr->activePCIHostdevs);
- VIR_FREE(devAddr);
return ret;
}
@@ -1613,7 +1610,6 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
out:
virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
virObjectUnlock(hostdev_mgr->activePCIHostdevs);
- VIR_FREE(devAddr);
return ret;
}
diff --git a/src/util/virpci.c b/src/util/virpci.c
index bececb5..bb874ac 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -56,10 +56,7 @@ VIR_ENUM_IMPL(virPCIELinkSpeed, VIR_PCIE_LINK_SPEED_LAST,
"", "2.5", "5", "8")
struct _virPCIDevice {
- unsigned int domain;
- unsigned int bus;
- unsigned int slot;
- unsigned int function;
+ virPCIDeviceAddress address;
char name[PCI_ADDR_LEN]; /* domain:bus:slot.function */
char id[PCI_ID_LEN]; /* product vendor */
@@ -655,10 +652,10 @@ virPCIDeviceSharesBusWithActive(virPCIDevicePtr dev, virPCIDevicePtr check, void
virPCIDeviceList *inactiveDevs = data;
/* Different domain, different bus, or simply identical device */
- if (dev->domain != check->domain ||
- dev->bus != check->bus ||
- (dev->slot == check->slot &&
- dev->function == check->function))
+ if (dev->address.domain != check->address.domain ||
+ dev->address.bus != check->address.bus ||
+ (dev->address.slot == check->address.slot &&
+ dev->address.function == check->address.function))
return 0;
/* same bus, but inactive, i.e. about to be assigned to guest */
@@ -689,7 +686,7 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
int ret = 0;
int fd;
- if (dev->domain != check->domain)
+ if (dev->address.domain != check->address.domain)
return 0;
if ((fd = virPCIDeviceConfigOpen(check, false)) < 0)
@@ -713,7 +710,7 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
/* if the secondary bus exactly equals the device's bus, then we found
* the direct parent. No further work is necessary
*/
- if (dev->bus == secondary) {
+ if (dev->address.bus == secondary) {
ret = 1;
goto cleanup;
}
@@ -722,10 +719,12 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
* In this case, what we need to do is look for the "best" match; i.e.
* the most restrictive match that still satisfies all of the conditions.
*/
- if (dev->bus > secondary && dev->bus <= subordinate) {
+ if (dev->address.bus > secondary && dev->address.bus <= subordinate) {
if (*best == NULL) {
- *best = virPCIDeviceNew(check->domain, check->bus, check->slot,
- check->function);
+ *best = virPCIDeviceNew(check->address.domain,
+ check->address.bus,
+ check->address.slot,
+ check->address.function);
if (*best == NULL) {
ret = -1;
goto cleanup;
@@ -745,8 +744,10 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data)
if (secondary > best_secondary) {
virPCIDeviceFree(*best);
- *best = virPCIDeviceNew(check->domain, check->bus, check->slot,
- check->function);
+ *best = virPCIDeviceNew(check->address.domain,
+ check->address.bus,
+ check->address.slot,
+ check->address.function);
if (*best == NULL) {
ret = -1;
goto cleanup;
@@ -970,7 +971,7 @@ virPCIDeviceReset(virPCIDevicePtr dev,
ret = virPCIDeviceTryPowerManagementReset(dev, fd);
/* Bus reset is not an option with the root bus */
- if (ret < 0 && dev->bus != 0)
+ if (ret < 0 && dev->address.bus != 0)
ret = virPCIDeviceTrySecondaryBusReset(dev, fd, inactiveDevs);
if (ret < 0) {
@@ -1483,8 +1484,8 @@ virPCIDeviceWaitForCleanup(virPCIDevicePtr dev, const char *matcher)
virStrToLong_ui(tmp + 1, &tmp, 16, &function) < 0 || *tmp != '\n')
continue;
- if (domain != dev->domain || bus != dev->bus || slot != dev->slot ||
- function != dev->function)
+ if (domain != dev->address.domain || bus != dev->address.bus ||
+ slot != dev->address.slot || function != dev->address.function)
continue;
in_matching_device = true;
match_depth = strspn(line, " ");
@@ -1560,17 +1561,16 @@ virPCIDeviceNew(unsigned int domain,
if (VIR_ALLOC(dev) < 0)
return NULL;
- dev->domain = domain;
- dev->bus = bus;
- dev->slot = slot;
- dev->function = function;
+ dev->address.domain = domain;
+ dev->address.bus = bus;
+ dev->address.slot = slot;
+ dev->address.function = function;
if (snprintf(dev->name, sizeof(dev->name), "%.4x:%.2x:%.2x.%.1x",
- dev->domain, dev->bus, dev->slot,
- dev->function) >= sizeof(dev->name)) {
+ domain, bus, slot, function) >= sizeof(dev->name)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("dev->name buffer overflow: %.4x:%.2x:%.2x.%.1x"),
- dev->domain, dev->bus, dev->slot, dev->function);
+ domain, bus, slot, function);
goto error;
}
if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config",
@@ -1661,25 +1661,14 @@ virPCIDeviceFree(virPCIDevicePtr dev)
* @dev: device to get address from
*
* Take a PCI device on input and return its PCI address. The
- * caller must free the returned value when no longer needed.
+ * returned object is owned by the device and must not be freed.
*
* Returns NULL on failure, the device address on success.
*/
virPCIDeviceAddressPtr
virPCIDeviceGetAddress(virPCIDevicePtr dev)
{
-
- virPCIDeviceAddressPtr pciAddrPtr;
-
- if (!dev || (VIR_ALLOC(pciAddrPtr) < 0))
- return NULL;
-
- pciAddrPtr->domain = dev->domain;
- pciAddrPtr->bus = dev->bus;
- pciAddrPtr->slot = dev->slot;
- pciAddrPtr->function = dev->function;
-
- return pciAddrPtr;
+ return &(dev->address);
}
const char *
@@ -1890,12 +1879,14 @@ virPCIDeviceListFindIndex(virPCIDeviceListPtr list, virPCIDevicePtr dev)
{
size_t i;
- for (i = 0; i < list->count; i++)
- if (list->devs[i]->domain == dev->domain &&
- list->devs[i]->bus == dev->bus &&
- list->devs[i]->slot == dev->slot &&
- list->devs[i]->function == dev->function)
+ for (i = 0; i < list->count; i++) {
+ virPCIDevicePtr other = list->devs[i];
+ if (other->address.domain == dev->address.domain &&
+ other->address.bus == dev->address.bus &&
+ other->address.slot == dev->address.slot &&
+ other->address.function == dev->address.function)
return i;
+ }
return -1;
}
@@ -1910,10 +1901,11 @@ virPCIDeviceListFindByIDs(virPCIDeviceListPtr list,
size_t i;
for (i = 0; i < list->count; i++) {
- if (list->devs[i]->domain == domain &&
- list->devs[i]->bus == bus &&
- list->devs[i]->slot == slot &&
- list->devs[i]->function == function)
+ virPCIDevicePtr other = list->devs[i];
+ if (other->address.domain == domain &&
+ other->address.bus == bus &&
+ other->address.slot == slot &&
+ other->address.function == function)
return list->devs[i];
}
return NULL;
@@ -1944,7 +1936,8 @@ int virPCIDeviceFileIterate(virPCIDevicePtr dev,
int direrr;
if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
- dev->domain, dev->bus, dev->slot, dev->function) < 0)
+ dev->address.domain, dev->address.bus,
+ dev->address.slot, dev->address.function) < 0)
goto cleanup;
if (!(dir = opendir(pcidir))) {
@@ -2074,13 +2067,11 @@ virPCIDeviceListPtr
virPCIDeviceGetIOMMUGroupList(virPCIDevicePtr dev)
{
virPCIDeviceListPtr groupList = virPCIDeviceListNew();
- virPCIDeviceAddress devAddr = { dev->domain, dev->bus,
- dev->slot, dev->function };
if (!groupList)
goto error;
- if (virPCIDeviceAddressIOMMUGroupIterate(&devAddr,
+ if (virPCIDeviceAddressIOMMUGroupIterate(&(dev->address),
virPCIDeviceGetIOMMUGroupAddOne,
groupList) < 0)
goto error;
@@ -2294,7 +2285,7 @@ virPCIDeviceIsBehindSwitchLackingACS(virPCIDevicePtr dev)
* into play since devices on the root bus can't P2P without going
* through the root IOMMU.
*/
- if (dev->bus == 0) {
+ if (dev->address.bus == 0) {
return 0;
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
--
2.5.0
8 years, 11 months
[libvirt] [PATCH 0/2] notify about reverting to snapshot
by Dmitry Andreev
Reverting to snapshot may change domain configuration but
there will be no events about that.
Lack of the event become a problem for virt-manager
https://bugzilla.redhat.com/show_bug.cgi?id=1081148
This patch-set introduces new event and emits it in
qemuDomainRevertToSnapshot.
Dmitry Andreev (2):
Introduce new VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT event
qemu: emit 'defined' event after reverted to snapshot
examples/object-events/event-test.c | 2 ++
include/libvirt/libvirt-domain.h | 1 +
src/qemu/qemu_driver.c | 5 +++++
tools/virsh-domain.c | 3 ++-
4 files changed, 10 insertions(+), 1 deletion(-)
--
1.8.3.1
8 years, 11 months
[libvirt] libvirt qcow2 internal snapshot without vm state
by Vasiliy Tolstov
Hi! I'm try to grep sources, but can't understand, how libvirt create
internal snapshot in the same qcow2 file without memory state?
As i understand libvirt via qmp/hmp runs savevm command via qemu. But
i don't understand how libvirt skips memory state in this case?
--
Vasiliy Tolstov,
e-mail: v.tolstov(a)selfip.ru
8 years, 11 months
Re: [libvirt] [Qemu-devel] [Patch V2 1/2] x86, mce: Basic support to add LMCE support to QEMU
by Eduardo Habkost
On Mon, Dec 14, 2015 at 07:17:27PM -0500, Raj, Ashok wrote:
> On Mon, Dec 14, 2015 at 11:37:16PM +0100, Borislav Petkov wrote:
> > On Mon, Dec 14, 2015 at 02:11:46PM -0500, Raj, Ashok wrote:
> > > This is mostly harmless.. since the MCG_CAP space is shared and has no
> > > conflict between vendors. Also just the CAP being set has no effect.
> >
> > Of course it does - we check SER_P in machine_check_poll() and when
> > I emulate an AMD guest and inject errors into it, error handling is
> > obviously wrong, see:
> >
> > https://lkml.kernel.org/r/20151123150355.GE5134@pd.tnic
> >
>
> I can see how this hurts.. since the poller isn't doing cpu model specific
> stuff..?
>
> in the LMCE case, even if you advertise MCG_LMCE_P in MCG_CAP, the guest kernel
> wont call intel_init_lmce() only from mce_intel.c.. so the same problem
> won't happen.
>
> but the issue Eduardo mentioned seems like the following.
>
> New QEMU_LMCE + New KVM_LMCE + New_GUEST_LMCE - No problem
>
> but if you were to migrage the Guest_LMCE to a non-LMCE supported KVM host
> we could run into an issue..
>
> is this the compatibility issue that you were looking to fix Eduardo?
If I understood you correctly, yes. Also, note that currently
kvm_arch_init_vcpu() simply warns about missing capabilities,
instead of preventing the VM from running/migrating (as it
should). We need to change that, and figure out a good way to
report "feature FOO can't be enabled in this host" errors to
management software[1]. The main problem is that we don't even
have a QMP console available anymore if machine initialization is
aborted.
CCing libvir-list so they get in the loop.
[1] This is similar to what we need for CPUID checks, but the new
MCE feature means we need something more generic (that just
reports QOM property names, probably?)
--
Eduardo
8 years, 11 months
[libvirt] [PATCHv2 0/3] security: misc cleanups
by Ján Tomko
v1: https://www.redhat.com/archives/libvir-list/2015-November/msg00781.html
new in v2:
* split by security driver
* more functions renamed
Ján Tomko (3):
security_dac: remove extra Security from function names
security_selinux: remove extra Security from function names
security_stack: : remove extra security from function names
src/security/security_dac.c | 242 +++++++++++++-------------
src/security/security_selinux.c | 375 ++++++++++++++++++++--------------------
src/security/security_stack.c | 68 ++++----
3 files changed, 338 insertions(+), 347 deletions(-)
--
2.4.6
8 years, 11 months
[libvirt] volume download/upload but for snapshots
by Vasiliy Tolstov
Hi! I'm happy with libvirt volume download/upload ability, but also i
need to download snapshot, what is the best way to do that?
Define volume from snapshot? Or write libvirt function for this?
--
Vasiliy Tolstov,
e-mail: v.tolstov(a)selfip.ru
8 years, 11 months
[libvirt] [PATCH v2 0/2] Add support for zero-write detection
by Martin Kletzander
QEMU supports detect-zeroes option since version 2.1, but we never
added support for it in libvirt. If was requested by Vasiliy Tolstov
in the list, so I just added it.
There are two discussions to be had, optionally. One is to decide
whether we should disable detect_zeros='unmap' if discard is not set
to 'unmap', but this is getting very hypervisor-specific, so I just
documented the behaviour. The other one is the naming. I described
why I made the decision for "zeros" instead of "zeroes" the decision
in the patch, but I have no problem changing it to what others like
better.
v2:
- format detect_zeroes on the command line instead of detect_zeros
v1:
- https://www.redhat.com/archives/libvir-list/2015-December/msg00484.html
Martin Kletzander (2):
conf: Add support of zero-detection for disks
qemu: Add support for zero-detection writes
docs/formatdomain.html.in | 10 ++++++
docs/schemas/domaincommon.rng | 12 +++++++
src/conf/domain_conf.c | 23 +++++++++++++-
src/conf/domain_conf.h | 11 +++++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 11 +++++++
tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.4.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.5.0-1.caps | 1 +
.../qemuxml2argv-disk-drive-detect-zeros.args | 27 ++++++++++++++++
.../qemuxml2argv-disk-drive-detect-zeros.xml | 37 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 4 +++
tests/qemuxml2xmltest.c | 1 +
15 files changed, 143 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeros.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeros.xml
--
2.6.4
8 years, 11 months
[libvirt] Exclusive VM lock
by Dmitry Andreev
Hi,
I'm looking for a mechanism to do a sequence of API calls as atomic
operation. Is there any way for libvirt's API client to acquire an
exclusive VM lock to prevent other client from changing VM state
through libvirt?
8 years, 11 months