[PATCH v5 00/18] *** qemu: block: Support block disk along with throttle filters ***
by Harikumar R
*** BLURB HERE ***
Chun Feng Wu (17):
schema: Add new domain elements to support multiple throttle groups
schema: Add new domain elements to support multiple throttle filters
config: Introduce ThrottleGroup and corresponding XML parsing
config: Introduce ThrottleFilter and corresponding XML parsing
qemu: monitor: Add support for ThrottleGroup operations
tests: Test qemuMonitorJSONGetThrottleGroup and
qemuMonitorJSONUpdateThrottleGroup
remote: New APIs for ThrottleGroup lifecycle management
qemu: Refactor qemuDomainSetBlockIoTune to extract common methods
qemu: Implement qemu driver for throttle API
qemu: helper: throttle filter nodename and preparation processing
qemu: block: Support block disk along with throttle filters
config: validate: Verify iotune, throttle group and filter
qemuxmlconftest: Add 'throttlefilter' tests
test_driver: Test throttle group lifecycle APIs
virsh: Refactor iotune options for re-use
virsh: Add support for throttle group operations
virsh: Add option "throttle-groups" to "attach_disk"
Harikumar Rajkumar (1):
tests: Test qemuxmlactivetestThrottleGroup
docs/formatdomain.rst | 47 ++
docs/manpages/virsh.rst | 135 +++-
include/libvirt/libvirt-domain.h | 21 +
src/conf/domain_conf.c | 398 ++++++++++
src/conf/domain_conf.h | 45 ++
src/conf/domain_validate.c | 119 ++-
src/conf/schemas/domaincommon.rng | 293 ++++----
src/conf/virconftypes.h | 4 +
src/driver-hypervisor.h | 22 +
src/libvirt-domain.c | 174 +++++
src/libvirt_private.syms | 8 +
src/libvirt_public.syms | 7 +
src/qemu/qemu_block.c | 136 ++++
src/qemu/qemu_block.h | 49 ++
src/qemu/qemu_command.c | 180 +++++
src/qemu/qemu_command.h | 6 +
src/qemu/qemu_domain.c | 73 +-
src/qemu/qemu_driver.c | 619 +++++++++++++---
src/qemu/qemu_hotplug.c | 33 +
src/qemu/qemu_monitor.c | 34 +
src/qemu/qemu_monitor.h | 14 +
src/qemu/qemu_monitor_json.c | 134 ++++
src/qemu/qemu_monitor_json.h | 14 +
src/remote/remote_daemon_dispatch.c | 44 ++
src/remote/remote_driver.c | 40 ++
src/remote/remote_protocol.x | 48 +-
src/remote_protocol-structs | 28 +
src/test/test_driver.c | 452 ++++++++----
tests/qemumonitorjsontest.c | 86 +++
.../throttlefilter-in.xml | 392 ++++++++++
.../throttlefilter-out.xml | 393 ++++++++++
tests/qemuxmlactivetest.c | 1 +
.../throttlefilter-invalid.x86_64-latest.err | 1 +
.../throttlefilter-invalid.xml | 89 +++
.../throttlefilter.x86_64-latest.args | 55 ++
.../throttlefilter.x86_64-latest.xml | 105 +++
tests/qemuxmlconfdata/throttlefilter.xml | 95 +++
tests/qemuxmlconftest.c | 2 +
tools/virsh-completer-domain.c | 82 +++
tools/virsh-completer-domain.h | 16 +
tools/virsh-domain.c | 680 ++++++++++++++----
41 files changed, 4649 insertions(+), 525 deletions(-)
create mode 100644 tests/qemustatusxml2xmldata/throttlefilter-in.xml
create mode 100644 tests/qemustatusxml2xmldata/throttlefilter-out.xml
create mode 100644 tests/qemuxmlconfdata/throttlefilter-invalid.x86_64-latest.err
create mode 100644 tests/qemuxmlconfdata/throttlefilter-invalid.xml
create mode 100644 tests/qemuxmlconfdata/throttlefilter.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/throttlefilter.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/throttlefilter.xml
--
2.39.5 (Apple Git-154)
2 months, 2 weeks
[PATCH 1/3] [bhyve] list pci devices on host
by Alexander Shursha
Linux gets the list via sysfs. FreeBSD can get the list through
ioctl
Sponsored by: Future Crew, LLC
Signed-off-by: Alexander Shursha <kekek2(a)ya.ru>
---
src/bhyve/bhyve_capabilities.c | 2 +-
src/conf/node_device_conf.c | 2 +-
src/node_device/node_device_driver.c | 2 +-
src/util/virmdev.c | 2 +-
src/util/virpci.c | 400 ++++++++++++++++++++++++++-
5 files changed, 399 insertions(+), 9 deletions(-)
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index b065256cf0..fcef91c435 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -108,7 +108,7 @@ virBhyveDomainCapsFill(virDomainCaps *caps,
VIR_DOMAIN_CAPS_ENUM_SET(caps->video.modelType, VIR_DOMAIN_VIDEO_TYPE_GOP);
}
- caps->hostdev.supported = VIR_TRISTATE_BOOL_NO;
+ caps->hostdev.supported = VIR_TRISTATE_BOOL_YES;
caps->features[VIR_DOMAIN_CAPS_FEATURE_IOTHREADS] = VIR_TRISTATE_BOOL_NO;
caps->features[VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO] = VIR_TRISTATE_BOOL_NO;
caps->features[VIR_DOMAIN_CAPS_FEATURE_GENID] = VIR_TRISTATE_BOOL_NO;
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 08a89942ba..39e6b78f3d 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -2836,7 +2836,7 @@ virNodeDeviceSyncMdevActiveConfig(virNodeDeviceDef *def)
}
}
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
int
virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHost *scsi_host)
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index fa5db0d5d5..282af02724 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -111,7 +111,7 @@ int nodeConnectIsAlive(virConnectPtr conn G_GNUC_UNUSED)
return 1;
}
-#if defined (__linux__) && defined(WITH_UDEV)
+#if (defined(__linux__) || defined(__FreeBSD__)) && defined(WITH_UDEV)
/* NB: It was previously believed that changes in driver name were
* relayed to libvirt as "change" events by udev, and the udev event
* notification is setup to recognize such events and effectively
diff --git a/src/util/virmdev.c b/src/util/virmdev.c
index 6ecdbdf0ab..3a07ba75f2 100644
--- a/src/util/virmdev.c
+++ b/src/util/virmdev.c
@@ -565,7 +565,7 @@ virMediatedDeviceParentGetAddress(const char *sysfspath,
return -1;
}
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
ssize_t
virMediatedDeviceGetMdevTypes(const char *sysfspath,
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 90617e69c6..f954ce4df2 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -30,6 +30,13 @@
#include <sys/stat.h>
#include <unistd.h>
+#ifdef __FreeBSD__
+# ifdef WITH_BHYVE
+# include <libudev.h>
+# endif
+# include <sys/pciio.h>
+#endif
+
#ifdef __linux__
# include <sys/utsname.h>
#endif
@@ -72,7 +79,11 @@ struct _virPCIDevice {
char *name; /* domain:bus:slot.function */
char id[PCI_ID_LEN]; /* product vendor */
+#ifndef __FreeBSD__
char *path;
+#else
+ struct pci_match_conf patterns[1];
+#endif
/* The driver:domain which uses the device */
char *used_by_drvname;
@@ -99,6 +110,9 @@ struct _virPCIDevice {
bool unbind_from_stub;
bool remove_slot;
bool reprobe;
+#ifdef __FreeBSD__
+ u_int8_t pc_hdr; /* PCI header type */
+#endif
};
struct _virPCIDeviceList {
@@ -359,6 +373,7 @@ virPCIDeviceGetCurrentDriverNameAndType(virPCIDevice *dev,
}
+#ifndef __FreeBSD__
static int
virPCIDeviceConfigOpenInternal(virPCIDevice *dev, bool readonly, bool fatal)
{
@@ -429,6 +444,7 @@ virPCIDeviceRead(virPCIDevice *dev,
return 0;
}
+#endif
/**
* virPCIDeviceReadN:
@@ -450,6 +466,7 @@ virPCIDeviceRead(virPCIDevice *dev,
* and the return value is 0, then the config file really does contain
* the value 0 at @pos.
*/
+#ifndef __FreeBSD__
static uint8_t
virPCIDeviceRead8(virPCIDevice *dev, int cfgfd, unsigned int pos)
{
@@ -473,7 +490,56 @@ virPCIDeviceRead32(virPCIDevice *dev, int cfgfd, unsigned int pos)
virPCIDeviceRead(dev, cfgfd, pos, &buf[0], sizeof(buf));
return (buf[0] << 0) | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
}
+#else
+static int
+virPCIDeviceRead(virPCIDevice *dev, int pi_reg, int pi_width, u_int32_t *pi_data)
+{
+ struct pci_io pc;
+ int fd;
+
+ bzero(&pc, sizeof(struct pci_io));
+ pc.pi_sel.pc_domain = dev->address.domain;
+ pc.pi_sel.pc_bus = dev->address.bus;
+ pc.pi_sel.pc_dev = dev->address.slot;
+ pc.pi_sel.pc_func = dev->address.function;
+ pc.pi_reg = pi_reg;
+ pc.pi_width = pi_width;
+
+ fd = open("/dev/pci", O_RDWR, 0);
+ errno = 0;
+ if (ioctl(fd, PCIOCREAD, &pc) == -1) {
+ VIR_FORCE_CLOSE(fd);
+ VIR_WARN("Failed to read from '%s' : %s", dev->name, g_strerror(errno));
+ return -1;
+ }
+ VIR_FORCE_CLOSE(fd);
+ *pi_data = pc.pi_data;
+ return 0;
+}
+static uint8_t
+virPCIDeviceRead8(virPCIDevice *dev, int pi_reg)
+{
+ u_int32_t pi_data;
+ virPCIDeviceRead(dev, pi_reg, 1, &pi_data);
+ return pi_data & 0xff;
+}
+static uint16_t
+virPCIDeviceRead16(virPCIDevice *dev, int pi_reg)
+{
+ u_int32_t pi_data;
+ virPCIDeviceRead(dev, pi_reg, 2, &pi_data);
+ return pi_data & 0xffff;
+}
+
+static uint32_t
+virPCIDeviceRead32(virPCIDevice *dev, int pi_reg)
+{
+ u_int32_t pi_data;
+ virPCIDeviceRead(dev, pi_reg, 4, &pi_data);
+ return pi_data;
+}
+#endif
static int
virPCIDeviceReadClass(virPCIDevice *dev, uint16_t *device_class)
{
@@ -499,6 +565,7 @@ virPCIDeviceReadClass(virPCIDevice *dev, uint16_t *device_class)
return 0;
}
+#ifndef __FreeBSD__
static int
virPCIDeviceWrite(virPCIDevice *dev,
int cfgfd,
@@ -528,6 +595,44 @@ virPCIDeviceWrite32(virPCIDevice *dev, int cfgfd, unsigned int pos, uint32_t val
uint8_t buf[4] = { (val >> 0), (val >> 8), (val >> 16), (val >> 24) };
virPCIDeviceWrite(dev, cfgfd, pos, &buf[0], sizeof(buf));
}
+#else
+static int
+virPCIDeviceWrite(virPCIDevice *dev, int pi_reg, int pi_width, u_int32_t pi_data)
+{
+ struct pci_io pc;
+ int fd;
+
+ bzero(&pc, sizeof(struct pci_io));
+ pc.pi_sel.pc_domain = dev->address.domain;
+ pc.pi_sel.pc_bus = dev->address.bus;
+ pc.pi_sel.pc_dev = dev->address.slot;
+ pc.pi_sel.pc_func = dev->address.function;
+ pc.pi_reg = pi_reg;
+ pc.pi_width = pi_width;
+ pc.pi_data = pi_data;
+
+ fd = open("/dev/pci", O_RDWR, 0);
+ errno = 0;
+ if (ioctl(fd, PCIOCWRITE, &pc) == -1) {
+ VIR_FORCE_CLOSE(fd);
+ VIR_WARN("Failed to write to '%s' : %s", dev->name, g_strerror(errno));
+ return -1;
+ }
+ VIR_FORCE_CLOSE(fd);
+ return 0;
+}
+static void
+virPCIDeviceWrite16(virPCIDevice *dev, int pi_reg, u_int16_t val)
+{
+ virPCIDeviceWrite(dev, pi_reg, 2, val);
+}
+
+static void
+virPCIDeviceWrite32(virPCIDevice *dev, int pi_reg, uint32_t val)
+{
+ virPCIDeviceWrite(dev, pi_reg, 4, val);
+}
+#endif
typedef int (*virPCIDeviceIterPredicate)(virPCIDevice *, virPCIDevice *,
void *);
@@ -610,7 +715,9 @@ virPCIDeviceIterDevices(virPCIDeviceIterPredicate predicate,
*/
static int
virPCIDeviceFindCapabilityOffset(virPCIDevice *dev,
+#ifndef __FreeBSD__
int cfgfd,
+#endif
unsigned int capability,
unsigned int *offset)
{
@@ -619,11 +726,19 @@ virPCIDeviceFindCapabilityOffset(virPCIDevice *dev,
*offset = 0; /* assume failure (*nothing* can be at offset 0) */
+#ifndef __FreeBSD__
status = virPCIDeviceRead16(dev, cfgfd, PCI_STATUS);
+#else
+ status = virPCIDeviceRead16(dev, PCI_STATUS);
+#endif
if (errno != 0 || !(status & PCI_STATUS_CAP_LIST))
goto error;
+#ifndef __FreeBSD__
pos = virPCIDeviceRead8(dev, cfgfd, PCI_CAPABILITY_LIST);
+#else
+ pos = virPCIDeviceRead8(dev, PCI_CAPABILITY_LIST);
+#endif
if (errno != 0)
goto error;
@@ -635,7 +750,11 @@ virPCIDeviceFindCapabilityOffset(virPCIDevice *dev,
* capabilities here.
*/
while (pos >= PCI_CONF_HEADER_LEN && pos != 0xff) {
+#ifndef __FreeBSD__
uint8_t capid = virPCIDeviceRead8(dev, cfgfd, pos);
+#else
+ uint8_t capid = virPCIDeviceRead8(dev, pos);
+#endif
if (errno != 0)
goto error;
@@ -646,7 +765,11 @@ virPCIDeviceFindCapabilityOffset(virPCIDevice *dev,
return 0;
}
+#ifndef __FreeBSD__
pos = virPCIDeviceRead8(dev, cfgfd, pos + 1);
+#else
+ pos = virPCIDeviceRead8(dev, pos + 1);
+#endif
if (errno != 0)
goto error;
}
@@ -665,7 +788,9 @@ virPCIDeviceFindCapabilityOffset(virPCIDevice *dev,
static unsigned int
virPCIDeviceFindExtendedCapabilityOffset(virPCIDevice *dev,
+#ifndef __FreeBSD__
int cfgfd,
+#endif
unsigned int capability)
{
int ttl;
@@ -677,7 +802,11 @@ virPCIDeviceFindExtendedCapabilityOffset(virPCIDevice *dev,
pos = PCI_EXT_CAP_BASE;
while (ttl > 0 && pos >= PCI_EXT_CAP_BASE) {
+#ifndef __FreeBSD__
header = virPCIDeviceRead32(dev, cfgfd, pos);
+#else
+ header = virPCIDeviceRead32(dev, pos);
+#endif
if ((header & PCI_EXT_CAP_ID_MASK) == capability)
return pos;
@@ -693,7 +822,11 @@ virPCIDeviceFindExtendedCapabilityOffset(virPCIDevice *dev,
* not have FLR, 1 if it does, and -1 on error
*/
static bool
+#ifndef __FreeBSD__
virPCIDeviceDetectFunctionLevelReset(virPCIDevice *dev, int cfgfd)
+#else
+virPCIDeviceDetectFunctionLevelReset(virPCIDevice *dev)
+#endif
{
uint32_t caps;
unsigned int pos;
@@ -707,7 +840,11 @@ virPCIDeviceDetectFunctionLevelReset(virPCIDevice *dev, int cfgfd)
* on SR-IOV NICs at the moment.
*/
if (dev->pcie_cap_pos) {
+#ifndef __FreeBSD__
caps = virPCIDeviceRead32(dev, cfgfd, dev->pcie_cap_pos + PCI_EXP_DEVCAP);
+#else
+ caps = virPCIDeviceRead32(dev, dev->pcie_cap_pos + PCI_EXP_DEVCAP);
+#endif
if (caps & PCI_EXP_DEVCAP_FLR) {
VIR_DEBUG("%s %s: detected PCIe FLR capability", dev->id, dev->name);
return true;
@@ -718,11 +855,19 @@ virPCIDeviceDetectFunctionLevelReset(virPCIDevice *dev, int cfgfd)
* the same thing, except for conventional PCI
* devices. This is not common yet.
*/
+#ifndef __FreeBSD__
if (virPCIDeviceFindCapabilityOffset(dev, cfgfd, PCI_CAP_ID_AF, &pos) < 0)
+#else
+ if (virPCIDeviceFindCapabilityOffset(dev, PCI_CAP_ID_AF, &pos) < 0)
+#endif
goto error;
if (pos) {
+#ifndef __FreeBSD__
caps = virPCIDeviceRead16(dev, cfgfd, pos + PCI_AF_CAP);
+#else
+ caps = virPCIDeviceRead16(dev, pos + PCI_AF_CAP);
+#endif
if (caps & PCI_AF_CAP_FLR) {
VIR_DEBUG("%s %s: detected PCI FLR capability", dev->id, dev->name);
return true;
@@ -754,13 +899,21 @@ virPCIDeviceDetectFunctionLevelReset(virPCIDevice *dev, int cfgfd)
* internal reset, not just a soft reset.
*/
static bool
+#ifndef __FreeBSD__
virPCIDeviceDetectPowerManagementReset(virPCIDevice *dev, int cfgfd)
+#else
+virPCIDeviceDetectPowerManagementReset(virPCIDevice *dev)
+#endif
{
if (dev->pci_pm_cap_pos) {
uint32_t ctl;
/* require the NO_SOFT_RESET bit is clear */
+#ifndef __FreeBSD__
ctl = virPCIDeviceRead32(dev, cfgfd, dev->pci_pm_cap_pos + PCI_PM_CTRL);
+#else
+ ctl = virPCIDeviceRead32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL);
+#endif
if (!(ctl & PCI_PM_CTRL_NO_SOFT_RESET)) {
VIR_DEBUG("%s %s: detected PM reset capability", dev->id, dev->name);
return true;
@@ -811,13 +964,17 @@ virPCIDeviceIsParent(virPCIDevice *dev, virPCIDevice *check, void *data)
uint8_t header_type, secondary, subordinate;
virPCIDevice **best = data;
int ret = 0;
+#ifndef __FreeBSD__
int fd;
+#endif
if (dev->address.domain != check->address.domain)
return 0;
+#ifndef __FreeBSD__
if ((fd = virPCIDeviceConfigOpenTry(check)) < 0)
return 0;
+#endif
/* Is it a bridge? */
ret = virPCIDeviceReadClass(check, &device_class);
@@ -825,12 +982,21 @@ virPCIDeviceIsParent(virPCIDevice *dev, virPCIDevice *check, void *data)
goto cleanup;
/* Is it a plane? */
+#ifndef __FreeBSD__
header_type = virPCIDeviceRead8(check, fd, PCI_HEADER_TYPE);
+#else
+ header_type = virPCIDeviceRead8(check, PCI_HEADER_TYPE);
+#endif
if ((header_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
goto cleanup;
+#ifndef __FreeBSD__
secondary = virPCIDeviceRead8(check, fd, PCI_SECONDARY_BUS);
subordinate = virPCIDeviceRead8(check, fd, PCI_SUBORDINATE_BUS);
+#else
+ secondary = virPCIDeviceRead8(check, PCI_SECONDARY_BUS);
+ subordinate = virPCIDeviceRead8(check, PCI_SUBORDINATE_BUS);
+#endif
VIR_DEBUG("%s %s: found parent device %s", dev->id, dev->name, check->name);
@@ -858,13 +1024,19 @@ virPCIDeviceIsParent(virPCIDevice *dev, virPCIDevice *check, void *data)
* parent. See if the current device is more restrictive than the
* best, and if so, make it the new best
*/
+#ifndef __FreeBSD__
int bestfd;
+#endif
uint8_t best_secondary;
+#ifndef __FreeBSD__
if ((bestfd = virPCIDeviceConfigOpenTry(*best)) < 0)
goto cleanup;
best_secondary = virPCIDeviceRead8(*best, bestfd, PCI_SECONDARY_BUS);
virPCIDeviceConfigClose(*best, bestfd);
+#else
+ best_secondary = virPCIDeviceRead8(*best, PCI_SECONDARY_BUS);
+#endif
if (secondary > best_secondary) {
virPCIDeviceFree(*best);
@@ -878,7 +1050,9 @@ virPCIDeviceIsParent(virPCIDevice *dev, virPCIDevice *check, void *data)
}
cleanup:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(check, fd);
+#endif
return ret;
}
@@ -902,7 +1076,9 @@ virPCIDeviceGetParent(virPCIDevice *dev, virPCIDevice **parent)
*/
static int
virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
+#ifndef __FreeBSD__
int cfgfd,
+#endif
virPCIDeviceList *inactiveDevs)
{
g_autoptr(virPCIDevice) parent = NULL;
@@ -910,7 +1086,9 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
uint8_t config_space[PCI_CONF_LEN];
uint16_t ctl;
int ret = -1;
+#ifndef __FreeBSD__
int parentfd;
+#endif
/* Refuse to do a secondary bus reset if there are other
* devices/functions behind the bus are used by the host
@@ -932,8 +1110,11 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
dev->name);
return -1;
}
+
+#ifndef __FreeBSD__
if ((parentfd = virPCIDeviceConfigOpenWrite(parent)) < 0)
goto out;
+#endif
VIR_DEBUG("%s %s: doing a secondary bus reset", dev->id, dev->name);
@@ -941,7 +1122,11 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
* for the supplied device since we refuse to do a reset if there
* are multiple devices/functions
*/
+#ifndef __FreeBSD__
if (virPCIDeviceRead(dev, cfgfd, 0, config_space, PCI_CONF_LEN) < 0) {
+#else
+ if (virPCIDeviceRead(dev, 0, PCI_CONF_LEN, (u_int32_t *) config_space) < 0) {
+#endif
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to read PCI config space for %1$s"),
dev->name);
@@ -951,6 +1136,7 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
/* Read the control register, set the reset flag, wait 200ms,
* unset the reset flag and wait 200ms.
*/
+#ifndef __FreeBSD__
ctl = virPCIDeviceRead16(dev, parentfd, PCI_BRIDGE_CONTROL);
virPCIDeviceWrite16(parent, parentfd, PCI_BRIDGE_CONTROL,
@@ -963,6 +1149,20 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
g_usleep(200 * 1000); /* sleep 200ms */
if (virPCIDeviceWrite(dev, cfgfd, 0, config_space, PCI_CONF_LEN) < 0) {
+#else
+ ctl = virPCIDeviceRead16(parent, PCI_BRIDGE_CONTROL);
+
+ virPCIDeviceWrite16(parent, PCI_BRIDGE_CONTROL,
+ ctl | PCI_BRIDGE_CTL_RESET);
+
+ g_usleep(200 * 1000); /* sleep 200ms */
+
+ virPCIDeviceWrite16(parent, PCI_BRIDGE_CONTROL, ctl);
+
+ g_usleep(200 * 1000); /* sleep 200ms */
+
+ if (virPCIDeviceWrite(dev, 0, PCI_CONF_LEN, (config_space[0] << 0) | (config_space[1] << 8) | (config_space[2] << 16) | (config_space[3] << 24)) < 0) {
+#endif
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to restore PCI config space for %1$s"),
dev->name);
@@ -971,7 +1171,9 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
ret = 0;
out:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(parent, parentfd);
+#endif
return ret;
}
@@ -980,7 +1182,11 @@ virPCIDeviceTrySecondaryBusReset(virPCIDevice *dev,
* above we require the device supports a full internal reset.
*/
static int
+#ifndef __FreeBSD__
virPCIDeviceTryPowerManagementReset(virPCIDevice *dev, int cfgfd)
+#else
+virPCIDeviceTryPowerManagementReset(virPCIDevice *dev)
+#endif
{
uint8_t config_space[PCI_CONF_LEN];
uint32_t ctl;
@@ -989,6 +1195,7 @@ virPCIDeviceTryPowerManagementReset(virPCIDevice *dev, int cfgfd)
return -1;
/* Save and restore the device's config space. */
+#ifndef __FreeBSD__
if (virPCIDeviceRead(dev, cfgfd, 0, &config_space[0], PCI_CONF_LEN) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to read PCI config space for %1$s"),
@@ -1012,6 +1219,31 @@ virPCIDeviceTryPowerManagementReset(virPCIDevice *dev, int cfgfd)
g_usleep(10 * 1000); /* sleep 10ms */
if (virPCIDeviceWrite(dev, cfgfd, 0, &config_space[0], PCI_CONF_LEN) < 0) {
+#else
+ if (virPCIDeviceRead(dev, 0, PCI_CONF_LEN, (u_int32_t *) config_space) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to read PCI config space for %1$s"),
+ dev->name);
+ return -1;
+ }
+
+ VIR_DEBUG("%s %s: doing a power management reset", dev->id, dev->name);
+
+ ctl = virPCIDeviceRead32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL);
+ ctl &= ~PCI_PM_CTRL_STATE_MASK;
+
+ virPCIDeviceWrite32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL,
+ ctl | PCI_PM_CTRL_STATE_D3hot);
+
+ g_usleep(10 * 1000); /* sleep 10ms */
+
+ virPCIDeviceWrite32(dev, dev->pci_pm_cap_pos + PCI_PM_CTRL,
+ ctl | PCI_PM_CTRL_STATE_D0);
+
+ g_usleep(10 * 1000); /* sleep 10ms */
+
+ if (virPCIDeviceWrite(dev, 0, PCI_CONF_LEN, (config_space[0] << 0) | (config_space[1] << 8) | (config_space[2] << 16) | (config_space[3] << 24)) < 0) {
+#endif
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to restore PCI config space for %1$s"),
dev->name);
@@ -1046,10 +1278,18 @@ virPCIDeviceTryPowerManagementReset(virPCIDevice *dev, int cfgfd)
* Always returns success (0) (for now)
*/
static int
+#ifndef __FreeBSD__
virPCIDeviceInit(virPCIDevice *dev, int cfgfd)
+#else
+virPCIDeviceInit(virPCIDevice *dev)
+#endif
{
dev->is_pcie = false;
+#ifndef __FreeBSD__
if (virPCIDeviceFindCapabilityOffset(dev, cfgfd, PCI_CAP_ID_EXP, &dev->pcie_cap_pos) < 0) {
+#else
+ if (virPCIDeviceFindCapabilityOffset(dev, PCI_CAP_ID_EXP, &dev->pcie_cap_pos) < 0) {
+#endif
/* an unprivileged process is unable to read *all* of a
* device's PCI config (it can only read the first 64
* bytes, which isn't enough for see the Express
@@ -1065,6 +1305,7 @@ virPCIDeviceInit(virPCIDevice *dev, int cfgfd)
* -1), then we blindly assume the most likely outcome -
* PCIe.
*/
+#ifndef __FreeBSD__
off_t configLen = virFileLength(virPCIDeviceGetConfigPath(dev), -1);
if (configLen != 256)
@@ -1077,6 +1318,16 @@ virPCIDeviceInit(virPCIDevice *dev, int cfgfd)
virPCIDeviceFindCapabilityOffset(dev, cfgfd, PCI_CAP_ID_PM, &dev->pci_pm_cap_pos);
dev->has_flr = virPCIDeviceDetectFunctionLevelReset(dev, cfgfd);
dev->has_pm_reset = virPCIDeviceDetectPowerManagementReset(dev, cfgfd);
+#else
+
+ } else {
+ dev->is_pcie = (dev->pcie_cap_pos != 0);
+ }
+
+ virPCIDeviceFindCapabilityOffset(dev, PCI_CAP_ID_PM, &dev->pci_pm_cap_pos);
+ dev->has_flr = virPCIDeviceDetectFunctionLevelReset(dev);
+ dev->has_pm_reset = virPCIDeviceDetectPowerManagementReset(dev);
+#endif
return 0;
}
@@ -1089,7 +1340,9 @@ virPCIDeviceReset(virPCIDevice *dev,
g_autofree char *drvName = NULL;
virPCIStubDriver drvType;
int ret = -1;
+#ifndef __FreeBSD__
int fd = -1;
+#endif
int hdrType = -1;
if (virPCIGetHeaderType(dev, &hdrType) < 0)
@@ -1125,10 +1378,14 @@ virPCIDeviceReset(virPCIDevice *dev,
VIR_DEBUG("Resetting device %s", dev->name);
+#ifndef __FreeBSD__
if ((fd = virPCIDeviceConfigOpenWrite(dev)) < 0)
goto cleanup;
if (virPCIDeviceInit(dev, fd) < 0)
+#else
+ if (virPCIDeviceInit(dev) < 0)
+#endif
goto cleanup;
/* KVM will perform FLR when starting and stopping
@@ -1144,11 +1401,19 @@ virPCIDeviceReset(virPCIDevice *dev,
* the function, not the whole device.
*/
if (dev->has_pm_reset)
+#ifndef __FreeBSD__
ret = virPCIDeviceTryPowerManagementReset(dev, fd);
+#else
+ ret = virPCIDeviceTryPowerManagementReset(dev);
+#endif
/* Bus reset is not an option with the root bus */
if (ret < 0 && dev->address.bus != 0)
+#ifndef __FreeBSD__
ret = virPCIDeviceTrySecondaryBusReset(dev, fd, inactiveDevs);
+#else
+ ret = virPCIDeviceTrySecondaryBusReset(dev, inactiveDevs);
+#endif
if (ret < 0) {
virErrorPtr err = virGetLastError();
@@ -1160,7 +1425,9 @@ virPCIDeviceReset(virPCIDevice *dev,
}
cleanup:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(dev, fd);
+#endif
return ret;
}
@@ -1868,6 +2135,12 @@ virPCIDeviceNew(const virPCIDeviceAddress *address)
g_autoptr(virPCIDevice) dev = NULL;
g_autofree char *vendor = NULL;
g_autofree char *product = NULL;
+#ifdef __FreeBSD__
+ struct pci_conf_io pc;
+ struct pci_match_conf patterns[1];
+ struct pci_conf conf[1];
+ int fd;
+#endif
dev = g_new0(virPCIDevice, 1);
@@ -1875,6 +2148,7 @@ virPCIDeviceNew(const virPCIDeviceAddress *address)
dev->name = virPCIDeviceAddressAsString(&dev->address);
+#ifndef __FreeBSD__
dev->path = g_strdup_printf(PCI_SYSFS "devices/%s/config", dev->name);
if (!virFileExists(dev->path)) {
@@ -1902,6 +2176,52 @@ virPCIDeviceNew(const virPCIDeviceAddress *address)
&vendor[2], &product[2]);
return NULL;
}
+#else
+ fd = open("/dev/pci", O_RDONLY, 0);
+ if (fd < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("Error open /dev/pci: %1$d"), errno);
+ return NULL;
+ }
+
+ bzero(&pc, sizeof(struct pci_conf_io));
+ pc.match_buf_len = sizeof(conf);
+ pc.matches = conf;
+
+ bzero(patterns, sizeof(patterns));
+ patterns[0].pc_sel.pc_domain = address->domain;
+ patterns[0].pc_sel.pc_bus = address->bus;
+ patterns[0].pc_sel.pc_dev = address->slot;
+ patterns[0].pc_sel.pc_func = address->function;
+
+ patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS | PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC;
+ pc.num_patterns = 1;
+ pc.pat_buf_len = sizeof(patterns);
+ pc.patterns = patterns;
+
+ if (ioctl(fd, PCIOCGETCONF, &pc) == -1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("ioctl(PCIOCGETCONF) eroor: %1$d"), errno);
+ return NULL;
+ }
+ if (pc.status != PCI_GETCONF_LAST_DEVICE && pc.status != PCI_GETCONF_MORE_DEVS) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("error returned from PCIOCGETCONF ioctl: %1$d"), pc.status);
+ return NULL;
+ }
+ VIR_FORCE_CLOSE(fd);
+ if (pc.num_matches == 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("Device not found: %1$d"), pc.num_matches);
+ return NULL;
+ }
+
+ /* strings contain '0x' prefix */
+ if (g_snprintf(dev->id, sizeof(dev->id), "%x %x", pc.matches->pc_vendor,
+ pc.matches->pc_device) >= sizeof(dev->id)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("dev->id buffer overflow: %1$x %2$x"),
+ pc.matches->pc_vendor, pc.matches->pc_device);
+ return NULL;
+ }
+ dev->pc_hdr = pc.matches->pc_hdr;
+#endif
VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
@@ -1918,10 +2238,12 @@ virPCIDeviceCopy(virPCIDevice *dev)
/* shallow copy to take care of most attributes */
*copy = *dev;
+#ifndef __FreeBSD__
copy->path = NULL;
+ copy->path = g_strdup(dev->path);
+#endif
copy->used_by_drvname = copy->used_by_domname = NULL;
copy->name = g_strdup(dev->name);
- copy->path = g_strdup(dev->path);
copy->used_by_drvname = g_strdup(dev->used_by_drvname);
copy->used_by_domname = g_strdup(dev->used_by_domname);
copy->stubDriverName = g_strdup(dev->stubDriverName);
@@ -1936,7 +2258,9 @@ virPCIDeviceFree(virPCIDevice *dev)
return;
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
g_free(dev->name);
+#ifndef __FreeBSD__
g_free(dev->path);
+#endif
g_free(dev->used_by_drvname);
g_free(dev->used_by_domname);
g_free(dev->stubDriverName);
@@ -1970,11 +2294,19 @@ virPCIDeviceGetName(virPCIDevice *dev)
* Returns a pointer to a string containing the path of @dev's PCI
* config file.
*/
+#ifndef __FreeBSD__
const char *
virPCIDeviceGetConfigPath(virPCIDevice *dev)
{
return dev->path;
}
+#else
+const char *
+virPCIDeviceGetConfigPath(virPCIDevice *dev G_GNUC_UNUSED)
+{
+ return NULL;
+}
+#endif
void virPCIDeviceSetManaged(virPCIDevice *dev, bool managed)
{
@@ -2484,14 +2816,20 @@ virPCIDeviceDownstreamLacksACS(virPCIDevice *dev)
uint16_t flags;
uint16_t ctrl;
unsigned int pos;
+#ifndef __FreeBSD__
int fd;
+#endif
int ret = 0;
uint16_t device_class;
+#ifndef __FreeBSD__
if ((fd = virPCIDeviceConfigOpen(dev)) < 0)
return -1;
if (virPCIDeviceInit(dev, fd) < 0) {
+#else
+ if (virPCIDeviceInit(dev) < 0) {
+#endif
ret = -1;
goto cleanup;
}
@@ -2503,18 +2841,30 @@ virPCIDeviceDownstreamLacksACS(virPCIDevice *dev)
if (!pos || device_class != PCI_CLASS_BRIDGE_PCI)
goto cleanup;
+#ifndef __FreeBSD__
flags = virPCIDeviceRead16(dev, fd, pos + PCI_EXP_FLAGS);
+#else
+ flags = virPCIDeviceRead16(dev, pos + PCI_EXP_FLAGS);
+#endif
if (((flags & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_DOWNSTREAM)
goto cleanup;
+#ifndef __FreeBSD__
pos = virPCIDeviceFindExtendedCapabilityOffset(dev, fd, PCI_EXT_CAP_ID_ACS);
+#else
+ pos = virPCIDeviceFindExtendedCapabilityOffset(dev, PCI_EXT_CAP_ID_ACS);
+#endif
if (!pos) {
VIR_DEBUG("%s %s: downstream port lacks ACS", dev->id, dev->name);
ret = 1;
goto cleanup;
}
+#ifndef __FreeBSD__
ctrl = virPCIDeviceRead16(dev, fd, pos + PCI_EXT_ACS_CTRL);
+#else
+ ctrl = virPCIDeviceRead16(dev, pos + PCI_EXT_ACS_CTRL);
+#endif
if ((ctrl & PCI_EXT_CAP_ACS_ENABLED) != PCI_EXT_CAP_ACS_ENABLED) {
VIR_DEBUG("%s %s: downstream port has ACS disabled",
dev->id, dev->name);
@@ -2523,7 +2873,9 @@ virPCIDeviceDownstreamLacksACS(virPCIDevice *dev)
}
cleanup:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(dev, fd);
+#endif
return ret;
}
@@ -2689,7 +3041,7 @@ virPCIGetVirtualFunctions(const char *sysfs_path,
}
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
virPCIDeviceAddress *
virPCIGetDeviceAddressFromSysfsLink(const char *device_link)
@@ -3189,33 +3541,43 @@ virPCIDeviceGetVPD(virPCIDevice *dev G_GNUC_UNUSED)
int
virPCIDeviceIsPCIExpress(virPCIDevice *dev)
{
+int ret = -1;
+#ifndef __FreeBSD__
int fd;
- int ret = -1;
if ((fd = virPCIDeviceConfigOpen(dev)) < 0)
return ret;
if (virPCIDeviceInit(dev, fd) < 0)
+#else
+ if (virPCIDeviceInit(dev) < 0)
+#endif
goto cleanup;
ret = dev->is_pcie;
cleanup:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(dev, fd);
+#endif
return ret;
}
int
virPCIDeviceHasPCIExpressLink(virPCIDevice *dev)
{
- int fd;
int ret = -1;
uint16_t cap, type;
+#ifndef __FreeBSD__
+ int fd;
if ((fd = virPCIDeviceConfigOpen(dev)) < 0)
return ret;
if (virPCIDeviceInit(dev, fd) < 0)
+#else
+ if (virPCIDeviceInit(dev) < 0)
+#endif
goto cleanup;
if (dev->pcie_cap_pos == 0) {
@@ -3223,13 +3585,19 @@ virPCIDeviceHasPCIExpressLink(virPCIDevice *dev)
goto cleanup;
}
+#ifndef __FreeBSD__
cap = virPCIDeviceRead16(dev, fd, dev->pcie_cap_pos + PCI_CAP_FLAGS);
+#else
+ cap = virPCIDeviceRead16(dev, dev->pcie_cap_pos + PCI_CAP_FLAGS);
+#endif
type = (cap & PCI_EXP_FLAGS_TYPE) >> 4;
ret = type != PCI_EXP_TYPE_ROOT_INT_EP && type != PCI_EXP_TYPE_ROOT_EC;
cleanup:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(dev, fd);
+#endif
return ret;
}
@@ -3242,13 +3610,17 @@ virPCIDeviceGetLinkCapSta(virPCIDevice *dev,
unsigned int *sta_width)
{
uint32_t t;
- int fd;
int ret = -1;
+#ifndef __FreeBSD__
+ int fd;
if ((fd = virPCIDeviceConfigOpen(dev)) < 0)
return ret;
if (virPCIDeviceInit(dev, fd) < 0)
+#else
+ if (virPCIDeviceInit(dev) < 0)
+#endif
goto cleanup;
if (!dev->pcie_cap_pos) {
@@ -3258,26 +3630,37 @@ virPCIDeviceGetLinkCapSta(virPCIDevice *dev,
goto cleanup;
}
+#ifndef __FreeBSD__
t = virPCIDeviceRead32(dev, fd, dev->pcie_cap_pos + PCI_EXP_LNKCAP);
+#else
+ t = virPCIDeviceRead32(dev, dev->pcie_cap_pos + PCI_EXP_LNKCAP);
+#endif
*cap_port = t >> 24;
*cap_speed = t & PCI_EXP_LNKCAP_SPEED;
*cap_width = (t & PCI_EXP_LNKCAP_WIDTH) >> 4;
+#ifndef __FreeBSD__
t = virPCIDeviceRead16(dev, fd, dev->pcie_cap_pos + PCI_EXP_LNKSTA);
+#else
+ t = virPCIDeviceRead16(dev, dev->pcie_cap_pos + PCI_EXP_LNKSTA);
+#endif
*sta_speed = t & PCI_EXP_LNKSTA_SPEED;
*sta_width = (t & PCI_EXP_LNKSTA_WIDTH) >> 4;
ret = 0;
cleanup:
+#ifndef __FreeBSD__
virPCIDeviceConfigClose(dev, fd);
+#endif
return ret;
}
int virPCIGetHeaderType(virPCIDevice *dev, int *hdrType)
{
+#ifndef __FreeBSD__
int fd;
uint8_t type;
@@ -3289,6 +3672,13 @@ int virPCIGetHeaderType(virPCIDevice *dev, int *hdrType)
type = virPCIDeviceRead8(dev, fd, PCI_HEADER_TYPE);
virPCIDeviceConfigClose(dev, fd);
+#else
+ uint8_t type = dev->pc_hdr;
+
+ *hdrType = -1;
+
+ type = virPCIDeviceRead8(dev, PCI_HEADER_TYPE);
+#endif
type &= PCI_HEADER_TYPE_MASK;
if (type >= VIR_PCI_HEADER_LAST) {
--
2.47.1
2 months, 2 weeks
[PATCH] docs: Reword virDomainGetEmulatorPinInfo description
by Martin Kletzander
This API only queries the XML settings and not the running threads
themselves. In order to avoid confusion, change the wording slightly.
Resolves: https://issues.redhat.com/browse/RHEL-72052
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/libvirt-domain.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index e8e5379672ae..275d65b8c16b 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -7998,8 +7998,8 @@ virDomainPinEmulator(virDomainPtr domain, unsigned char *cpumap,
* Must not be VIR_DOMAIN_AFFECT_LIVE and
* VIR_DOMAIN_AFFECT_CONFIG concurrently.
*
- * Query the CPU affinity setting of all emulator threads of domain, store
- * it in cpumap.
+ * Query the CPU pinning setting of all emulator threads from the domain XML,
+ * store it in cpumap.
*
* Returns 1 in case of success,
* 0 in case of no emulator threads are pined to pcpus,
--
2.48.0
2 months, 2 weeks
[PATCH] tests: emuxmlconfdata: Update launch-security-sev-snp.xml
by Michal Privoznik
Recently, I was part of a discussion where it was suspected that
libvirt does not pick up correct FW for SEV-SNP guests. Update
our test to demonstrate it does.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
...launch-security-sev-snp.x86_64-latest.args | 13 +++-
.../launch-security-sev-snp.x86_64-latest.xml | 74 ++++++++++++++++++-
.../launch-security-sev-snp.xml | 38 ++++++++--
3 files changed, 113 insertions(+), 12 deletions(-)
mode change 120000 => 100644 tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml
diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args
index e74335f09d..b3bc7fcf04 100644
--- a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args
@@ -10,7 +10,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-name guest=QEMUGuest1,debug-threads=on \
-S \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
--machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,confidential-guest-support=lsec0,acpi=off \
+-blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF.amdsev.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \
+-machine pc-q35-8.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,confidential-guest-support=lsec0,pflash0=libvirt-pflash0-format,acpi=on \
-accel kvm \
-cpu qemu64 \
-m size=219136k \
@@ -26,10 +28,15 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-rtc base=utc \
-no-shutdown \
-boot strict=on \
--device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \
+-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \
+-device '{"driver":"pcie-root-port","port":10,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x1.0x2"}' \
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \
--device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-storage","id":"ide0-0-0","bootindex":1}' \
+-device '{"driver":"virtio-blk-pci","bus":"pci.2","addr":"0x0","drive":"libvirt-1-storage","id":"virtio-disk0","bootindex":1}' \
-audiodev '{"id":"audio1","driver":"none"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
-object '{"qom-type":"sev-snp-guest","id":"lsec0","cbitpos":47,"reduced-phys-bits":1,"policy":196608,"guest-visible-workarounds":"bGlidmlydGxpYnZpcnRsaQ==","id-block":"bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZp","id-auth":"bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bA==","host-data":"bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnY=","author-key-enabled":true,"vcek-disabled":true}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml
deleted file mode 120000
index 0159cc057b..0000000000
--- a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml
+++ /dev/null
@@ -1 +0,0 @@
-launch-security-sev-snp.xml
\ No newline at end of file
diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml
new file mode 100644
index 0000000000..d9bf146993
--- /dev/null
+++ b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml
@@ -0,0 +1,73 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os firmware='efi'>
+ <type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
+ <firmware>
+ <feature enabled='no' name='enrolled-keys'/>
+ <feature enabled='no' name='secure-boot'/>
+ </firmware>
+ <loader readonly='yes' type='pflash' stateless='yes' format='raw'>/usr/share/edk2/ovmf/OVMF.amdsev.fd</loader>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
+ </disk>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x9'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='3' port='0xa'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ </devices>
+ <launchSecurity type='sev-snp' authorKey='yes' vcek='no'>
+ <cbitpos>47</cbitpos>
+ <reducedPhysBits>1</reducedPhysBits>
+ <policy>0x00030000</policy>
+ <guestVisibleWorkarounds>bGlidmlydGxpYnZpcnRsaQ==</guestVisibleWorkarounds>
+ <idBlock>bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZp</idBlock>
+ <idAuth>bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bA==</idAuth>
+ <hostData>bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnY=</hostData>
+ </launchSecurity>
+</domain>
diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.xml b/tests/qemuxmlconfdata/launch-security-sev-snp.xml
index b277d7de1b..408198674e 100644
--- a/tests/qemuxmlconfdata/launch-security-sev-snp.xml
+++ b/tests/qemuxmlconfdata/launch-security-sev-snp.xml
@@ -4,10 +4,16 @@
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
- <os>
- <type arch='x86_64' machine='pc'>hvm</type>
+ <os firmware='efi'>
+ <type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
+ <loader stateless='yes'/>
<boot dev='hd'/>
</os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
@@ -20,19 +26,35 @@
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
- <target dev='hda' bus='ide'/>
- <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</disk>
- <controller type='usb' index='0' model='piix3-uhci'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</controller>
- <controller type='ide' index='0'>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x9'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
- <controller type='pci' index='0' model='pci-root'/>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='3' port='0xa'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<audio id='1' type='none'/>
+ <watchdog model='itco' action='reset'/>
<memballoon model='none'/>
</devices>
<launchSecurity type='sev-snp' authorKey='yes' vcek='no'>
--
2.45.2
2 months, 3 weeks
[PATCH] nodedev: udev: Hook up virFileWaitForExist to address uevent,
race of pci device
by Guoyi Tu
this commit addresses the same issue that as commit 1af45804 does.
the following message is copying from that commit:
If we find ourselves in the situation that the 'add' uevent has been
fired earlier than the sysfs tree for a device was created, we should
use the best-effort approach and give kernel some predetermined amount
of time, thus waiting for the attributes to be ready rather than
discarding the device from our device list forever. If those don't appear
in the given time frame, we need to move on, since libvirt can't wait
indefinitely.
Signed-off-by: Guoyi Tu <tugy(a)chinatelecom.cn>
---
src/node_device/node_device_udev.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/node_device/node_device_udev.c
b/src/node_device/node_device_udev.c
index 1d8486f623..4a1786c21c 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -427,10 +427,19 @@ udevProcessPCI(virNodeDeviceDriverState *driver_state,
virPCIEDeviceInfo *pci_express = NULL;
virPCIDevice *pciDev = NULL;
virPCIDeviceAddress devAddr = { 0 };
+ g_autofree char *linkpath = NULL;
int ret = -1;
char *p;
bool privileged = false;
+ linkpath = g_strdup_printf("%s/config",
udev_device_get_syspath(device));
+ if (virFileWaitForExists(linkpath, 10, 100) < 0) {
+ virReportSystemError(errno,
+ _("failed to wait for file '%1$s' to appear"),
+ linkpath);
+ goto cleanup;
+ }
+
VIR_WITH_MUTEX_LOCK_GUARD(&driver_state->lock) {
privileged = driver_state->privileged;
}
--
2.27.0
--
Guoyi
2 months, 3 weeks
[PATCH] docs: fix 'virsh domstats --vcpu' measure units and descriptions
by Fabricio Duarte
The fields are in nanoseconds, not microseconds. Also fixes the description of `vcpu.<num>.wait`, as it does not actually represent the time waiting on I/O.
Signed-off-by: Fabricio Duarte <fabricio.duarte.jr(a)gmail.com>
---
docs/manpages/virsh.rst | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 2e525d3fac..b0a21e019a 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2428,14 +2428,14 @@ When selecting the *--state* group the following fields are returned:
* ``vcpu.<num>.state`` - state of the virtual CPU <num>, as
number from virVcpuState enum
* ``vcpu.<num>.time`` - virtual cpu time spent by virtual
- CPU <num> (in microseconds)
-* ``vcpu.<num>.wait`` - virtual cpu time spent by virtual
- CPU <num> waiting on I/O (in microseconds)
+ CPU <num> (in nanoseconds)
+* ``vcpu.<num>.wait`` - time the vCPU <num> wants to run, but the host
+ scheduler has something else running ahead of it (in nanoseconds)
* ``vcpu.<num>.halted`` - virtual CPU <num> is halted: yes or
no (may indicate the processor is idle or even disabled,
depending on the architecture)
* ``vcpu.<num>.delay`` - time the vCPU <num> thread was enqueued by the
- host scheduler, but was waiting in the queue instead of running.
+ host scheduler, but was waiting in the queue instead of running (in nanoseconds).
Exposed to the VM as a steal time.
This group of statistics also reports additional hypervisor-originating per-vCPU
--
2.39.2
2 months, 3 weeks
Investigating MAC Address Conflict Resolution in libvirt: Log
Analysis and Code Location Inquiry
by Xuda Zhang
Dear Team,
I am reaching out regarding an issue I encountered with libvirt and MAC
address conflicts. Below is a summary of the situation:
1. Initially, the vNIC's MAC address was different from the target VM's
MAC address.
2. After modifying the vNIC's MAC address to match the VM's MAC address,
the network was interrupted.
3. After rebooting the VM, the vNIC's MAC address was automatically
modified again.
I have observed the following kernel logs during this process:
Dec 24 16:59:40 zstack-manager kernel: br_enp2s0: port 14(vnic43.0)
entered disabled stateDec 24 16:59:40 zstack-manager kernel: device
vnic43.0 left promiscuous modeDec 24 16:59:40 zstack-manager kernel:
br_enp2s0: port 14(vnic43.0) entered disabled stateDec 24 17:00:11
zstack-manager kernel: br_enp2s0: port 14(vnic43.0) entered blocking
stateDec 24 17:00:11 zstack-manager kernel: br_enp2s0: port
14(vnic43.0) entered disabled stateDec 24 17:00:11 zstack-manager
kernel: device vnic43.0 entered promiscuous modeDec 24 17:00:11
zstack-manager kernel: br_enp2s0: port 14(vnic43.0) entered blocking
stateDec 24 17:00:11 zstack-manager kernel: br_enp2s0: port
14(vnic43.0) entered forwarding state
I am looking to understand the underlying code that handles the automatic
modification of the vNIC's MAC address after the conflict and how the
network interruption occurs. Can you help direct me to the relevant code
segment or provide any insights into this behavior?
Thank you for your assistance.
Best regards,
2 months, 3 weeks
[PATCH v3 00/17] hw/microblaze: Allow running cross-endian vCPUs
by Philippe Mathieu-Daudé
Missing review: 4 (new) & 10
Since v2:
- Addressed Richard's review comments
Since v1:
- Make device endianness configurable (Edgar)
- Convert more Xilinx devices
- Avoid preprocessor #if (Richard)
- Add R-b tags
Make machines endianness-agnostic, allowing to run a big-endian vCPU
on the little-endian 'qemu-system-microblazeel' binary, and a little
endian one on the big-endian 'qemu-system-microblaze' binary.
Tests added, following combinations covered:
- little-endian vCPU using little-endian binary (in-tree)
- little-endian vCPU using big-endian binary (new)
- big-endian vCPU using little-endian binary (new)
- big-endian vCPU using big-endian binary (in-tree)
To make a target endian-agnostic we need to remove the MO_TE uses.
In order to do that, we propagate the MemOp from earlier in the
call stack, or we extract it from the vCPU env (on MicroBlaze the
CPU endianness is exposed by the 'ENDI' bit).
Next step: Look at unifying binaries.
Please review,
Phil.
Philippe Mathieu-Daudé (17):
hw/microblaze: Restrict MemoryRegionOps are implemented as 32-bit
hw/microblaze: Propagate CPU endianness to microblaze_load_kernel()
hw/intc/xilinx_intc: Make device endianness configurable
RFC hw/net/xilinx_ethlite: Simplify by having configurable endianness
RFC hw/timer/xilinx_timer: Allow down to 8-bit memory access
hw/timer/xilinx_timer: Make device endianness configurable
hw/char/xilinx_uartlite: Make device endianness configurable
hw/ssi/xilinx_spi: Make device endianness configurable
hw/ssi/xilinx_spips: Make device endianness configurable
hw/arm/xlnx-zynqmp: Use &error_abort for programming errors
target/microblaze: Explode MO_TExx -> MO_TE | MO_xx
target/microblaze: Set MO_TE once in do_load() / do_store()
target/microblaze: Introduce mo_endian() helper
target/microblaze: Consider endianness while translating code
hw/microblaze: Support various endianness for s3adsp1800 machines
tests/functional: Explicit endianness of microblaze assets
tests/functional: Add microblaze cross-endianness tests
hw/microblaze/boot.h | 4 +-
include/hw/ssi/xilinx_spips.h | 1 +
target/microblaze/cpu.h | 7 +++
hw/arm/xilinx_zynq.c | 1 +
hw/arm/xlnx-zynqmp.c | 40 +++++--------
hw/char/xilinx_uartlite.c | 31 ++++++----
hw/intc/xilinx_intc.c | 50 ++++++++++++----
hw/microblaze/boot.c | 8 +--
hw/microblaze/petalogix_ml605_mmu.c | 4 +-
hw/microblaze/petalogix_s3adsp1800_mmu.c | 58 ++++++++++++++++---
hw/microblaze/xlnx-zynqmp-pmu.c | 2 +-
hw/net/xilinx_ethlite.c | 42 +++++++++-----
hw/ppc/virtex_ml507.c | 1 +
hw/ssi/xilinx_spi.c | 24 +++++---
hw/ssi/xilinx_spips.c | 36 +++++++-----
hw/timer/xilinx_timer.c | 33 +++++++----
target/microblaze/translate.c | 49 ++++++++++------
.../functional/test_microblaze_s3adsp1800.py | 27 ++++++++-
.../test_microblazeel_s3adsp1800.py | 25 +++++++-
19 files changed, 309 insertions(+), 134 deletions(-)
--
2.45.2
2 months, 3 weeks
[PATCH] qemu: introduce load qemu.conf for "virt-qemu-run"
by Adam Julis
Adding a new option --config (or -c) for specifying a custom
qemu.conf file.
Previously, virt-qemu-run loaded default configuration values for
QEMU via qemuStateInitialize(). The configuration was loaded from
a temporary ../etc/ directory using virQEMUDriverConfigLoadFile(),
and any qemu.conf file present in that directory was also loaded
automatically.
This patch allows users to specify a custom configuration file,
which is copied into the temporary directory (or a permanent
folder if the -r option is used) before loading the
configuration. If an existing qemu.conf is present, it is
properly backed up and restored in case of a permanent folder.
The custom qemu.conf is always removed when the program exits.
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/723
Signed-off-by: Adam Julis <ajulis(a)redhat.com>
---
docs/manpages/virt-qemu-run.rst | 9 +++
src/qemu/qemu_shim.c | 121 +++++++++++++++++++++++++++++++-
2 files changed, 129 insertions(+), 1 deletion(-)
diff --git a/docs/manpages/virt-qemu-run.rst b/docs/manpages/virt-qemu-run.rst
index 4d546ff8cc..ba1c90b52a 100644
--- a/docs/manpages/virt-qemu-run.rst
+++ b/docs/manpages/virt-qemu-run.rst
@@ -72,6 +72,15 @@ whose UUID should match a secret referenced in the guest domain XML.
Display verbose information about startup.
+``-c`` *QEMU-CONF-FILE*,
+``--config``\ =\ *QEMU-CONF-FILE*
+
+Specify the QEMU configuration file to be used for starting the VM.
+*QEMU-CONF-FILE* is the full path to the QEMU configuration file.
+
+If this parameter is omitted, the default configuration values will
+be used.
+
``-h``, ``--help``
Display the command line help.
diff --git a/src/qemu/qemu_shim.c b/src/qemu/qemu_shim.c
index 7fdd69b538..64c87ab264 100644
--- a/src/qemu/qemu_shim.c
+++ b/src/qemu/qemu_shim.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
+#include <fcntl.h>
#include "virfile.h"
#include "virgettext.h"
@@ -132,6 +133,100 @@ qemuShimQuench(void *userData G_GNUC_UNUSED,
{
}
+/* Load specific QEMU config file, is the -c option is used */
+static int
+qemuAddConfigFile(const char *source_file, const char *root, bool *config_to_delete, long long deltams)
+{
+ int ret = -1;
+ struct stat st;
+ VIR_AUTOCLOSE srcFD = -1;
+ VIR_AUTOCLOSE dstFD = -1;
+ g_autofree char *config_dir = NULL;
+ g_autofree char *source_file_real = NULL;
+ g_autofree char *config_path_file = NULL;
+ g_autofree char *config_path_file_real = NULL;
+
+ if ((srcFD = open(source_file, O_RDONLY)) < 0) {
+ g_printerr("Couldn't open specific config file\n");
+ goto cleanup;
+ }
+
+ if (fstat(srcFD, &st) != 0) {
+ g_printerr("Specific config file does not exist\n");
+ goto cleanup;
+ }
+ if (!S_ISREG(st.st_mode)) {
+ g_printerr("Specific config is not a regular file\n");
+ goto cleanup;
+ }
+
+ /* Since source file exists, make the destination path or
+ * validate that it already exists */
+ config_dir = g_strdup_printf("%s/etc/", root);
+
+ if (g_mkdir_with_parents(config_dir, 0777) < 0) {
+ g_printerr("Couldn't make the directory for specific config file\n");
+ goto cleanup;
+ }
+
+ config_path_file = g_strdup_printf("%sqemu.conf", config_dir);
+
+ /* If the source file is same as the destination file, no action needed */
+ if ((source_file_real = realpath(source_file, NULL)) &&
+ (config_path_file_real = realpath(config_path_file, NULL))) {
+ if (STREQ(source_file_real, config_path_file_real)) {
+ ret = 0;
+ goto cleanup;
+ }
+ }
+
+ /* Check already existing qemu.conf in the subfolder, if so, renamed
+ * (appended via deltams constant - should be unique). Final cleanup
+ * at main() will revert this change */
+ if (access(config_path_file, R_OK) == 0) {
+ if (rename(config_path_file, g_strdup_printf("%sqemu_old_%lld.conf",
+ config_dir, deltams)) != 0) {
+ g_printerr("Couldn't rename old config file, try delete it\n");
+ goto cleanup;
+ }
+ }
+
+ if ((dstFD = open(config_path_file, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
+ g_printerr("Couldn't open file for define specific config\n");
+ goto cleanup;
+ }
+
+ /* Set the flag for deleting the new/modified config in main() cleanup,
+ * for ensure that behaviour without the user config will be always
+ * consistent and take default value */
+ *config_to_delete = true;
+
+ do {
+ char buffer[1024];
+ ssize_t readed = 0;
+
+ readed = saferead(srcFD, buffer, 1024);
+
+ if (readed < 0) {
+ g_printerr("Couldn't read from specific config\n");
+ goto cleanup;
+ } else if (readed == 0) {
+ break;
+ } else {
+ ssize_t writed = safewrite(dstFD, buffer, readed);
+ if (writed != readed) {
+ g_printerr("Couldn't write to file for define specific config\n");
+ goto cleanup;
+ }
+ }
+ } while (1);
+
+ ret = 0;
+
+ cleanup:
+ return ret;
+}
+
int main(int argc, char **argv)
{
g_autoptr(virIdentity) sysident = NULL;
@@ -142,8 +237,11 @@ int main(int argc, char **argv)
g_autofree char *uri = NULL;
g_autofree char *suri = NULL;
const char *root = NULL;
+ const char *config = NULL;
+ long long delta_ms = 0;
g_autofree char *escaped = NULL;
bool tmproot = false;
+ bool config_to_delete = false;
int ret = 1;
g_autoptr(GError) error = NULL;
g_auto(GStrv) secrets = NULL;
@@ -156,6 +254,7 @@ int main(int argc, char **argv)
{ "root", 'r', 0, G_OPTION_ARG_STRING, &root, "Root directory", "DIR" },
{ "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Debug output", NULL },
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", NULL },
+ { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "Load specific QEMU configuration file", "QEMU-CONF-FILE"},
{ 0 }
};
int quitfd[2] = {-1, -1};
@@ -172,7 +271,7 @@ int main(int argc, char **argv)
return 1;
}
- if (argc != 2) {
+ if (argc != 2 && argc != 3) {
g_autofree char *help = g_option_context_get_help(ctx, TRUE, NULL);
g_printerr("%s", help);
return 1;
@@ -234,6 +333,10 @@ int main(int argc, char **argv)
goto cleanup;
}
+ delta_ms = deltams();
+ if (config && (qemuAddConfigFile(config, root, &config_to_delete, delta_ms) < 0))
+ g_printerr("Specific config file was not loaded, default was used\n");
+
escaped = g_uri_escape_string(root, NULL, true);
virFileActivateDirOverrideForProg(argv[0]);
@@ -402,6 +505,22 @@ int main(int argc, char **argv)
VIR_FORCE_CLOSE(quitfd[0]);
VIR_FORCE_CLOSE(quitfd[1]);
+ if (config_to_delete) {
+ g_autofree char *possible_old_file = g_strdup_printf("%s/etc/qemu_old_%lld.conf",
+ root, delta_ms);
+ g_autofree char *to_delete = g_strdup_printf("%s/etc/qemu.conf", root);
+
+ if (remove(to_delete) != 0)
+ g_printerr("Deleting specific config failed, located in: %s\n",
+ to_delete);
+
+ if (access(possible_old_file, R_OK) == 0) {
+ if (rename(possible_old_file, to_delete) != 0)
+ g_printerr("Renaming your old qemu.conf failed, ups, located in %s\n",
+ possible_old_file);
+ }
+ }
+
if (dom != NULL)
virDomainFree(dom);
if (sconn != NULL)
--
2.47.1
2 months, 3 weeks
[PATCH 0/5] Drop support for VirtualBox-6.1
by Michal Privoznik
This was initiated by the following issue:
https://gitlab.com/libvirt/libvirt/-/issues/681
and I tried to add support for VBOX-7.1 but unfortunately got hit by a
bug in VBOX which renders the way we initialize C bindings useless. I've
reported the bug here:
https://www.virtualbox.org/ticket/22224
but it didn't get any attention.
Michal Prívozník (5):
vbox: Use g_autofree in tryLoadOne()
vbox: Report an error when VBox CAPI initialization fails
vbox: Drop support for VirtualBox-6.1.x
vbox: Drop code supporting old VBox version
NEWS: Document VBOX-6.1 removal
NEWS.rst | 5 +
src/vbox/meson.build | 1 -
src/vbox/vbox_CAPI_v6_1.h | 32896 --------------------------------
src/vbox/vbox_V6_1.c | 13 -
src/vbox/vbox_XPCOMCGlue.c | 5 +-
src/vbox/vbox_XPCOMCGlue.h | 2 +-
src/vbox/vbox_common.h | 4 +-
src/vbox/vbox_storage.c | 4 +-
src/vbox/vbox_tmpl.c | 30 +-
src/vbox/vbox_uniformed_api.h | 1 -
10 files changed, 16 insertions(+), 32945 deletions(-)
delete mode 100644 src/vbox/vbox_CAPI_v6_1.h
delete mode 100644 src/vbox/vbox_V6_1.c
--
2.45.2
2 months, 3 weeks