[libvirt] [PATCH] fix libvirtd memory leak when client was killed by user at eventRegister sense
by xinhua.Cao
【DTS/AR】:DTS2017102200357
【description】:当客户端注册libvirt事件后,将客户端进程Kill,libvirtd服务端会有内存泄露。
Change-Id: I7eeffb4f1ba46038cd41fd26e6725ad2943229a8
---
daemon/remote.c | 52 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index f67370f..4b8de85 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1727,25 +1727,14 @@ void remoteRelayConnectionClosedEvent(virConnectPtr conn ATTRIBUTE_UNUSED, int r
VIR_WARN("unexpected %s event deregister failure", name); \
} \
VIR_FREE(eventCallbacks); \
+ neventCallbacks = 0; \
} while (0);
-/*
- * You must hold lock for at least the client
- * We don't free stuff here, merely disconnect the client's
- * network socket & resources.
- * We keep the libvirt connection open until any async
- * jobs have finished, then clean it up elsewhere
- */
-void remoteClientFreeFunc(void *data)
+static void
+remoteFreePrivCallbacks(void *data)
{
struct daemonClientPrivate *priv = data;
-
- /* Deregister event delivery callback */
- if (priv->conn) {
- virIdentityPtr sysident = virIdentityGetSystem();
-
- virIdentitySetCurrent(sysident);
-
+ if (priv && priv->conn) {
DEREG_CB(priv->conn, priv->domainEventCallbacks,
priv->ndomainEventCallbacks,
virConnectDomainEventDeregisterAny, "domain");
@@ -1764,6 +1753,27 @@ void remoteClientFreeFunc(void *data)
DEREG_CB(priv->conn, priv->qemuEventCallbacks,
priv->nqemuEventCallbacks,
virConnectDomainQemuMonitorEventDeregister, "qemu monitor");
+ }
+}
+#undef DEREG_CB
+
+/*
+ * You must hold lock for at least the client
+ * We don't free stuff here, merely disconnect the client's
+ * network socket & resources.
+ * We keep the libvirt connection open until any async
+ * jobs have finished, then clean it up elsewhere
+ */
+void remoteClientFreeFunc(void *data)
+{
+ struct daemonClientPrivate *priv = data;
+
+ /* Deregister event delivery callback */
+ if (priv) {
+ virIdentityPtr sysident = virIdentityGetSystem();
+
+ virIdentitySetCurrent(sysident);
+ remoteFreePrivCallbacks(priv);
if (priv->closeRegistered) {
if (virConnectUnregisterCloseCallback(priv->conn,
@@ -1775,19 +1785,21 @@ void remoteClientFreeFunc(void *data)
virIdentitySetCurrent(NULL);
virObjectUnref(sysident);
- }
- VIR_FREE(priv->hmacSalt);
- VIR_FREE(priv);
+ VIR_FREE(priv->hmacSalt);
+ VIR_FREE(priv);
+ }
}
-#undef DEREG_CB
static void remoteClientCloseFunc(virNetServerClientPtr client)
{
struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
- daemonRemoveAllClientStreams(priv->streams);
+ if (priv) {
+ daemonRemoveAllClientStreams(priv->streams);
+ remoteFreePrivCallbacks(priv);
+ }
}
--
2.8.3
7 years
[libvirt] [PATCH dbus] Run system instance as an unprivileged user account
by Daniel P. Berrange
There is no reason for the libvirt-dbus daemon to require root privileges. All
it actually needs is ability to connect to libvirtd, which can be achieved by
dropping in a polkit configuration file
Now a libvirt connection to the system bus gives you privileges equivalent to
root, so this doesn't really improve security on its own. It relies on there
being a dbus policy that prevents users from issuing elevated APIs.
For example, a DBus policy could allow non-root users to list VMs on the
system bus and get their status (aka virsh list equiv). In this case, the
security isolation does give some benefit.
Security can be further improved if the admin uses the libvirt polkit file to
restrict what libvirt-dbus is permitted to do.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
configure.ac | 5 +++++
data/Makefile.am | 33 +++++++++++++++++++++++++++------
data/system/libvirt-dbus.rules.in | 8 ++++++++
data/system/org.libvirt.conf | 2 +-
data/system/org.libvirt.conf.in | 15 +++++++++++++++
data/system/org.libvirt.service.in | 2 +-
libvirt-dbus.spec.in | 9 +++++++++
src/main.c | 8 ++++++++
8 files changed, 74 insertions(+), 8 deletions(-)
create mode 100644 data/system/libvirt-dbus.rules.in
create mode 100644 data/system/org.libvirt.conf.in
diff --git a/configure.ac b/configure.ac
index 228ea11..aef3d37 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,11 @@ else
fi
AC_SUBST(DBUS_SYSTEM_POLICIES_DIR)
+LIBVIRT_ARG_WITH([SYSTEM_USER], [username to run system instance as],
+ ['libvirtdbus'])
+SYSTEM_USER=$with_system_user
+AC_SUBST([SYSTEM_USER])
+
AC_OUTPUT(Makefile
data/Makefile
src/Makefile
diff --git a/data/Makefile.am b/data/Makefile.am
index 58e855f..3f27b02 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -9,18 +9,28 @@ system_servicedir = $(DBUS_SYSTEM_SERVICES_DIR)
system_service_DATA = $(system_service_in_files:.service.in=.service)
system_policy_files = \
- system/org.libvirt.conf
+ system/org.libvirt.conf.in
system_policydir = $(DBUS_SYSTEM_POLICIES_DIR)
-system_policy_DATA = $(system_policy_files)
+system_policy_DATA = $(system_policy_files:.conf.in=.conf)
+
+polkit_files = \
+ system/libvirt-dbus.rules.in
+polkit_policydir = $(sysconfdir)/polkit-1/rules.d
+polkit_policy_DATA = $(polkit_files:.rules.in=.rules)
EXTRA_DIST = \
$(service_in_files) \
$(system_service_in_files) \
- $(system_policy_files)
+ $(system_policy_files) \
+ $(polkit_files) \
+ $(NULL)
CLEANFILES = \
$(service_DATA) \
- $(system_service_DATA)
+ $(system_service_DATA) \
+ $(system_policy_DATA) \
+ $(polkit_DATA) \
+ $(NULL)
session/org.libvirt.service: session/org.libvirt.service.in
$(AM_V_GEN)$(MKDIR_P) session && \
@@ -29,5 +39,16 @@ session/org.libvirt.service: session/org.libvirt.service.in
system/org.libvirt.service: system/org.libvirt.service.in
$(AM_V_GEN)$(MKDIR_P) system && \
- sed -e 's|[@]bindir[@]|$(bindir)|g' < $< > $@-t && \
- mv $@-t $@
+ sed -e 's|[@]bindir[@]|$(bindir)|g' \
+ -e 's|[@]SYSTEM_USER[@]|$(SYSTEM_USER)|' \
+ < $< > $@-t && mv $@-t $@
+
+system/org.libvirt.conf: system/org.libvirt.conf.in
+ $(AM_V_GEN)$(MKDIR_P) system && \
+ sed -e 's|[@]SYSTEM_USER[@]|$(SYSTEM_USER)|' \
+ < $< > $@-t && mv $@-t $@
+
+system/libvirt-dbus.rules: system/libvirt-dbus.rules.in
+ $(AM_V_GEN)$(MKDIR_P) system && \
+ sed -e 's|[@]SYSTEM_USER[@]|$(SYSTEM_USER)|' \
+ < $< > $@-t && mv $@-t $@
diff --git a/data/system/libvirt-dbus.rules.in b/data/system/libvirt-dbus.rules.in
new file mode 100644
index 0000000..4eb4ee1
--- /dev/null
+++ b/data/system/libvirt-dbus.rules.in
@@ -0,0 +1,8 @@
+// Allow libvirt-dbus running in dedicated account to use libvirt
+
+polkit.addRule(function(action, subject) {
+ if (action.id == "org.libvirt.unix.manage" &&
+ subject.user == "@SYSTEM_USER@") {
+ return polkit.Result.YES;
+ }
+});
diff --git a/data/system/org.libvirt.conf b/data/system/org.libvirt.conf
index 5cbc732..2b11717 100644
--- a/data/system/org.libvirt.conf
+++ b/data/system/org.libvirt.conf
@@ -4,7 +4,7 @@
<busconfig>
- <policy user="root">
+ <policy user="libvirtdbus">
<allow own="org.libvirt"/>
<allow send_destination="org.libvirt"/>
</policy>
diff --git a/data/system/org.libvirt.conf.in b/data/system/org.libvirt.conf.in
new file mode 100644
index 0000000..fe61b70
--- /dev/null
+++ b/data/system/org.libvirt.conf.in
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<busconfig>
+
+ <policy user="@SYSTEM_USER@">
+ <allow own="org.libvirt"/>
+ </policy>
+
+ <policy user="root">
+ <allow send_destination="org.libvirt"/>
+ </policy>
+
+</busconfig>
diff --git a/data/system/org.libvirt.service.in b/data/system/org.libvirt.service.in
index 08d32a2..0d3abdd 100644
--- a/data/system/org.libvirt.service.in
+++ b/data/system/org.libvirt.service.in
@@ -1,4 +1,4 @@
[D-BUS Service]
Name=org.libvirt
Exec=@bindir@/libvirt-dbus --system
-User=root
+User=@SYSTEM_USER@
diff --git a/libvirt-dbus.spec.in b/libvirt-dbus.spec.in
index 5be4c22..572300f 100644
--- a/libvirt-dbus.spec.in
+++ b/libvirt-dbus.spec.in
@@ -19,6 +19,7 @@ BuildRequires: systemd-devel >= %{systemd_version}
Requires: libvirt-libs >= %{libvirt_version}
Requires: systemd-libs >= %{systemd_version}
+Requires(pre): shadow-utils
%description
This package provides integration between libvirt and the DBus
@@ -37,9 +38,17 @@ rm -rf $RPM_BUILD_ROOT
%clean
rm -rf $RPM_BUILD_ROOT
+%pre
+getent group libvirtdbus >/dev/null || groupadd -r libvirtdbus
+getent passwd libvirtdbus >/dev/null || \
+ useradd -r -g libvirtdbus -d / -s /sbin/nologin \
+ -c "Libvirt DBus bridge" libvirtdbus
+exit 0
+
%files
%defattr(-,root,root,-)
%doc README COPYING AUTHORS NEWS
+%{_sysconfdir}/polkit-1/rules.d/libvirt-dbus.rules
%{_bindir}/libvirt-dbus
%{_datadir}/dbus-1/services/org.libvirt.service
%{_datadir}/dbus-1/system-services/org.libvirt.service
diff --git a/src/main.c b/src/main.c
index a6a0212..225fb46 100644
--- a/src/main.c
+++ b/src/main.c
@@ -143,6 +143,14 @@ main(int argc, char *argv[])
}
}
+ if (uri == NULL) {
+ if (system_bus) {
+ uri = "qemu:///system";
+ } else {
+ uri = "qemu:///session";
+ }
+ }
+
sigemptyset(&mask);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGINT);
--
2.13.6
7 years
[libvirt] [PATCH/QEMU] s390x/kvm: use cpu_model_available for guarded storage on compat machines
by Christian Borntraeger
Starting a guest with
<os>
<type arch='s390x' machine='s390-ccw-virtio-2.9'>hvm</type>
</os>
<cpu mode='host-model'/>
on an IBM z14 results in
"qemu-system-s390x: Some features requested in the CPU model are not
available in the configuration: gs"
This is because guarded storage is fenced for compat machines that did not have
guarded storage support, but libvirt expands the cpu model according to the
latest available machine.
While this prevents future migration abort (by not starting the guest at all),
not being able to start a "host-model" guest is very much unexpected. As it
turns out, even if we would modify libvirt to not expand the cpu model to
contain "gs" for compat machines, it cannot guarantee that a migration will
succeed. For example if the kernel changes its features (or the user has
nested=1 on one host but not on the other) the migration will fail
nevertheless. So instead of fencing "gs" for machines <= 2.9 lets allow it for
all machine types that support the CPU model. This will make "host-model"
runnable all the time, while relying on the CPU model to reject invalid
migration attempts.
Suggested-by: David Hildenbrand <david(a)redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger(a)de.ibm.com>
---
hw/s390x/s390-virtio-ccw.c | 8 --------
include/hw/s390x/s390-virtio-ccw.h | 3 ---
target/s390x/kvm.c | 2 +-
3 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index fabe4a6..ae5b01a 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -414,7 +414,6 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
s390mc->ri_allowed = true;
s390mc->cpu_model_allowed = true;
s390mc->css_migration_enabled = true;
- s390mc->gs_allowed = true;
mc->init = ccw_init;
mc->reset = s390_machine_reset;
mc->hot_add_cpu = s390_hot_add_cpu;
@@ -495,12 +494,6 @@ bool cpu_model_allowed(void)
return get_machine_class()->cpu_model_allowed;
}
-bool gs_allowed(void)
-{
- /* for "none" machine this results in true */
- return get_machine_class()->gs_allowed;
-}
-
static char *machine_get_loadparm(Object *obj, Error **errp)
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
@@ -740,7 +733,6 @@ static void ccw_machine_2_9_class_options(MachineClass *mc)
{
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
- s390mc->gs_allowed = false;
ccw_machine_2_10_class_options(mc);
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_9);
s390mc->css_migration_enabled = false;
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index a9a90c2..ac896e3 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -40,15 +40,12 @@ typedef struct S390CcwMachineClass {
bool ri_allowed;
bool cpu_model_allowed;
bool css_migration_enabled;
- bool gs_allowed;
} S390CcwMachineClass;
/* runtime-instrumentation allowed by the machine */
bool ri_allowed(void);
/* cpu model allowed by the machine */
bool cpu_model_allowed(void);
-/* guarded-storage allowed by the machine */
-bool gs_allowed(void);
/**
* Returns true if (vmstate based) migration of the channel subsystem
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 4c85ed8..020a7ea 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -363,7 +363,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_ri = 1;
}
}
- if (gs_allowed()) {
+ if (cpu_model_allowed()) {
if (kvm_vm_enable_cap(s, KVM_CAP_S390_GS, 0) == 0) {
cap_gs = 1;
}
--
2.9.4
7 years
[libvirt] [PATCH dbus 0/5] Harden the build process
by Daniel P. Berrange
This hardens the build process by turning on all possible compiler flags and
enabling features like relro and PIE.
Daniel P. Berrange (5):
util: don't inline virtDBusUtilVirDomainListFreep
src: annotate parameters that are unused in functions
build: turn on all practical compiler warning flags
Enable full RELRO mode
Build all binaries with PIE
.gitignore | 1 +
Makefile.am | 2 +
configure.ac | 5 +
m4/manywarnings.m4 | 276 ++++++++++++++++++++++++++++++++++++++++++++
m4/virt-arg.m4 | 154 ++++++++++++++++++++++++
m4/virt-compile-pie.m4 | 35 ++++++
m4/virt-compile-warnings.m4 | 225 ++++++++++++++++++++++++++++++++++++
m4/virt-linker-relro.m4 | 35 ++++++
m4/warnings.m4 | 79 +++++++++++++
src/Makefile.am | 10 +-
src/domain.c | 78 ++++++-------
src/events.c | 12 +-
src/main.c | 12 +-
src/manager.c | 4 +-
src/util.c | 14 +++
src/util.h | 17 +--
16 files changed, 891 insertions(+), 68 deletions(-)
create mode 100644 m4/manywarnings.m4
create mode 100644 m4/virt-arg.m4
create mode 100644 m4/virt-compile-pie.m4
create mode 100644 m4/virt-compile-warnings.m4
create mode 100644 m4/virt-linker-relro.m4
create mode 100644 m4/warnings.m4
--
2.13.6
7 years
[libvirt] [jenkins-ci PATCH v2 0/4] Expand test matrix, plus cleanups
by Andrea Bolognani
Changes from [v1]:
* don't move project-specific environment variables to the default
check_env.
[v1] https://www.redhat.com/archives/libvir-list/2017-October/msg01256.html
Andrea Bolognani (4):
README: Update, expand and convert to Markdown
jobs: Move check_env defaults
projects: Set $OSINFO_SYSTEM_DIR in check_env
projects: Expand test matrix
README | 34 ------------------------------
README.markdown | 48 +++++++++++++++++++++++++++++++++++++++++++
jobs/autotools.yaml | 1 -
jobs/defaults.yaml | 1 +
jobs/go.yaml | 1 -
projects/libosinfo.yaml | 11 +++++-----
projects/libvirt-glib.yaml | 4 ++++
projects/libvirt-go-xml.yaml | 4 ++++
projects/libvirt-go.yaml | 4 ++++
projects/libvirt-perl.yaml | 5 +++++
projects/libvirt-python.yaml | 4 ++++
projects/libvirt-sandbox.yaml | 2 ++
projects/libvirt-tck.yaml | 4 ++++
projects/libvirt.yaml | 16 +++++++--------
projects/osinfo-db-tools.yaml | 4 ++++
projects/osinfo-db.yaml | 3 +++
projects/virt-manager.yaml | 4 ++++
projects/virt-viewer.yaml | 4 ++++
18 files changed, 104 insertions(+), 50 deletions(-)
delete mode 100644 README
create mode 100644 README.markdown
--
2.13.6
7 years
[libvirt] [PATCH] qemuhotplugtest: Test user supplied alias
by Michal Privoznik
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tests/qemuhotplugtest.c | 6 +++
.../qemuhotplug-watchdog-user-alias-full.xml | 4 ++
.../qemuhotplug-watchdog-user-alias.xml | 3 ++
.../qemuhotplug-base-live+watchdog-user-alias.xml | 56 ++++++++++++++++++++++
4 files changed, 69 insertions(+)
create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias-full.xml
create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias.xml
create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+watchdog-user-alias.xml
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
index 8d77c0056..bdde7e45f 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -828,6 +828,12 @@ mymain(void)
DO_TEST_DETACH("base-live", "watchdog-full", false, false,
"device_del", QMP_OK);
+ DO_TEST_ATTACH("base-live", "watchdog-user-alias", false, true,
+ "watchdog-set-action", QMP_OK,
+ "device_add", QMP_OK);
+ DO_TEST_DETACH("base-live", "watchdog-user-alias-full", false, false,
+ "device_del", QMP_OK);
+
#define DO_TEST_CPU_GROUP(prefix, vcpus, modernhp, expectfail) \
do { \
cpudata.test = prefix; \
diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias-full.xml b/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias-full.xml
new file mode 100644
index 000000000..d34f24554
--- /dev/null
+++ b/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias-full.xml
@@ -0,0 +1,4 @@
+<watchdog model='i6300esb' action='poweroff'>
+ <alias name='ua-UserWatchdog'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+</watchdog>
diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias.xml b/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias.xml
new file mode 100644
index 000000000..0caff99e4
--- /dev/null
+++ b/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-user-alias.xml
@@ -0,0 +1,3 @@
+<watchdog model='i6300esb' action='poweroff'>
+ <alias name="ua-UserWatchdog"/>
+</watchdog>
diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+watchdog-user-alias.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+watchdog-user-alias.xml
new file mode 100644
index 000000000..27aff2b6f
--- /dev/null
+++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+watchdog-user-alias.xml
@@ -0,0 +1,56 @@
+<domain type='kvm' id='7'>
+ <name>hotplug</name>
+ <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0'>
+ <alias name='usb'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='ide' index='0'>
+ <alias name='ide'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='scsi' index='0' model='virtio-scsi'>
+ <alias name='scsi0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'>
+ <alias name='pci'/>
+ </controller>
+ <controller type='virtio-serial' index='0'>
+ <alias name='virtio-serial0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </controller>
+ <input type='mouse' bus='ps2'>
+ <alias name='input0'/>
+ </input>
+ <input type='keyboard' bus='ps2'>
+ <alias name='input1'/>
+ </input>
+ <watchdog model='i6300esb' action='poweroff'>
+ <alias name='ua-UserWatchdog'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+ </watchdog>
+ <memballoon model='none'>
+ <alias name='balloon0'/>
+ </memballoon>
+ </devices>
+ <seclabel type='none' model='none'/>
+</domain>
--
2.13.6
7 years
[libvirt] [PATCH v3 RESEND] vhost-user: add support reconnect for vhost-user ports
by ZhiPeng Lu
For vhost-user ports, Open vSwitch acts as the server and QEMU the client.
When OVS crashes or restarts, the QEMU process should be reconnected to
OVS.
Signed-off-by: ZhiPeng Lu <lu.zhipeng(a)zte.com.cn>
---
docs/schemas/domaincommon.rng | 26 ++++++++------
src/conf/domain_conf.c | 40 ++++++++++++++++++----
src/conf/domain_conf.h | 10 +++---
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_monitor_json.c | 2 +-
.../qemuxml2argv-net-vhostuser-multiq.args | 4 +--
.../qemuxml2argv-net-vhostuser-multiq.xml | 8 +++--
8 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 76852ab..3f4ed82 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2327,6 +2327,18 @@
</attribute>
</optional>
</define>
+ <define name="reconnect">
+ <element name="reconnect">
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ <optional>
+ <attribute name="timeout">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ </element>
+ </define>
<!--
An interface description can either be of type bridge in which case
@@ -2388,6 +2400,9 @@
<value>client</value>
</choice>
</attribute>
+ <optional>
+ <ref name="reconnect"/>
+ </optional>
<empty/>
</element>
<ref name="interface-options"/>
@@ -3636,16 +3651,7 @@
</attribute>
</optional>
<optional>
- <element name="reconnect">
- <attribute name="enabled">
- <ref name="virYesNo"/>
- </attribute>
- <optional>
- <attribute name="timeout">
- <ref name="unsignedInt"/>
- </attribute>
- </optional>
- </element>
+ <ref name="reconnect"/>
</optional>
<zeroOrMore>
<ref name='devSeclabel'/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cc5e79b..b7fc3a5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -83,6 +83,13 @@ struct _virDomainXMLOption {
/* Private data for save image stored in snapshot XML */
virSaveCookieCallbacks saveCookie;
};
+static int
+virDomainDeviceSourceReconnectDefParseXML(virDomainDeviceSourceReconnectDefPtr def,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt);
+static void
+virDomainDeviceSourceReconnectDefFormat(virBufferPtr buf,
+ virDomainDeviceSourceReconnectDefPtr def);
#define VIR_DOMAIN_DEF_FORMAT_COMMON_FLAGS \
(VIR_DOMAIN_DEF_FORMAT_SECURE | \
@@ -10245,6 +10252,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
virNWFilterHashTablePtr filterparams = NULL;
virDomainActualNetDefPtr actual = NULL;
xmlNodePtr oldnode = ctxt->node;
+ virDomainDeviceSourceReconnectDef reconnect = {0};
int rv, val;
if (VIR_ALLOC(def) < 0)
@@ -10331,6 +10339,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
vhostuser_type = virXMLPropString(cur, "type");
vhostuser_path = virXMLPropString(cur, "path");
vhostuser_mode = virXMLPropString(cur, "mode");
+ if (virDomainDeviceSourceReconnectDefParseXML(&reconnect, cur, ctxt) < 0)
+ goto error;
} else if (!def->virtPortProfile
&& virXMLNodeNameEqual(cur, "virtualport")) {
if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -10552,8 +10562,17 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (STREQ(vhostuser_mode, "server")) {
def->data.vhostuser->data.nix.listen = true;
+ if (reconnect.enabled != VIR_TRISTATE_BOOL_ABSENT) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("'reconnect' attribute unsupported "
+ "'server' mode for <interface type='vhostuser'>"));
+ goto error;
+ }
} else if (STREQ(vhostuser_mode, "client")) {
def->data.vhostuser->data.nix.listen = false;
+ def->data.vhostuser->data.nix.reconnect.enabled = reconnect.enabled;
+ def->data.vhostuser->data.nix.reconnect.timeout = reconnect.timeout;
+ reconnect.enabled = VIR_TRISTATE_BOOL_ABSENT;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Wrong <source> 'mode' attribute "
@@ -11216,7 +11235,7 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
}
static int
-virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def,
+virDomainDeviceSourceReconnectDefParseXML(virDomainDeviceSourceReconnectDefPtr def,
xmlNodePtr node,
xmlXPathContextPtr ctxt)
{
@@ -11338,7 +11357,7 @@ virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
VIR_FREE(tmp);
}
- if (virDomainChrSourceReconnectDefParseXML(&def->data.tcp.reconnect,
+ if (virDomainDeviceSourceReconnectDefParseXML(&def->data.tcp.reconnect,
source,
ctxt) < 0) {
goto error;
@@ -11389,7 +11408,7 @@ virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def,
def->data.nix.listen = mode == VIR_DOMAIN_CHR_SOURCE_MODE_BIND;
def->data.nix.path = virXMLPropString(source, "path");
- if (virDomainChrSourceReconnectDefParseXML(&def->data.nix.reconnect,
+ if (virDomainDeviceSourceReconnectDefParseXML(&def->data.nix.reconnect,
source,
ctxt) < 0) {
return -1;
@@ -22984,6 +23003,13 @@ virDomainNetDefFormat(virBufferPtr buf,
def->data.vhostuser->data.nix.listen ?
"server" : "client");
sourceLines++;
+ if (def->data.vhostuser->data.nix.reconnect.enabled != VIR_TRISTATE_BOOL_ABSENT) {
+ virBufferAddLit(buf, ">\n");
+ sourceLines++;
+ virBufferAdjustIndent(buf, 2);
+ virDomainDeviceSourceReconnectDefFormat(buf, &def->data.vhostuser->data.nix.reconnect);
+ virBufferAdjustIndent(buf, -2);
+ }
}
break;
@@ -23218,8 +23244,8 @@ virDomainChrAttrsDefFormat(virBufferPtr buf,
static void
-virDomainChrSourceReconnectDefFormat(virBufferPtr buf,
- virDomainChrSourceReconnectDefPtr def)
+virDomainDeviceSourceReconnectDefFormat(virBufferPtr buf,
+ virDomainDeviceSourceReconnectDefPtr def)
{
if (def->enabled == VIR_TRISTATE_BOOL_ABSENT)
return;
@@ -23314,7 +23340,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'",
def->data.tcp.tlsFromConfig);
- virDomainChrSourceReconnectDefFormat(&childBuf,
+ virDomainDeviceSourceReconnectDefFormat(&childBuf,
&def->data.tcp.reconnect);
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
@@ -23333,7 +23359,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels,
def->seclabels, flags);
- virDomainChrSourceReconnectDefFormat(&childBuf,
+ virDomainDeviceSourceReconnectDefFormat(&childBuf,
&def->data.nix.reconnect);
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bb3b6f0..909f60d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1138,12 +1138,12 @@ typedef enum {
} virDomainChrSpicevmcName;
-struct _virDomainChrSourceReconnectDef {
+struct _virDomainDeviceSourceReconnectDef {
virTristateBool enabled;
unsigned int timeout;
};
-typedef struct _virDomainChrSourceReconnectDef virDomainChrSourceReconnectDef;
-typedef virDomainChrSourceReconnectDef *virDomainChrSourceReconnectDefPtr;
+typedef struct _virDomainDeviceSourceReconnectDef virDomainDeviceSourceReconnectDef;
+typedef virDomainDeviceSourceReconnectDef *virDomainDeviceSourceReconnectDefPtr;
/* The host side information for a character device. */
@@ -1168,7 +1168,7 @@ struct _virDomainChrSourceDef {
bool tlscreds;
int haveTLS; /* enum virTristateBool */
bool tlsFromConfig;
- virDomainChrSourceReconnectDef reconnect;
+ virDomainDeviceSourceReconnectDef reconnect;
} tcp;
struct {
char *bindHost;
@@ -1179,7 +1179,7 @@ struct _virDomainChrSourceDef {
struct {
char *path;
bool listen;
- virDomainChrSourceReconnectDef reconnect;
+ virDomainDeviceSourceReconnectDef reconnect;
} nix;
int spicevmc;
struct {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9b3e3fc..4640ce8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5094,7 +5094,7 @@ qemuBuildChrChardevFileStr(virLogManagerPtr logManager,
static void
qemuBuildChrChardevReconnectStr(virBufferPtr buf,
- const virDomainChrSourceReconnectDef *def)
+ const virDomainDeviceSourceReconnectDef *def)
{
if (def->enabled == VIR_TRISTATE_BOOL_YES) {
virBufferAsprintf(buf, ",reconnect=%u", def->timeout);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 50b536e..4ea0727 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3244,7 +3244,7 @@ qemuDomainNetSupportsCoalesce(virDomainNetType type)
static int
-qemuDomainChrSourceReconnectDefValidate(const virDomainChrSourceReconnectDef *def)
+qemuDomainChrSourceReconnectDefValidate(const virDomainDeviceSourceReconnectDef *def)
{
if (def->enabled == VIR_TRISTATE_BOOL_YES &&
def->timeout == 0) {
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 63b8559..b3d572e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6443,7 +6443,7 @@ int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon,
static int
qemuMonitorJSONBuildChrChardevReconnect(virJSONValuePtr object,
- const virDomainChrSourceReconnectDef *def)
+ const virDomainDeviceSourceReconnectDef *def)
{
if (def->enabled != VIR_TRISTATE_BOOL_YES)
return 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
index b69ebd8..0b08f44 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
@@ -25,14 +25,14 @@ server,nowait \
-netdev vhost-user,chardev=charnet0,id=hostnet0 \
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:ee:96:6b,bus=pci.0,\
addr=0x3 \
--chardev socket,id=charnet1,path=/tmp/vhost1.sock \
+-chardev socket,id=charnet1,path=/tmp/vhost1.sock,reconnect=10 \
-netdev vhost-user,chardev=charnet1,id=hostnet1 \
-device virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:ee:96:6c,bus=pci.0,\
addr=0x4 \
-netdev socket,listen=:2015,id=hostnet2 \
-device rtl8139,netdev=hostnet2,id=net2,mac=52:54:00:95:db:c0,bus=pci.0,\
addr=0x5 \
--chardev socket,id=charnet3,path=/tmp/vhost2.sock \
+-chardev socket,id=charnet3,path=/tmp/vhost2.sock,reconnect=0 \
-netdev vhost-user,chardev=charnet3,queues=4,id=hostnet3 \
-device virtio-net-pci,mq=on,vectors=10,netdev=hostnet3,id=net3,\
mac=52:54:00:ee:96:6d,bus=pci.0,addr=0x6
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
index d5c42fe..2fadb1c 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
@@ -30,7 +30,9 @@
</interface>
<interface type='vhostuser'>
<mac address='52:54:00:ee:96:6c'/>
- <source type='unix' path='/tmp/vhost1.sock' mode='client'/>
+ <source type='unix' path='/tmp/vhost1.sock' mode='client'>
+ <reconnect enabled='yes' timeout='10'/>
+ </source>
<model type='virtio'/>
</interface>
<interface type='server'>
@@ -40,7 +42,9 @@
</interface>
<interface type='vhostuser'>
<mac address='52:54:00:ee:96:6d'/>
- <source type='unix' path='/tmp/vhost2.sock' mode='client'/>
+ <source type='unix' path='/tmp/vhost2.sock' mode='client'>
+ <reconnect enabled='no'/>
+ </source>
<model type='virtio'/>
<driver queues='4'/>
</interface>
--
1.8.3.1
7 years
[libvirt] [PATCH v3 0/2] daemon: fix termination/reload issues
by Nikolay Shirokovskiy
v1: https://www.redhat.com/archives/libvir-list/2017-September/msg01006.html
Changes from v2:
Fix syntax check issues.
Changes from v1:
1. Patches that fixes qemu driver termination are moved out of this series
2. New version of [1] now fixes issue in a way that suggested by reviewer
3. [2] fixes another issue that was discovered in the process of review
Nikolay Shirokovskiy (2):
libvirtd: fix crash on termination [1]
virtlogd: add missing netserver refcount increment on reload [2]
src/locking/lock_daemon.c | 1 +
src/rpc/virnetdaemon.c | 3 +++
2 files changed, 4 insertions(+)
--
1.8.3.1
7 years
[libvirt] [jenkins-ci PATCH 0/5] Expand test matrix, plus cleanups
by Andrea Bolognani
Andrea Bolognani (5):
README: Update, expand and convert to Markdown
jobs: Move check_env defaults
jobs: Define $VIR_TEST_{DEBUG,EXPENSIVE} in default check_env
jobs: Define $OSINFO_SYSTEM_DIR in default make_env
projects: Expand test matrix
README | 34 ------------------------------
README.markdown | 48 +++++++++++++++++++++++++++++++++++++++++++
jobs/autotools.yaml | 1 -
jobs/defaults.yaml | 4 ++++
jobs/go.yaml | 1 -
projects/libosinfo.yaml | 11 ++++------
projects/libvirt-glib.yaml | 4 ++++
projects/libvirt-go-xml.yaml | 4 ++++
projects/libvirt-go.yaml | 4 ++++
projects/libvirt-perl.yaml | 5 +++++
projects/libvirt-python.yaml | 4 ++++
projects/libvirt-sandbox.yaml | 2 ++
projects/libvirt-tck.yaml | 4 ++++
projects/libvirt.yaml | 15 ++++++--------
projects/osinfo-db-tools.yaml | 4 ++++
projects/osinfo-db.yaml | 3 +++
projects/virt-manager.yaml | 4 ++++
projects/virt-viewer.yaml | 4 ++++
18 files changed, 104 insertions(+), 52 deletions(-)
delete mode 100644 README
create mode 100644 README.markdown
--
2.13.6
7 years
[libvirt] [PATCH v3 REBASE 0/2] qemu: report block job errors from qemu to the user
by Nikolay Shirokovskiy
So that you can see nice report on migration:
"error: operation failed: migration of disk sda failed: No space left on device"
diff from v2:
============
1. split into 2 patches
2. change formal documentation where it is present accordingly
3. add variable initialization for safety
Nikolay Shirokovskiy (2):
qemu: prepare blockjob complete event error usage
qemu: report drive mirror errors on migration
src/qemu/qemu_blockjob.c | 14 +++++++++--
src/qemu/qemu_blockjob.h | 3 ++-
src/qemu/qemu_domain.c | 1 +
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 4 ++--
src/qemu/qemu_migration.c | 55 +++++++++++++++++++++++++++++++-------------
src/qemu/qemu_monitor.c | 5 ++--
src/qemu/qemu_monitor.h | 4 +++-
src/qemu/qemu_monitor_json.c | 4 +++-
src/qemu/qemu_process.c | 4 ++++
10 files changed, 70 insertions(+), 25 deletions(-)
--
1.8.3.1
7 years