[PATCH 0/4] storage pool define: add support for validation against schema
by Kristina Hanicova
Kristina Hanicova (4):
api: add virStoragePoolDefineFlags
storage_conf: add validation against schema in pool define
storage_driver & test_driver: allow VIR_STORAGE_POOL_DEFINE_VALIDATE
flag
virsh: add support for '--validate' option in define storage pool
docs/manpages/virsh.rst | 4 +++-
include/libvirt/libvirt-storage.h | 4 ++++
src/conf/domain_conf.c | 2 +-
src/conf/storage_conf.c | 13 ++++++++-----
src/conf/storage_conf.h | 3 ++-
src/libvirt-storage.c | 2 +-
src/storage/storage_driver.c | 6 +++---
src/test/test_driver.c | 6 +++---
tools/virsh-pool.c | 11 +++++++++--
9 files changed, 34 insertions(+), 17 deletions(-)
--
2.31.1
3 years
[PATCH] lxcxml2xmltest: Substitute 'inactive' variable with 'active'
by Kristina Hanicova
I removed negation from the name of a variable to make the code
more readable.
Signed-off-by: Kristina Hanicova <khanicov(a)redhat.com>
---
tests/lxcxml2xmltest.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c
index 00341ad695..69c333b9b5 100644
--- a/tests/lxcxml2xmltest.c
+++ b/tests/lxcxml2xmltest.c
@@ -21,7 +21,7 @@ static virLXCDriver *driver;
struct testInfo {
const char *name;
int different;
- bool inactive_only;
+ bool active_only;
unsigned int parse_flags;
};
@@ -40,7 +40,7 @@ testCompareXMLToXMLHelper(const void *data)
ret = testCompareDomXML2XMLFiles(driver->caps, driver->xmlopt, xml_in,
info->different ? xml_out : xml_in,
- !info->inactive_only,
+ info->active_only,
info->parse_flags,
TEST_COMPARE_DOM_XML2XML_RESULT_SUCCESS);
VIR_FREE(xml_in);
@@ -57,9 +57,9 @@ mymain(void)
if (!(driver = testLXCDriverInit()))
return EXIT_FAILURE;
-# define DO_TEST_FULL(name, is_different, inactive, parse_flags) \
+# define DO_TEST_FULL(name, is_different, active, parse_flags) \
do { \
- const struct testInfo info = {name, is_different, inactive, \
+ const struct testInfo info = {name, is_different, active, \
parse_flags}; \
if (virTestRun("LXC XML-2-XML " name, \
testCompareXMLToXMLHelper, &info) < 0) \
@@ -67,10 +67,10 @@ mymain(void)
} while (0)
# define DO_TEST(name) \
- DO_TEST_FULL(name, 0, false, 0)
+ DO_TEST_FULL(name, 0, true, 0)
# define DO_TEST_DIFFERENT(name) \
- DO_TEST_FULL(name, 1, false, 0)
+ DO_TEST_FULL(name, 1, true, 0)
/* Unset or set all envvars here that are copied in lxcdBuildCommandLine
* using ADD_ENV_COPY, otherwise these tests may fail due to unexpected
--
2.31.1
3 years
[libvirt PATCH 0/6] qemu: capabilities: use g_auto (glib chronicles)
by Ján Tomko
This is not a cover letter.
Ján Tomko (6):
qemu: refactor virQEMUCapsNewForBinaryInternal
qemu: refactor virQEMUCapsLoadFile
qemu: refactor virQEMUCapsInit
qemu: refactor virQEMUCapsNewCopy
qemu: capabilities: use g_auto
qemu: capabilities: remove pointless labels
src/qemu/qemu_capabilities.c | 134 ++++++++++++-----------------------
1 file changed, 45 insertions(+), 89 deletions(-)
--
2.31.1
3 years
[PATCHv2 0/2] Support VM core dump to block device
by Simon Rowe
When the destination of a VM core dump is a block device (e.g. NBD)
avoid file operations that are unnecessary.
Simon Rowe (2):
iohelper: skip lseek() and ftruncate() on block devices
qemu: check unlink hint from virQEMUFileOpenAs()
src/qemu/qemu_driver.c | 8 +++-----
src/util/iohelper.c | 10 ++++++++--
2 files changed, 11 insertions(+), 7 deletions(-)
--
2.22.3
3 years
[libvirt PATCH 0/1] Add a PCI/PCIe device VPD Capability
by Dmitrii Shcherbakov
Add support for deserializing the binary PCI/PCIe VPD format and
exposing VPD resources as XML elements in a new nested capability
of PCI/PCIe devices called 'vpd'.
The VPD format is specified in "I.3. VPD Definitions" in PCI specs
(2.2+) and "6.28.1 VPD Format" PCIe 4.0. As section 6.28 in PCIe 4.0
notes, the PCI Local Bus and PCIe VPD formats are binary compatible
and PCIe 4.0 merely started incorporating what was already present in
PCI specs.
Linux kernel exposes a binary blob in the VPD format via sysfs since
v2.6.26 (commit 94e6108803469a37ee1e3c92dafdd1d59298602f) which requires
a parser to interpret.
There are usage scenarios where information such as the board serial
number needs to be retrieved from PCI(e) VPD. Projects like Nova can
utilize this information for cases which involve virtual interface
plugging on SmartNIC DPUs but there may be other scenarios and types of
information useful to retrieve from VPD. The fact that the format is
binary requires proper parsing instead of substring searching hence the
full parser is proposed. Likewise, checksum validation requires proper
parsing as well.
The patch follows a prior discussion on the mailing list which has
additional context about the use-case but a narrower proposal:
https://listman.redhat.com/archives/libvir-list/2021-May/msg00873.html
https://www.mail-archive.com/libvir-list@redhat.com/msg218165.html
The new functionality is mostly contained in virpcivpd with a
couple of new functions added to virpci. Additionally, the necessary XML
serialization/deserialization and glue code is added to expose the VPD
capability to external clients as XML.
A new capability flag is added along with a new capability in order to
allow for filtering of PCI devices with the VPD capability using virsh:
virsh nodedev-list --cap vpd
sudo virsh nodedev-dumpxml --device pci_dddd_bb_ss_f
In this example having the root uid is required in order to access the
vpd sysfs entry, therefore, the nodedev XML output will only contain
the VPD capability if virsh is run as root.
The capability is treated as dynamic due to the presence of read-write
sections in the VPD format per PCI/PCIe specs (the idea being that
read-write resource fields may potentially be altered by the DPU OS
over time independently from the host OS).
Unit tests cover the parser functionality (including many possible
invalid cases), in-memory representation as well as XML serialization
and deserialization.
Manual functional testing was performed with 2 DPUs and several other
NIC models which expose PCI(e) VPD. Testing have also been performed
for devices that do not have VPD or those that expose a VPD capability
but exhibit invalid behavior (I/O errors while reading a sysfs entry).
Per the existing guidelines, the implementation relies heavily on glib
for various purposes.
https://libvirt.org/glib-adoption.html
Dmitrii Shcherbakov (1):
Add a PCI/PCIe device VPD Capability
build-aux/syntax-check.mk | 4 +-
docs/drvnodedev.html.in | 46 ++
docs/formatnode.html.in | 24 +-
docs/schemas/nodedev.rng | 40 +
include/libvirt/libvirt-nodedev.h | 1 +
po/POTFILES.in | 1 +
src/conf/node_device_conf.c | 258 ++++++
src/conf/node_device_conf.h | 6 +-
src/conf/virnodedeviceobj.c | 7 +-
src/libvirt_private.syms | 17 +
src/node_device/node_device_driver.c | 2 +
src/node_device/node_device_udev.c | 2 +
src/util/meson.build | 1 +
src/util/virpci.c | 60 ++
src/util/virpci.h | 3 +
src/util/virpcivpd.c | 771 +++++++++++++++++
src/util/virpcivpd.h | 106 +++
src/util/virpcivpdpriv.h | 42 +
tests/meson.build | 1 +
.../pci_0000_42_00_0_vpd.xml | 33 +
.../pci_0000_42_00_0_vpd.xml | 1 +
tests/nodedevxml2xmltest.c | 1 +
tests/testutils.c | 51 ++
tests/testutils.h | 6 +
tests/virpcitest.c | 3 +
tests/virpcivpdtest.c | 777 ++++++++++++++++++
tools/virsh-nodedev.c | 3 +
27 files changed, 2262 insertions(+), 5 deletions(-)
create mode 100644 src/util/virpcivpd.c
create mode 100644 src/util/virpcivpd.h
create mode 100644 src/util/virpcivpdpriv.h
create mode 100644 tests/nodedevschemadata/pci_0000_42_00_0_vpd.xml
create mode 120000 tests/nodedevxml2xmlout/pci_0000_42_00_0_vpd.xml
create mode 100644 tests/virpcivpdtest.c
--
2.30.2
3 years
[PATCH 0/7] network define: add support for validation against schema
by Kristina Hanicova
Kristina Hanicova (7):
api: add public virNetworkDefineXMLFlags() and remote protocol
vbox_network: add flags to vboxNetworkDefineCreateXML()
src: add driver support for networkDefineXMLFlags()
api: add virNetworkDefineFlags
src & network_conf: add validation against schema in define
network: allow VIR_NETWORK_DEFINE_VALIDATE flag
virsh: add support for '--validate' option in define network
docs/manpages/virsh.rst | 4 ++-
include/libvirt/libvirt-network.h | 7 ++++++
src/conf/domain_conf.c | 2 +-
src/conf/network_conf.c | 15 ++++++-----
src/conf/network_conf.h | 3 ++-
src/driver-network.h | 6 +++++
src/esx/esx_network_driver.c | 16 ++++++++++--
src/libvirt-network.c | 41 +++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
src/network/bridge_driver.c | 22 +++++++++++++----
src/qemu/qemu_process.c | 2 +-
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 19 +++++++++++++-
src/remote_protocol-structs | 8 ++++++
src/test/test_driver.c | 20 ++++++++++++---
src/vbox/vbox_network.c | 18 +++++++++++---
tools/virsh-network.c | 13 +++++++++-
17 files changed, 171 insertions(+), 27 deletions(-)
--
2.31.1
3 years
[libvirt PATCH] qemu: simplify machine-type check for implicit floppy controller
by Ján Tomko
Q35 machine types 2.3 and older had an integrated floppy controller.
Support for these machine types was removed by QEMU commit
commit 86165b499edf8b03bb2d0e926d116c2f12a95bfe
q35: Remove old machine versions
git describe: v2.5.0-1530-g86165b499e contains: v2.6.0-rc0~76^2~4
In libvirt, we have bumped the minimum QEMU version to 2.11:
commit b4cbdbe90bbf85eaf687f532d5a52a11e664b781
qemu: Formally deprecate support for qemu < 2.11
git describe: v7.3.0-13-gb4cbdbe90b contains: v7.4.0-rc1~300
Since this QEMU version only supports Q35 machine versions 2.4+,
remove the code dealing with older ones.
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
src/qemu/qemu_domain.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9baa4b5d90..50a921c80d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8823,22 +8823,12 @@ static bool
qemuDomainMachineNeedsFDC(const char *machine,
const virArch arch)
{
- const char *p = STRSKIP(machine, "pc-q35-");
-
if (!ARCH_IS_X86(arch))
return false;
- if (!p)
+ if (!STRPREFIX(machine, "pc-q35-"))
return false;
- if (STRPREFIX(p, "1.") ||
- STREQ(p, "2.0") ||
- STREQ(p, "2.1") ||
- STREQ(p, "2.2") ||
- STREQ(p, "2.3")) {
- return false;
- }
-
return true;
}
--
2.31.1
3 years
[libvirt PATCHv2] API: discourage usage of non-ListAll APIs
by Ján Tomko
They require the caller to provide the maximum number
of array elements upfront, leading to either incomplete
results or violations of the zero-one-infinity rule.
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
src/libvirt-domain-snapshot.c | 12 ++++++++----
src/libvirt-domain.c | 8 ++++----
src/libvirt-interface.c | 6 ++++--
src/libvirt-network.c | 6 ++++--
src/libvirt-nodedev.c | 3 ++-
src/libvirt-nwfilter.c | 3 +++
src/libvirt-secret.c | 3 +++
src/libvirt-storage.c | 9 ++++++---
8 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/src/libvirt-domain-snapshot.c b/src/libvirt-domain-snapshot.c
index 15bf4d8634..4a79e95704 100644
--- a/src/libvirt-domain-snapshot.c
+++ b/src/libvirt-domain-snapshot.c
@@ -381,8 +381,10 @@ virDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
* snapshots were listed if the return is less than @nameslen. Likewise,
* you should be prepared for virDomainSnapshotLookupByName() to fail when
* converting a name from this call into a snapshot object, if another
- * connection deletes the snapshot in the meantime. For more control over
- * the results, see virDomainListAllSnapshots().
+ * connection deletes the snapshot in the meantime.
+ *
+ * The use of this function is discouraged. Instead, use
+ * virDomainListAllSnapshots().
*
* Returns the number of domain snapshots found or -1 in case of error.
* The caller is responsible to call free() for each member of the array.
@@ -582,8 +584,10 @@ virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags)
* snapshots were listed if the return is less than @nameslen. Likewise,
* you should be prepared for virDomainSnapshotLookupByName() to fail when
* converting a name from this call into a snapshot object, if another
- * connection deletes the snapshot in the meantime. For more control over
- * the results, see virDomainSnapshotListAllChildren().
+ * connection deletes the snapshot in the meantime.
+ *
+ * The use of this function is discouraged. Instead, use
+ * virDomainSnapshotListAllChildren().
*
* Returns the number of domain snapshots found or -1 in case of error.
* The caller is responsible to call free() for each member of the array.
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 3c4204e563..a8a386e839 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -41,8 +41,8 @@ VIR_LOG_INIT("libvirt.domain");
*
* Collect the list of active domains, and store their IDs in array @ids
*
- * For inactive domains, see virConnectListDefinedDomains(). For more
- * control over the results, see virConnectListAllDomains().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllDomains().
*
* Returns the number of domains found or -1 in case of error. Note that
* this command is inherently racy; a domain can be started between a
@@ -6526,8 +6526,8 @@ virConnectNumOfDefinedDomains(virConnectPtr conn)
* list the defined but inactive domains, stores the pointers to the names
* in @names
*
- * For active domains, see virConnectListDomains(). For more control over
- * the results, see virConnectListAllDomains().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllDomains().
*
* Returns the number of names provided in the array or -1 in case of error.
* Note that this command is inherently racy; a domain can be defined between
diff --git a/src/libvirt-interface.c b/src/libvirt-interface.c
index 2af86291d3..e4e8178ba9 100644
--- a/src/libvirt-interface.c
+++ b/src/libvirt-interface.c
@@ -150,7 +150,8 @@ virConnectNumOfInterfaces(virConnectPtr conn)
* Collect the list of active physical host interfaces,
* and store their names in @names
*
- * For more control over the results, see virConnectListAllInterfaces().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllInterfaces().
*
* Returns the number of interfaces found or -1 in case of error. Note that
* this command is inherently racy; a interface can be started between a call
@@ -227,7 +228,8 @@ virConnectNumOfDefinedInterfaces(virConnectPtr conn)
* Collect the list of defined (inactive) physical host interfaces,
* and store their names in @names.
*
- * For more control over the results, see virConnectListAllInterfaces().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllInterfaces().
*
* Returns the number of names provided in the array or -1 in case of error.
* Note that this command is inherently racy; a interface can be defined between
diff --git a/src/libvirt-network.c b/src/libvirt-network.c
index 145487d599..2cecbf6c12 100644
--- a/src/libvirt-network.c
+++ b/src/libvirt-network.c
@@ -159,7 +159,8 @@ virConnectNumOfNetworks(virConnectPtr conn)
*
* Collect the list of active networks, and store their names in @names
*
- * For more control over the results, see virConnectListAllNetworks().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllNetworks().
*
* Returns the number of networks found or -1 in case of error. Note that
* this command is inherently racy; a network can be started between a call
@@ -235,7 +236,8 @@ virConnectNumOfDefinedNetworks(virConnectPtr conn)
*
* list the inactive networks, stores the pointers to the names in @names
*
- * For more control over the results, see virConnectListAllNetworks().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllNetworks().
*
* Returns the number of names provided in the array or -1 in case of error.
* Note that this command is inherently racy; a network can be defined between
diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c
index e416c12534..ce0f30e958 100644
--- a/src/libvirt-nodedev.c
+++ b/src/libvirt-nodedev.c
@@ -128,7 +128,8 @@ virConnectListAllNodeDevices(virConnectPtr conn,
*
* Collect the list of node devices, and store their names in @names
*
- * For more control over the results, see virConnectListAllNodeDevices().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllNodeDevices().
*
* If the optional 'cap' argument is non-NULL, then the count
* will be restricted to devices with the specified capability
diff --git a/src/libvirt-nwfilter.c b/src/libvirt-nwfilter.c
index 7b857d1422..8d09270296 100644
--- a/src/libvirt-nwfilter.c
+++ b/src/libvirt-nwfilter.c
@@ -117,6 +117,9 @@ virConnectListAllNWFilters(virConnectPtr conn,
*
* Collect the list of network filters, and store their names in @names
*
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllNWFilters().
+ *
* Returns the number of network filters found or -1 in case of error
*/
int
diff --git a/src/libvirt-secret.c b/src/libvirt-secret.c
index d3626ed561..d2a3a4bd9d 100644
--- a/src/libvirt-secret.c
+++ b/src/libvirt-secret.c
@@ -156,6 +156,9 @@ virConnectListAllSecrets(virConnectPtr conn,
*
* List UUIDs of defined secrets, store pointers to names in uuids.
*
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllSecrets().
+ *
* Returns the number of UUIDs provided in the array, or -1 on failure.
*/
int
diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c
index 2a7cdca234..4badb13f04 100644
--- a/src/libvirt-storage.c
+++ b/src/libvirt-storage.c
@@ -179,7 +179,8 @@ virConnectNumOfStoragePools(virConnectPtr conn)
* If there are more than maxnames, the remaining names will be silently
* ignored.
*
- * For more control over the results, see virConnectListAllStoragePools().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllStoragePools().
*
* Returns the number of pools found or -1 in case of error. Note that
* this command is inherently racy; a pool can be started between a call to
@@ -259,7 +260,8 @@ virConnectNumOfDefinedStoragePools(virConnectPtr conn)
* If there are more than maxnames, the remaining names will be silently
* ignored.
*
- * For more control over the results, see virConnectListAllStoragePools().
+ * The use of this function is discouraged. Instead, use
+ * virConnectListAllStoragePools().
*
* Returns the number of names provided in the array or -1 in case of error.
* Note that this command is inherently racy; a pool can be defined between
@@ -1254,7 +1256,8 @@ virStoragePoolNumOfVolumes(virStoragePoolPtr pool)
* Fetch list of storage volume names, limiting to
* at most maxnames.
*
- * To list the volume objects directly, see virStoragePoolListAllVolumes().
+ * The use of this function is discouraged. Instead, use
+ * virStoragePoolListAllVolumes().
*
* Returns the number of names fetched, or -1 on error
*/
--
2.31.1
3 years
[PATCH V2] qemu: Set label on vhostuser net device when hotplugging
by Jim Fehlig
Attaching a newly created vhostuser port to a VM fails due to an
apparmor denial
internal error: unable to execute QEMU command 'chardev-add': Failed
to bind socket to /run/openvswitch/vhu838c4d29-c9: Permission denied
In the case of a net device type VIR_DOMAIN_NET_TYPE_VHOSTUSER, the
underlying chardev is not labeled in qemuDomainAttachNetDevice prior
to calling qemuMonitorAttachCharDev.
A simple fix would be to call qemuSecuritySetChardevLabel using the
embedded virDomainChrSourceDef in the virDomainNetDef vhostuser data,
but this incurs the risk of incorrectly restoring the label. E.g.
consider the DAC driver behavior with a vhostuser net device, which
uses a socket for the chardev backend. The DAC driver uses XATTRS to
store original labelling information, but XATTRS are not compatible
with sockets. Without the original labelling information, the socket
labels will be restored with root ownership, preventing other
less-privileged processes from connecting to the socket.
This patch avoids overloading chardev labelling with vhostuser net
devices by introducing virSecurityManager{Set,Restore}NetdevLabel,
which is currently only implemented for the apparmor driver. The
new APIs are then used to set and restore labels for the vhostuser
net devices.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
V2 of:
https://listman.redhat.com/archives/libvir-list/2021-August/msg00373.html
Changes since V1:
Introduce and use new APIs for labeling net devices
Don't perform labelling while executing monitor commands
Restore labels if hotplug fails
src/libvirt_private.syms | 2 ++
src/qemu/qemu_hotplug.c | 13 +++++++
src/qemu/qemu_security.c | 59 ++++++++++++++++++++++++++++++
src/qemu/qemu_security.h | 8 +++++
src/security/security_apparmor.c | 61 ++++++++++++++++++++++++++++++++
src/security/security_driver.h | 9 +++++
src/security/security_manager.c | 38 ++++++++++++++++++++
src/security/security_manager.h | 8 +++++
src/security/security_stack.c | 52 +++++++++++++++++++++++++++
9 files changed, 250 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fcb02c21b1..9d3e0421c0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1687,6 +1687,7 @@ virSecurityManagerRestoreHostdevLabel;
virSecurityManagerRestoreImageLabel;
virSecurityManagerRestoreInputLabel;
virSecurityManagerRestoreMemoryLabel;
+virSecurityManagerRestoreNetdevLabel;
virSecurityManagerRestoreSavedStateLabel;
virSecurityManagerRestoreTPMLabels;
virSecurityManagerSetAllLabel;
@@ -1698,6 +1699,7 @@ virSecurityManagerSetImageFDLabel;
virSecurityManagerSetImageLabel;
virSecurityManagerSetInputLabel;
virSecurityManagerSetMemoryLabel;
+virSecurityManagerSetNetdevLabel;
virSecurityManagerSetProcessLabel;
virSecurityManagerSetSavedStateLabel;
virSecurityManagerSetSocketLabel;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index c3c49fe080..77dbf69845 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1203,6 +1203,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
g_autofree char *netdev_name = NULL;
g_autoptr(virConnect) conn = NULL;
virErrorPtr save_err = NULL;
+ bool teardownlabel = false;
/* If appropriate, grab a physical device from the configured
* network's pool of devices, or resolve bridge device name
@@ -1343,6 +1344,9 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
&net->ifname) < 0)
goto cleanup;
+ if (qemuSecuritySetNetdevLabel(driver, vm, net) < 0)
+ goto cleanup;
+ teardownlabel = true;
break;
case VIR_DOMAIN_NET_TYPE_USER:
@@ -1559,6 +1563,10 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
qemuDomainNetDeviceVportRemove(net);
}
+ if (teardownlabel &&
+ qemuSecurityRestoreNetdevLabel(driver, vm, net) < 0)
+ VIR_WARN("Unable to restore network device labelling on hotplug fail");
+
/* we had potentially pre-added the device to the domain
* device lists, if so we need to remove it (from def->nets
* and/or def->hostdevs) on failure
@@ -4763,6 +4771,11 @@ qemuDomainRemoveNetDevice(virQEMUDriver *driver,
cfg->stateDir));
}
+ if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
+ if (qemuSecurityRestoreNetdevLabel(driver, vm, net) < 0)
+ VIR_WARN("Unable to restore security label on vhostuser char device");
+ }
+
qemuDomainNetDeviceVportRemove(net);
if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
index e582a66071..19d957dd4b 100644
--- a/src/qemu/qemu_security.c
+++ b/src/qemu/qemu_security.c
@@ -439,6 +439,65 @@ qemuSecurityRestoreChardevLabel(virQEMUDriver *driver,
return ret;
}
+int
+qemuSecuritySetNetdevLabel(virQEMUDriver *driver,
+ virDomainObj *vm,
+ virDomainNetDef *net)
+{
+ int ret = -1;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ pid_t pid = -1;
+
+ if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+ pid = vm->pid;
+
+ if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
+ goto cleanup;
+
+ if (virSecurityManagerSetNetdevLabel(driver->securityManager,
+ vm->def, net) < 0)
+ goto cleanup;
+
+ if (virSecurityManagerTransactionCommit(driver->securityManager,
+ pid, priv->rememberOwner) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virSecurityManagerTransactionAbort(driver->securityManager);
+ return ret;
+}
+
+
+int
+qemuSecurityRestoreNetdevLabel(virQEMUDriver *driver,
+ virDomainObj *vm,
+ virDomainNetDef *net)
+{
+ int ret = -1;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ pid_t pid = -1;
+
+ if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+ pid = vm->pid;
+
+ if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
+ goto cleanup;
+
+ if (virSecurityManagerRestoreNetdevLabel(driver->securityManager,
+ vm->def, net) < 0)
+ goto cleanup;
+
+ if (virSecurityManagerTransactionCommit(driver->securityManager,
+ pid, priv->rememberOwner) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virSecurityManagerTransactionAbort(driver->securityManager);
+ return ret;
+}
+
/*
* qemuSecurityStartVhostUserGPU:
diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h
index 4c3d81e4b5..8b26ea3f99 100644
--- a/src/qemu/qemu_security.h
+++ b/src/qemu/qemu_security.h
@@ -79,6 +79,14 @@ int qemuSecurityRestoreChardevLabel(virQEMUDriver *driver,
virDomainObj *vm,
virDomainChrDef *chr);
+int qemuSecuritySetNetdevLabel(virQEMUDriver *driver,
+ virDomainObj *vm,
+ virDomainNetDef *net);
+
+int qemuSecurityRestoreNetdevLabel(virQEMUDriver *driver,
+ virDomainObj *vm,
+ virDomainNetDef *net);
+
int qemuSecurityStartVhostUserGPU(virQEMUDriver *driver,
virDomainObj *vm,
virCommand *cmd,
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 84363015dc..d942ea5005 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -1053,6 +1053,64 @@ AppArmorRestoreChardevLabel(virSecurityManager *mgr,
return reload_profile(mgr, def, NULL, false);
}
+static int
+AppArmorSetNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *def,
+ virDomainNetDef *net)
+{
+ int ret = -1;
+ virSecurityLabelDef *secdef;
+ virDomainChrSourceDef *dev_source;
+ virDomainNetType actualType;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+ if (!secdef)
+ return 0;
+
+ actualType = virDomainNetGetActualType(net);
+ if (actualType != VIR_DOMAIN_NET_TYPE_VHOSTUSER)
+ return 0;
+
+ dev_source = net->data.vhostuser;
+ switch ((virDomainChrType)dev_source->type) {
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ ret = reload_profile(mgr, def, dev_source->data.file.path, true);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
+ case VIR_DOMAIN_CHR_TYPE_NULL:
+ case VIR_DOMAIN_CHR_TYPE_VC:
+ case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_UDP:
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+ case VIR_DOMAIN_CHR_TYPE_NMDM:
+ case VIR_DOMAIN_CHR_TYPE_LAST:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+AppArmorRestoreNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *def,
+ virDomainNetDef *net G_GNUC_UNUSED)
+{
+ virSecurityLabelDef *secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+ if (!secdef)
+ return 0;
+
+ return reload_profile(mgr, def, NULL, false);
+}
+
static int
AppArmorSetPathLabel(virSecurityManager *mgr,
virDomainDef *def,
@@ -1168,6 +1226,9 @@ virSecurityDriver virAppArmorSecurityDriver = {
.domainSetSecurityChardevLabel = AppArmorSetChardevLabel,
.domainRestoreSecurityChardevLabel = AppArmorRestoreChardevLabel,
+ .domainSetSecurityNetdevLabel = AppArmorSetNetdevLabel,
+ .domainRestoreSecurityNetdevLabel = AppArmorRestoreNetdevLabel,
+
.domainSetSecurityImageFDLabel = AppArmorSetFDLabel,
.domainSetSecurityTapFDLabel = AppArmorSetFDLabel,
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index 07f8def3d3..a1fc23be38 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -157,6 +157,12 @@ typedef int (*virSecurityDomainSetTPMLabels) (virSecurityManager *mgr,
virDomainDef *def);
typedef int (*virSecurityDomainRestoreTPMLabels) (virSecurityManager *mgr,
virDomainDef *def);
+typedef int (*virSecurityDomainSetNetdevLabel) (virSecurityManager *mgr,
+ virDomainDef *def,
+ virDomainNetDef *net);
+typedef int (*virSecurityDomainRestoreNetdevLabel) (virSecurityManager *mgr,
+ virDomainDef *def,
+ virDomainNetDef *net);
struct _virSecurityDriver {
@@ -224,6 +230,9 @@ struct _virSecurityDriver {
virSecurityDomainSetTPMLabels domainSetSecurityTPMLabels;
virSecurityDomainRestoreTPMLabels domainRestoreSecurityTPMLabels;
+
+ virSecurityDomainSetNetdevLabel domainSetSecurityNetdevLabel;
+ virSecurityDomainRestoreNetdevLabel domainRestoreSecurityNetdevLabel;
};
virSecurityDriver *virSecurityDriverLookup(const char *name,
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 9906c1691d..d8a03a19cb 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -1297,6 +1297,44 @@ virSecurityManagerRestoreTPMLabels(virSecurityManager *mgr,
}
+int
+virSecurityManagerSetNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *vm,
+ virDomainNetDef *net)
+{
+ int ret;
+
+ if (mgr->drv->domainSetSecurityNetdevLabel) {
+ virObjectLock(mgr);
+ ret = mgr->drv->domainSetSecurityNetdevLabel(mgr, vm, net);
+ virObjectUnlock(mgr);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+
+int
+virSecurityManagerRestoreNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *vm,
+ virDomainNetDef *net)
+{
+ int ret;
+
+ if (mgr->drv->domainRestoreSecurityNetdevLabel) {
+ virObjectLock(mgr);
+ ret = mgr->drv->domainRestoreSecurityNetdevLabel(mgr, vm, net);
+ virObjectUnlock(mgr);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+
static int
cmpstringp(const void *p1, const void *p2)
{
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 57047ccb13..59020b1475 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -220,6 +220,14 @@ int virSecurityManagerSetTPMLabels(virSecurityManager *mgr,
int virSecurityManagerRestoreTPMLabels(virSecurityManager *mgr,
virDomainDef *vm);
+int virSecurityManagerSetNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *vm,
+ virDomainNetDef *net);
+
+int virSecurityManagerRestoreNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *vm,
+ virDomainNetDef *net);
+
typedef struct _virSecurityManagerMetadataLockState virSecurityManagerMetadataLockState;
struct _virSecurityManagerMetadataLockState {
size_t nfds; /* Captures size of both @fds and @paths */
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index f7a9ed1e33..3c2239910a 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -963,6 +963,55 @@ virSecurityStackRestoreTPMLabels(virSecurityManager *mgr,
}
+static int
+virSecurityStackDomainSetNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *def,
+ virDomainNetDef *net)
+{
+ virSecurityStackData *priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItem *item = priv->itemsHead;
+
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetNetdevLabel(item->securityManager, def, net) < 0)
+ goto rollback;
+ }
+
+ return 0;
+
+ rollback:
+ for (item = item->prev; item; item = item->prev) {
+ if (virSecurityManagerRestoreNetdevLabel(item->securityManager,
+ def, net) < 0) {
+ VIR_WARN("Unable to restore netdev label after failed set label "
+ "call virDriver=%s driver=%s domain=%s",
+ virSecurityManagerGetVirtDriver(mgr),
+ virSecurityManagerGetDriver(item->securityManager),
+ def->name);
+ }
+ }
+ return -1;
+}
+
+
+static int
+virSecurityStackDomainRestoreNetdevLabel(virSecurityManager *mgr,
+ virDomainDef *def,
+ virDomainNetDef *net)
+{
+ virSecurityStackData *priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItem *item = priv->itemsHead;
+ int rc = 0;
+
+ for (; item; item = item->next) {
+ if (virSecurityManagerRestoreNetdevLabel(item->securityManager,
+ def, net) < 0)
+ rc = -1;
+ }
+
+ return rc;
+}
+
+
virSecurityDriver virSecurityDriverStack = {
.privateDataLen = sizeof(virSecurityStackData),
.name = "stack",
@@ -1028,4 +1077,7 @@ virSecurityDriver virSecurityDriverStack = {
.domainSetSecurityTPMLabels = virSecurityStackSetTPMLabels,
.domainRestoreSecurityTPMLabels = virSecurityStackRestoreTPMLabels,
+
+ .domainSetSecurityNetdevLabel = virSecurityStackDomainSetNetdevLabel,
+ .domainRestoreSecurityNetdevLabel = virSecurityStackDomainRestoreNetdevLabel,
};
--
2.32.0
3 years
[PATCH 0/2] Support VM core dump to block device
by Simon Rowe
When the destination of a VM core dump is a block device (e.g. NBD)
avoid file operations that are unnecessary.
Simon Rowe (2):
iohelper: skip lseek() and ftruncate() on block devices
qemu: never unlink() the core dump output file
src/qemu/qemu_driver.c | 2 --
src/util/iohelper.c | 10 ++++++++--
2 files changed, 8 insertions(+), 4 deletions(-)
--
2.22.3
3 years