[libvirt] [PATCH] maint: enforce whitespace on shell scripts
by Eric Blake
Noticed because virt-pki-validate was very inconsistent on
using tabs vs. 8 spaces, sometimes mixing both paradigms on
a single line.
'git diff -b' shows significant changes only in cfg.mk.
* cfg.mk (sc_TAB_in_indentation): Add a few files.
* daemon/libvirtd.init.in: Avoid tabs.
* tools/virt-pki-validate.in: Likewise.
---
cfg.mk | 4 +-
daemon/libvirtd.init.in | 6 +-
tools/virt-pki-validate.in | 138 ++++++++++++++++++++++----------------------
3 files changed, 74 insertions(+), 74 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 790d357..105b625 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -139,8 +139,8 @@ sc_prohibit_ctype_h:
# files in gnulib, since they're imported.
sc_TAB_in_indentation:
@prohibit='^ * ' \
- in_vc_files='\.(rng|[ch](\.in)?)$$' \
- halt='use spaces, not TAB, for indentation in C sources and RNG schemas' \
+ in_vc_files='(\.(rng|[ch](\.in)?)|(daemon|tools)/.*\.in)$$' \
+ halt='use spaces, not TAB, for indentation in C, sh, and RNG schemas' \
$(_sc_search_regexp)
ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\
diff --git a/daemon/libvirtd.init.in b/daemon/libvirtd.init.in
index 4c8821b..d4dc98b 100644
--- a/daemon/libvirtd.init.in
+++ b/daemon/libvirtd.init.in
@@ -72,7 +72,7 @@ stop() {
if [ $RETVAL -eq 0 ]; then
rm -f @localstatedir@/lock/subsys/$SERVICE
rm -f $PIDFILE
- rm -rf @localstatedir@/cache/libvirt/*
+ rm -rf @localstatedir@/cache/libvirt/*
fi
}
@@ -101,13 +101,13 @@ case "$1" in
;;
force-reload)
reload
- ;;
+ ;;
condrestart|try-restart)
[ -f @localstatedir@/lock/subsys/$SERVICE ] && restart || :
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload|try-restart}"
- exit 2
+ exit 2
;;
esac
exit $RETVAL
diff --git a/tools/virt-pki-validate.in b/tools/virt-pki-validate.in
index ee7b79d..9a1c6fa 100755
--- a/tools/virt-pki-validate.in
+++ b/tools/virt-pki-validate.in
@@ -147,35 +147,35 @@ then
if [ ! -r $LIBVIRT/clientcert.pem ]
then
echo Client certificate $LIBVIRT/clientcert.pem should be world readable
- echo "as root do: chown root:root $LIBVIRT/clientcert.pem ; chmod 644 $LIBVIRT/clientcert.pem"
+ echo "as root do: chown root:root $LIBVIRT/clientcert.pem ; chmod 644 $LIBVIRT/clientcert.pem"
else
S_ORG=`$CERTOOL -i --infile $LIBVIRT/clientcert.pem | grep Subject: | sed 's+.*O=\([a-zA-Z \._-]*\).*+\1+'`
- if [ "$ORG" != "$S_ORG" ]
- then
- echo The CA certificate and the client certificate do not match
- echo CA organization: $ORG
- echo Client organization: $S_ORG
- fi
- CLIENT=`$CERTOOL -i --infile $LIBVIRT/clientcert.pem | grep Subject: | sed 's+.*CN=\(.[a-zA-Z \._-]*\).*+\1+'`
- echo Found client certificate $LIBVIRT/clientcert.pem for $CLIENT
- if [ ! -e $LIBVIRTP/clientkey.pem ]
- then
- echo Missing client private key $LIBVIRTP/clientkey.pem
- else
- echo Found client private key $LIBVIRTP/clientkey.pem
- OWN=`ls -l $LIBVIRTP/clientkey.pem | awk '{ print $3 }'`
- MOD=`ls -l $LIBVIRTP/clientkey.pem | awk '{ print $1 }'`
- if [ "$OWN" != "root" ]
- then
- echo The client private key should be owned by root
- echo "as root do: chown root $LIBVIRTP/clientkey.pem"
- fi
- if [ "$MOD" != "-rw-r--r--" ]
- then
- echo The client private key need to be read by client tools
- echo "as root do: chmod 644 $LIBVIRTP/clientkey.pem"
- fi
- fi
+ if [ "$ORG" != "$S_ORG" ]
+ then
+ echo The CA certificate and the client certificate do not match
+ echo CA organization: $ORG
+ echo Client organization: $S_ORG
+ fi
+ CLIENT=`$CERTOOL -i --infile $LIBVIRT/clientcert.pem | grep Subject: | sed 's+.*CN=\(.[a-zA-Z \._-]*\).*+\1+'`
+ echo Found client certificate $LIBVIRT/clientcert.pem for $CLIENT
+ if [ ! -e $LIBVIRTP/clientkey.pem ]
+ then
+ echo Missing client private key $LIBVIRTP/clientkey.pem
+ else
+ echo Found client private key $LIBVIRTP/clientkey.pem
+ OWN=`ls -l $LIBVIRTP/clientkey.pem | awk '{ print $3 }'`
+ MOD=`ls -l $LIBVIRTP/clientkey.pem | awk '{ print $1 }'`
+ if [ "$OWN" != "root" ]
+ then
+ echo The client private key should be owned by root
+ echo "as root do: chown root $LIBVIRTP/clientkey.pem"
+ fi
+ if [ "$MOD" != "-rw-r--r--" ]
+ then
+ echo The client private key need to be read by client tools
+ echo "as root do: chmod 644 $LIBVIRTP/clientkey.pem"
+ fi
+ fi
fi
else
@@ -193,41 +193,41 @@ then
if [ ! -r $LIBVIRT/servercert.pem ]
then
echo Server certificate $LIBVIRT/servercert.pem should be world readable
- echo "as root do: chown root:root $LIBVIRT/servercert.pem ; chmod 644 $LIBVIRT/servercert.pem"
+ echo "as root do: chown root:root $LIBVIRT/servercert.pem ; chmod 644 $LIBVIRT/servercert.pem"
else
S_ORG=`$CERTOOL -i --infile $LIBVIRT/servercert.pem | grep Subject: | sed 's+.*O=\([a-zA-Z\. _-]*\).*+\1+'`
- if [ "$ORG" != "$S_ORG" ]
- then
- echo The CA certificate and the server certificate do not match
- echo CA organization: $ORG
- echo Server organization: $S_ORG
- fi
- S_HOST=`$CERTOOL -i --infile $LIBVIRT/servercert.pem | grep Subject: | sed 's+.*CN=\([a-zA-Z\. _-]*\)+\1+'`
- if test "$S_HOST" != "`hostname -s`" && test "$S_HOST" != "`hostname`"
- then
- echo The server certificate does not seem to match the host name
- echo hostname: '"'`hostname`'"'
- echo Server certificate CN: '"'$S_HOST'"'
- fi
- echo Found server certificate $LIBVIRT/servercert.pem for $S_HOST
- if [ ! -e $LIBVIRTP/serverkey.pem ]
- then
- echo Missing server private key $LIBVIRTP/serverkey.pem
- else
- echo Found server private key $LIBVIRTP/serverkey.pem
- OWN=`ls -l $LIBVIRTP/serverkey.pem | awk '{ print $3 }'`
- MOD=`ls -l $LIBVIRTP/serverkey.pem | awk '{ print $1 }'`
- if [ "$OWN" != "root" ]
- then
- echo The server private key should be owned by root
- echo "as root do: chown root $LIBVIRTP/serverkey.pem"
- fi
- if [ "$MOD" != "-rw-------" ]
- then
- echo The server private key need to be read only by root
- echo "as root do: chmod 600 $LIBVIRTP/serverkey.pem"
- fi
- fi
+ if [ "$ORG" != "$S_ORG" ]
+ then
+ echo The CA certificate and the server certificate do not match
+ echo CA organization: $ORG
+ echo Server organization: $S_ORG
+ fi
+ S_HOST=`$CERTOOL -i --infile $LIBVIRT/servercert.pem | grep Subject: | sed 's+.*CN=\([a-zA-Z\. _-]*\)+\1+'`
+ if test "$S_HOST" != "`hostname -s`" && test "$S_HOST" != "`hostname`"
+ then
+ echo The server certificate does not seem to match the host name
+ echo hostname: '"'`hostname`'"'
+ echo Server certificate CN: '"'$S_HOST'"'
+ fi
+ echo Found server certificate $LIBVIRT/servercert.pem for $S_HOST
+ if [ ! -e $LIBVIRTP/serverkey.pem ]
+ then
+ echo Missing server private key $LIBVIRTP/serverkey.pem
+ else
+ echo Found server private key $LIBVIRTP/serverkey.pem
+ OWN=`ls -l $LIBVIRTP/serverkey.pem | awk '{ print $3 }'`
+ MOD=`ls -l $LIBVIRTP/serverkey.pem | awk '{ print $1 }'`
+ if [ "$OWN" != "root" ]
+ then
+ echo The server private key should be owned by root
+ echo "as root do: chown root $LIBVIRTP/serverkey.pem"
+ fi
+ if [ "$MOD" != "-rw-------" ]
+ then
+ echo The server private key need to be read only by root
+ echo "as root do: chmod 600 $LIBVIRTP/serverkey.pem"
+ fi
+ fi
fi
else
@@ -243,19 +243,19 @@ then
if [ -r $(SYSCONFDIR)/sysconfig/libvirtd ]
then
if [ "`grep '^LIBVIRTD_ARGS' $(SYSCONFDIR)/sysconfig/libvirtd | grep -- '--listen'`" = "" ]
- then
- echo Make sure $(SYSCONFDIR)/sysconfig/libvirtd is setup to listen to
- echo TCP/IP connections and restart the libvirtd service
- fi
+ then
+ echo Make sure $(SYSCONFDIR)/sysconfig/libvirtd is setup to listen to
+ echo TCP/IP connections and restart the libvirtd service
+ fi
fi
if [ -r $(SYSCONFDIR)/sysconfig/iptables ]
then
if [ "`grep $PORT $(SYSCONFDIR)/sysconfig/iptables`" = "" ]
- then
- echo Make sure $(SYSCONFDIR)/sysconfig/iptables is setup to allow
- echo incoming TCP/IP connections on port $PORT and
- echo restart the iptables service
- fi
+ then
+ echo Make sure $(SYSCONFDIR)/sysconfig/iptables is setup to allow
+ echo incoming TCP/IP connections on port $PORT and
+ echo restart the iptables service
+ fi
fi
fi
--
1.6.6.1
14 years, 7 months
[libvirt] [PATCH] Fix initial VCPU pinning in qemu driver
by Jiri Denemark
First, inital VCPU pinning is set correctly but then it is reset by
assigning qemu process to a new cgroup (which contains all CPUs). It's
easily fixed by swapping these two actions.
---
src/qemu/qemu_driver.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
Originally, I thought it would be better to change the initial pinning
at cgroup level but then I realized it was not a good idea. AFAIK cgroup
olny works for processes and is not usable for per-VCPU pinning. That
is, it is fine to have all CPUs in cgroup and fine tune VCPU pinning by
setting procss affinity.
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5f4adfd..cc3e3b2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3081,10 +3081,10 @@ static int qemudSecurityHook(void *data) {
/* This must take place before exec(), so that all QEMU
* memory allocation is on the correct NUMA node
*/
- if (qemudInitCpuAffinity(h->vm) < 0)
+ if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
return -1;
- if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
+ if (qemudInitCpuAffinity(h->vm) < 0)
return -1;
if (h->driver->securityDriver &&
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH] Make avahi startup more robust.
by Chris Lalancette
If the hostname of the current virtualization machine
could not be resolved, then libvirtd would fail to
start. However, for disconnected operation (on a laptop,
for instance) the hostname may very legitimately not
be resolvable. This patch makes it so that if we can't
resolve the hostname, avahi doesn't fail, it just uses
a less useful MDNS string.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
daemon/libvirtd.c | 28 ++++++++++++++++++++--------
1 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 863bf21..4533f40 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -998,22 +998,34 @@ static int qemudNetworkInit(struct qemud_server *server) {
struct libvirtd_mdns_group *group;
struct qemud_socket *sock;
int port = 0;
+ int ret;
server->mdns = libvirtd_mdns_new();
if (!mdns_name) {
- char groupname[64], *localhost, *tmp;
- /* Extract the host part of the potentially FQDN */
+ char *groupname, *localhost, *tmp;
+
localhost = virGetHostname(NULL);
if (localhost == NULL)
+ /* we couldn't resolve the hostname; assume that we are
+ * running in disconnected operation, and report a less
+ * useful Avahi string
+ */
+ ret = virAsprintf(&groupname, "Virtualization Host");
+ else {
+ /* Extract the host part of the potentially FQDN */
+ if ((tmp = strchr(localhost, '.')))
+ *tmp = '\0';
+ ret = virAsprintf(&groupname, "Virtualization Host %s",
+ localhost);
+ }
+ VIR_FREE(localhost);
+ if (ret < 0) {
+ virReportOOMError();
goto cleanup;
-
- if ((tmp = strchr(localhost, '.')))
- *tmp = '\0';
- snprintf(groupname, sizeof(groupname)-1, "Virtualization Host %s", localhost);
- groupname[sizeof(groupname)-1] = '\0';
+ }
group = libvirtd_mdns_add_group(server->mdns, groupname);
- VIR_FREE(localhost);
+ VIR_FREE(groupname);
} else {
group = libvirtd_mdns_add_group(server->mdns, mdns_name);
}
--
1.6.6.1
14 years, 7 months
[libvirt] [PATCH] maint: ignore 'make syntax-check' failure files
by Eric Blake
* .gitignore: Add exemption.
* cfg.mk (local-checks-to-skip): Ignore a test to silence a skip
warning.
---
Noticed these while fixing the 'make syntax-check' fallout.
They border on trivial, but I decided to wait for an ACK.
.gitignore | 1 +
cfg.mk | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
index a7466fd..8c275f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
*~
.git
.git-module-status
+.sc-start-sc_*
/GNUmakefile
/maint.mk
ABOUT-NLS
diff --git a/cfg.mk b/cfg.mk
index 5d8103e..790d357 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -34,6 +34,7 @@ local-checks-to-skip = \
sc_GPL_version \
sc_always_defined_macros \
sc_cast_of_alloca_return_value \
+ sc_cross_check_PATH_usage_in_tests \
sc_dd_max_sym_length \
sc_error_exit_success \
sc_file_system \
--
1.6.6.1
14 years, 7 months
[libvirt] [PATCH 1/4] Make avahi startup more robust.
by Chris Lalancette
If the hostname of the current virtualization machine
could not be resolved, then libvirtd would fail to
start. However, for disconnected operation (on a laptop,
for instance) the hostname may very legitimately not
be resolvable. This patch makes it so that if we can't
resolve the hostname, avahi doesn't fail, it just uses
a less useful MDNS string.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
daemon/libvirtd.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 863bf21..69106ee 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -998,22 +998,29 @@ static int qemudNetworkInit(struct qemud_server *server) {
struct libvirtd_mdns_group *group;
struct qemud_socket *sock;
int port = 0;
+ int ret;
server->mdns = libvirtd_mdns_new();
if (!mdns_name) {
- char groupname[64], *localhost, *tmp;
+ char *groupname, *localhost, *tmp;
/* Extract the host part of the potentially FQDN */
localhost = virGetHostname(NULL);
if (localhost == NULL)
+ ret = virAsprintf(&groupname, "Virtualization Host");
+ else {
+ if ((tmp = strchr(localhost, '.')))
+ *tmp = '\0';
+ ret = virAsprintf(&groupname, "Virtualization Host %s",
+ localhost);
+ }
+ if (ret < 0) {
+ virReportOOMError();
goto cleanup;
-
- if ((tmp = strchr(localhost, '.')))
- *tmp = '\0';
- snprintf(groupname, sizeof(groupname)-1, "Virtualization Host %s", localhost);
- groupname[sizeof(groupname)-1] = '\0';
+ }
group = libvirtd_mdns_add_group(server->mdns, groupname);
VIR_FREE(localhost);
+ VIR_FREE(groupname);
} else {
group = libvirtd_mdns_add_group(server->mdns, mdns_name);
}
--
1.6.6.1
14 years, 7 months
[libvirt] empty type parameter in driver tag for disk in machine xml file
by Frederik Himpe
I updated my system from libvirt 0.7.1 to 0.7.7, one of my qemu-kvm VMs
was not starting anymore, with this error:
LC_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin HOME=/ TMPDIR=/tmp
QEMU_AUDIO_DRV=none /usr/bin/qemu-kvm -S -M pc-0.11 -enable-kvm -m 512 -
smp 1,sockets=1,cores=1,threads=1 -name debian-testing -uuid 54f57a86-
b84c-61ba-7f2a-c69f39f80a41 -nodefaults -chardev socket,id=monitor,path=/
var/lib/libvirt/qemu/debian-testing.monitor,server,nowait -mon
chardev=monitor,mode=readline -rtc base=utc -boot c -drive file=/home/
frederik/Software/iso/debian-testing-amd64-
netinst.iso,if=none,media=cdrom,id=drive-ide0-1-0 -device ide-
drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -drive file=/home/
frederik/VM/debian-testing.img,if=none,id=drive-virtio-
disk0,boot=on,format= -device virtio-blk-
pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 -device
virtio-net-pci,vlan=0,id=net0,mac=52:54:00:25:9c:a0,bus=pci.0,addr=0x5 -
net tap,fd=19,vlan=0,name=hostnet0 -chardev pty,id=serial0 -device isa-
serial,chardev=serial0 -usb -device usb-tablet,id=input0 -vnc 127.0.0.1:1
-k fr-be -vga vmware -device ES1370,id=sound0,bus=pci.0,addr=0x6 -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
char device redirected to /dev/pts/6
qemu: '' invalid format
It seems this part of the libvirt xml file was causing the problem:
<disk type='file' device='disk'>
<driver name='qemu' type=''/>
<source file='/home/frederik/VM/debian-testing.img'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04'
function='0x0'/>
</disk>
Notice the empty type parameter in the driver tag. Removing type=''
completely, makes the machine start fine.
Is this a bug which should be fixed, so that libvirt can deal empty type
tags, possible set by older versions?
--
Frederik Himpe
14 years, 7 months
[libvirt] [PATCH] Add a test case that validates save to a block device
by Daniel P. Berrange
There are some unusual problems when saving to a block device,
vs a file. This test case covers problems inherant in using
block devices
---
scripts/domain/103-blockdev-save-restore.t | 91 ++++++++++++++++++++++++++++
1 files changed, 91 insertions(+), 0 deletions(-)
create mode 100644 scripts/domain/103-blockdev-save-restore.t
diff --git a/scripts/domain/103-blockdev-save-restore.t b/scripts/domain/103-blockdev-save-restore.t
new file mode 100644
index 0000000..3cacc2f
--- /dev/null
+++ b/scripts/domain/103-blockdev-save-restore.t
@@ -0,0 +1,91 @@
+# -*- perl -*-
+#
+# Copyright (C) 2009-2010 Red Hat, Inc.
+# Copyright (C) 2009 Daniel P. Berrange
+#
+# This program is free software; You can redistribute it and/or modify
+# it under the GNU General Public License as published by the Free
+# Software Foundation; either version 2, or (at your option) any
+# later version
+#
+# The file "LICENSE" distributed along with this file provides full
+# details of the terms and conditions
+#
+
+=pod
+
+=head1 NAME
+
+domain/103-blockdev-save-restore.t: Save/restore with a block device
+
+=head1 DESCRIPTION
+
+The test case validates that it is possible to save and restore
+transient domains to/from a block device, instead of a plain file
+
+=cut
+
+use strict;
+use warnings;
+
+use Test::More tests => 9;
+
+use Sys::Virt::TCK;
+use Test::Exception;
+
+my $tck = Sys::Virt::TCK->new();
+my $conn = eval { $tck->setup(); };
+BAIL_OUT "failed to setup test harness: $@" if $@;
+END {
+ $tck->cleanup if $tck;
+ unlink "tck.img" if -f "tck.img";
+}
+
+
+my $xml = $tck->generic_domain("tck")->as_xml;
+
+my $dev = $tck->get_host_block_device();
+
+my $dom;
+diag "Creating a new transient domain";
+ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object");
+
+SKIP: {
+ skip "no block device available", 7 unless $dev;
+
+ ok(-b $dev, "$dev is a block device");
+
+ diag "Clearing any existing data in block device";
+ open DEV, ">$dev" or die "cannot open $dev: $1";
+ my $zeros = "\0"x1024;
+ for (my $i = 0; $i < 1024 * 10 ; $i++) {
+ print DEV $zeros;
+ }
+ close DEV or die "cannot save $dev: $!";
+
+ eval { $dom->save($dev); };
+ skip "save/restore not implemented", 6 if $@ && err_not_implemented($@);
+
+ ok(!$@, "domain saved");
+ die $@ if $@;
+
+ diag "Verifying it is still a block device, not a file";
+ ok(-b $dev, "$dev is a block device");
+
+ diag "Checking that transient domain has gone away";
+ ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", 42);
+
+ diag "Attempting to restore the guest";
+ lives_ok { $conn->restore_domain($dev) } "domain has been restored";
+
+ ok_domain(sub { $dom = $conn->get_domain_by_name("tck") }, "restored domain is still there", "tck");
+
+ ok(-b $dev, "$dev is a block device");
+}
+diag "Destroying the transient domain";
+$dom->destroy;
+
+diag "Checking that transient domain has gone away";
+ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", 42);
+
+# end
--
1.6.5.2
14 years, 7 months
[libvirt] [PATCH[ nwfilter: lock interface by its index
by Stefan Berger
Since the name of an interface can be the same between stops and starts
of different VMs I have to switch the IP address learning thread to use
the index of the interface to determine whether an interface is still
available or not - in the case of macvtap the thread needs to listen for
traffic on the physical interface, thus having to time out periodically
to check whether the VM's macvtap device is still there as an indication
that the VM is still alive. Previously the following sequence of 2 VMs
with macvtap device
virsh start testvm1; virsh destroy testvm1 ; virsh start testvm2
would not terminate the thread upon testvm1's destroy since the name of
the interface on the host could be the same (i.e, macvtap0) on testvm1
and testvm2, thus it was easily race-able. The thread would then
determine the IP address parameter for testvm2 but apply the rule set
for testvm1. :-(
I am also introducing a lock for the interface (by name) that the thread
must hold while it listens for the traffic and releases when it
terminates upon VM termination or 0.5 second thereafter. Thus, the new
thread for a newly started VM with the same interface name will not
start while the old one still holds the lock. The only other code that I
see that also needs to grab the lock to serialize operation is the one
that tears down the firewall that were established on behalf of an
interface.
I am moving the code applying the 'basic' firewall rules during the IP
address learning phase inside the thread but won't start the thread
unless it is ensured that the firewall driver has the ability to apply
the 'basic' firewall rules.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
src/nwfilter/nwfilter_gentech_driver.c | 24 +++
src/nwfilter/nwfilter_gentech_driver.h | 2
src/nwfilter/nwfilter_learnipaddr.c | 231 +++++++++++++++++++++++++++------
src/nwfilter/nwfilter_learnipaddr.h | 7 -
4 files changed, 221 insertions(+), 43 deletions(-)
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
@@ -54,6 +54,11 @@
#define VIR_FROM_THIS VIR_FROM_NWFILTER
+#define IFINDEX2STR(VARNAME, ifindex) \
+ char VARNAME[20]; \
+ snprintf(VARNAME, sizeof(VARNAME), "%d", ifindex);
+
+#define PKT_TIMEOUT_MS 500 /* ms */
/* structure of an ARP request/reply message */
struct f_arphdr {
@@ -109,6 +114,81 @@ static virHashTablePtr pendingLearnReq;
static virMutex ipAddressMapLock;
static virNWFilterHashTablePtr ipAddressMap;
+static virMutex ifaceMapLock;
+static virHashTablePtr ifaceLockMap;
+
+typedef struct _virNWFilterIfaceLock virNWFilterIfaceLock;
+typedef virNWFilterIfaceLock *virNWFilterIfaceLockPtr;
+struct _virNWFilterIfaceLock {
+ char ifname[IF_NAMESIZE];
+ virMutex lock;
+ int refctr;
+};
+
+
+static bool threadsTerminate = false;
+
+
+int
+virNWFilterLockIface(const char *ifname) {
+ virNWFilterIfaceLockPtr ifaceLock;
+
+ virMutexLock(&ifaceMapLock);
+
+ ifaceLock = virHashLookup(ifaceLockMap, ifname);
+ if (!ifaceLock) {
+ if (VIR_ALLOC(ifaceLock) < 0) {
+ virReportOOMError();
+ goto err_exit;
+ }
+
+ if (virMutexInitRecursive(&ifaceLock->lock) ||
+ virStrcpyStatic(ifaceLock->ifname, ifname) == NULL ||
+ virHashAddEntry(ifaceLockMap, ifname, ifaceLock)) {
+ VIR_FREE(ifaceLock);
+ goto err_exit;
+ }
+
+ ifaceLock->refctr = 0;
+ }
+
+ ifaceLock->refctr++;
+
+ virMutexUnlock(&ifaceMapLock);
+
+ virMutexLock(&ifaceLock->lock);
+
+ return 0;
+
+ err_exit:
+ virMutexUnlock(&ifaceMapLock);
+
+ return 1;
+}
+
+
+static void
+freeIfaceLock(void *payload, const char *name ATTRIBUTE_UNUSED) {
+ VIR_FREE(payload);
+}
+
+
+void
+virNWFilterUnlockIface(const char *ifname) {
+ virNWFilterIfaceLockPtr ifaceLock;
+
+ virMutexLock(&ifaceMapLock);
+
+ ifaceLock = virHashLookup(ifaceLockMap, ifname);
+ virMutexUnlock(&ifaceLock->lock);
+
+ ifaceLock->refctr--;
+ if (ifaceLock->refctr == 0)
+ virHashRemoveEntry(ifaceLockMap, ifname, freeIfaceLock);
+
+ virMutexUnlock(&ifaceMapLock);
+}
+
static void
virNWFilterIPAddrLearnReqFree(virNWFilterIPAddrLearnReqPtr req) {
@@ -127,10 +207,12 @@ virNWFilterIPAddrLearnReqFree(virNWFilte
static int
virNWFilterRegisterLearnReq(virNWFilterIPAddrLearnReqPtr req) {
int res = -1;
+ IFINDEX2STR(ifindex_str, req->ifindex);
+
virMutexLock(&pendingLearnReqLock);
- if (!virHashLookup(pendingLearnReq, req->ifname))
- res = virHashAddEntry(pendingLearnReq, req->ifname, req);
+ if (!virHashLookup(pendingLearnReq, ifindex_str))
+ res = virHashAddEntry(pendingLearnReq, ifindex_str, req);
virMutexUnlock(&pendingLearnReqLock);
@@ -141,12 +223,13 @@ virNWFilterRegisterLearnReq(virNWFilterI
virNWFilterIPAddrLearnReqPtr
-virNWFilterLookupLearnReq(const char *ifname) {
+virNWFilterLookupLearnReq(int ifindex) {
void *res;
+ IFINDEX2STR(ifindex_str, ifindex);
virMutexLock(&pendingLearnReqLock);
- res = virHashLookup(pendingLearnReq, ifname);
+ res = virHashLookup(pendingLearnReq, ifindex_str);
virMutexUnlock(&pendingLearnReqLock);
@@ -163,15 +246,16 @@ freeLearnReqEntry(void *payload, const c
#ifdef HAVE_LIBPCAP
static virNWFilterIPAddrLearnReqPtr
-virNWFilterDeregisterLearnReq(const char *ifname) {
+virNWFilterDeregisterLearnReq(int ifindex) {
virNWFilterIPAddrLearnReqPtr res;
+ IFINDEX2STR(ifindex_str, ifindex);
virMutexLock(&pendingLearnReqLock);
- res = virHashLookup(pendingLearnReq, ifname);
+ res = virHashLookup(pendingLearnReq, ifindex_str);
if (res)
- virHashRemoveEntry(pendingLearnReq, ifname, NULL);
+ virHashRemoveEntry(pendingLearnReq, ifindex_str, NULL);
virMutexUnlock(&pendingLearnReqLock);
@@ -274,7 +358,7 @@ static void *
learnIPAddressThread(void *arg)
{
char errbuf[PCAP_ERRBUF_SIZE] = {0};
- pcap_t *handle;
+ pcap_t *handle = NULL;
struct bpf_program fp;
struct pcap_pkthdr header;
const u_char *packet;
@@ -285,19 +369,26 @@ learnIPAddressThread(void *arg)
unsigned int ethHdrSize;
char *listen_if = (strlen(req->linkdev) != 0) ? req->linkdev
: req->ifname;
- int to_ms = (strlen(req->linkdev) != 0) ? 1000
- : 0;
int dhcp_opts_len;
char macaddr[VIR_MAC_STRING_BUFLEN];
virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *filter= NULL;
+ char *filter = NULL;
uint16_t etherType;
+ bool showError = true;
enum howDetect howDetected = 0;
virNWFilterTechDriverPtr techdriver = req->techdriver;
+ virNWFilterLockIface(req->ifname);
+
req->status = 0;
- handle = pcap_open_live(listen_if, BUFSIZ, 0, to_ms, errbuf);
+ /* anything change to the VM's interface -- check at least once */
+ if (ifaceCheck(false, req->ifname, NULL, req->ifindex)) {
+ req->status = ENODEV;
+ goto done;
+ }
+
+ handle = pcap_open_live(listen_if, BUFSIZ, 0, PKT_TIMEOUT_MS, errbuf);
if (handle == NULL) {
VIR_DEBUG("Couldn't open device %s: %s\n", listen_if, errbuf);
@@ -309,11 +400,22 @@ learnIPAddressThread(void *arg)
switch (req->howDetect) {
case DETECT_DHCP:
+ if (techdriver->applyDHCPOnlyRules(req->ifname,
+ req->macaddr,
+ NULL)) {
+ req->status = EINVAL;
+ goto done;
+ }
virBufferVSprintf(&buf, " ether dst %s"
" and src port 67 and dst port 68",
macaddr);
break;
default:
+ if (techdriver->applyBasicRules(req->ifname,
+ req->macaddr)) {
+ req->status = EINVAL;
+ goto done;
+ }
virBufferVSprintf(&buf, "ether host %s", macaddr);
}
@@ -324,25 +426,36 @@ learnIPAddressThread(void *arg)
filter = virBufferContentAndReset(&buf);
- if (pcap_compile(handle, &fp, filter, 1, 0) != 0 ||
- pcap_setfilter(handle, &fp) != 0) {
- VIR_DEBUG("Couldn't compile or set filter '%s'.\n", filter);
+ if (pcap_compile(handle, &fp, filter, 1, 0) != 0) {
+ VIR_DEBUG("Couldn't compile filter '%s'.\n", filter);
req->status = EINVAL;
goto done;
}
+ if (pcap_setfilter(handle, &fp) != 0) {
+ VIR_DEBUG("Couldn't set filter '%s'.\n", filter);
+ req->status = EINVAL;
+ pcap_freecode(&fp);
+ goto done;
+ }
+
+ pcap_freecode(&fp);
+
while (req->status == 0 && vmaddr == 0) {
packet = pcap_next(handle, &header);
if (!packet) {
- if (to_ms == 0) {
- /* assuming IF disappeared */
- req->status = ENODEV;
+
+ if (threadsTerminate) {
+ req->status = ECANCELED;
+ showError = false;
break;
}
- /* listening on linkdev, check whether VM's dev is still there */
- if (ifaceCheck(false, req->ifname, req->macaddr, -1)) {
+
+ /* check whether VM's dev is still there */
+ if (ifaceCheck(false, req->ifname, NULL, req->ifindex)) {
req->status = ENODEV;
+ showError = false;
break;
}
continue;
@@ -470,6 +583,7 @@ learnIPAddressThread(void *arg)
ret = virNWFilterInstantiateFilterLate(NULL,
req->ifname,
+ req->ifindex,
req->linkdev,
req->nettype,
req->macaddr,
@@ -478,13 +592,22 @@ learnIPAddressThread(void *arg)
req->driver);
VIR_DEBUG("Result from applying firewall rules on "
"%s with IP addr %s : %d\n", req->ifname, inetaddr, ret);
+ } else {
+ if (showError)
+ virReportSystemError(req->status,
+ "%s encountered an error. Shutting down "
+ "interface %s",
+ __FUNCTION__, req->ifname);
+ ifaceDown(req->ifname);
}
memset(&req->thread, 0x0, sizeof(req->thread));
VIR_DEBUG("pcap thread terminating for interface %s\n",req->ifname);
- virNWFilterDeregisterLearnReq(req->ifname);
+ virNWFilterDeregisterLearnReq(req->ifindex);
+
+ virNWFilterUnlockIface(req->ifname);
virNWFilterIPAddrLearnReqFree(req);
@@ -496,6 +619,7 @@ learnIPAddressThread(void *arg)
* virNWFilterLearnIPAddress
* @techdriver : driver to build firewalls
* @ifname: the name of the interface
+ * @ifindex: the index of the interface
* @linkdev : the name of the link device; currently only used in case of a
* macvtap device
* @nettype : the type of interface
@@ -516,6 +640,7 @@ learnIPAddressThread(void *arg)
int
virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
const char *ifname,
+ int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const unsigned char *macaddr,
@@ -530,6 +655,14 @@ virNWFilterLearnIPAddress(virNWFilterTec
if (howDetect == 0)
return 1;
+ if ( !techdriver->canApplyBasicRules()) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("IP parameter must be provided since "
+ "snooping the IP address does not work "
+ "possibly due to missing tools"));
+ return 1;
+ }
+
if (VIR_ALLOC(req) < 0) {
virReportOOMError();
goto err_no_req;
@@ -538,7 +671,7 @@ virNWFilterLearnIPAddress(virNWFilterTec
ht = virNWFilterHashTableCreate(0);
if (ht == NULL) {
virReportOOMError();
- goto err_no_ht;
+ goto err_free_req;
}
if (virNWFilterHashTablePutAll(filterparams, ht))
@@ -565,6 +698,8 @@ virNWFilterLearnIPAddress(virNWFilterTec
goto err_free_ht;
}
}
+
+ req->ifindex = ifindex;
req->nettype = nettype;
memcpy(req->macaddr, macaddr, sizeof(req->macaddr));
req->driver = driver;
@@ -576,35 +711,21 @@ virNWFilterLearnIPAddress(virNWFilterTec
rc = virNWFilterRegisterLearnReq(req);
if (rc)
- goto err_free_ht;
-
- switch (howDetect) {
- case DETECT_DHCP:
- if (techdriver->applyDHCPOnlyRules(ifname,
- macaddr,
- NULL))
- goto err_free_ht;
- break;
- default:
- if (techdriver->applyBasicRules(ifname,
- macaddr))
- goto err_free_ht;
- }
-
+ goto err_free_req;
if (pthread_create(&req->thread,
NULL,
learnIPAddressThread,
req) != 0)
- goto err_remove_rules;
+ goto err_dereg_req;
return 0;
-err_remove_rules:
- techdriver->removeBasicRules(ifname);
+err_dereg_req:
+ virNWFilterDeregisterLearnReq(ifindex);
err_free_ht:
virNWFilterHashTableFree(ht);
-err_no_ht:
+err_free_req:
virNWFilterIPAddrLearnReqFree(req);
err_no_req:
return 1;
@@ -615,6 +736,7 @@ err_no_req:
int
virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver ATTRIBUTE_UNUSED,
const char *ifname ATTRIBUTE_UNUSED,
+ int ifindex ATTRIBUTE_UNUSED,
const char *linkdev ATTRIBUTE_UNUSED,
enum virDomainNetType nettype ATTRIBUTE_UNUSED,
const unsigned char *macaddr ATTRIBUTE_UNUSED,
@@ -637,6 +759,12 @@ virNWFilterLearnIPAddress(virNWFilterTec
*/
int
virNWFilterLearnInit(void) {
+
+ if (pendingLearnReq)
+ return 0;
+
+ threadsTerminate = false;
+
pendingLearnReq = virHashCreate(0);
if (!pendingLearnReq) {
virReportOOMError();
@@ -660,6 +788,18 @@ virNWFilterLearnInit(void) {
return 1;
}
+ ifaceLockMap = virHashCreate(0);
+ if (!ifaceLockMap) {
+ virReportOOMError();
+ virNWFilterLearnShutdown();
+ return 1;
+ }
+
+ if (virMutexInit(&ifaceMapLock)) {
+ virNWFilterLearnShutdown();
+ return 1;
+ }
+
return 0;
}
@@ -670,9 +810,18 @@ virNWFilterLearnInit(void) {
*/
void
virNWFilterLearnShutdown(void) {
+
+ threadsTerminate = true;
+
+ while (virHashSize(pendingLearnReq) != 0)
+ usleep((PKT_TIMEOUT_MS * 1000) / 3);
+
virHashFree(pendingLearnReq, freeLearnReqEntry);
pendingLearnReq = NULL;
virNWFilterHashTableFree(ipAddressMap);
ipAddressMap = NULL;
+
+ virHashFree(ifaceLockMap, freeIfaceLock);
+ ifaceLockMap = NULL;
}
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.h
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
@@ -35,6 +35,7 @@ typedef virNWFilterIPAddrLearnReq *virNW
struct _virNWFilterIPAddrLearnReq {
virNWFilterTechDriverPtr techdriver;
char ifname[IF_NAMESIZE];
+ int ifindex;
char linkdev[IF_NAMESIZE];
enum virDomainNetType nettype;
unsigned char macaddr[VIR_MAC_BUFLEN];
@@ -49,6 +50,7 @@ struct _virNWFilterIPAddrLearnReq {
int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
const char *ifname,
+ int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const unsigned char *macaddr,
@@ -57,12 +59,15 @@ int virNWFilterLearnIPAddress(virNWFilte
virNWFilterDriverStatePtr driver,
enum howDetect howDetect);
-virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(const char *ifname);
+virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex);
void virNWFilterDelIpAddrForIfname(const char *ifname);
const char *virNWFilterGetIpAddrForIfname(const char *ifname);
+int virNWFilterLockIface(const char *ifname);
+void virNWFilterUnlockIface(const char *ifname);
+
int virNWFilterLearnInit(void);
void virNWFilterLearnShutdown(void);
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
@@ -557,6 +557,7 @@ virNWFilterInstantiate(virConnectPtr con
enum virDomainNetType nettype,
virNWFilterDefPtr filter,
const char *ifname,
+ int ifindex,
const char *linkdev,
virNWFilterHashTablePtr vars,
enum instCase useNewFilter, int *foundNewFilter,
@@ -592,9 +593,10 @@ virNWFilterInstantiate(virConnectPtr con
if (virHashSize(missing_vars->hashTable) == 1) {
if (virHashLookup(missing_vars->hashTable,
NWFILTER_STD_VAR_IP) != NULL) {
- if (virNWFilterLookupLearnReq(ifname) == NULL) {
+ if (virNWFilterLookupLearnReq(ifindex) == NULL) {
rc = virNWFilterLearnIPAddress(techdriver,
ifname,
+ ifindex,
linkdev,
nettype, macaddr,
filter->name,
@@ -639,11 +641,21 @@ virNWFilterInstantiate(virConnectPtr con
if (rc)
goto err_exit;
+ virNWFilterLockIface(ifname);
+
rc = techdriver->applyNewRules(conn, ifname, nptrs, ptrs);
if (teardownOld && rc == 0)
techdriver->tearOldRules(conn, ifname);
+ if (rc == 0 && ifaceCheck(false, ifname, NULL, ifindex)) {
+ /* interface changed/disppeared */
+ techdriver->allTeardown(ifname);
+ rc = 1;
+ }
+
+ virNWFilterUnlockIface(ifname);
+
VIR_FREE(ptrs);
}
@@ -666,6 +678,7 @@ static int
__virNWFilterInstantiateFilter(virConnectPtr conn,
bool teardownOld,
const char *ifname,
+ int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const unsigned char *macaddr,
@@ -767,6 +780,7 @@ __virNWFilterInstantiateFilter(virConnec
nettype,
filter,
ifname,
+ ifindex,
linkdev,
vars,
useNewFilter, &foundNewFilter,
@@ -798,9 +812,15 @@ _virNWFilterInstantiateFilter(virConnect
const char *linkdev = (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
? net->data.direct.linkdev
: NULL;
+ int ifindex;
+
+ if (ifaceGetIndex(true, net->ifname, &ifindex))
+ return 1;
+
return __virNWFilterInstantiateFilter(conn,
teardownOld,
net->ifname,
+ ifindex,
linkdev,
net->type,
net->mac,
@@ -814,6 +834,7 @@ _virNWFilterInstantiateFilter(virConnect
int
virNWFilterInstantiateFilterLate(virConnectPtr conn,
const char *ifname,
+ int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const unsigned char *macaddr,
@@ -825,6 +846,7 @@ virNWFilterInstantiateFilterLate(virConn
rc = __virNWFilterInstantiateFilter(conn,
1,
ifname,
+ ifindex,
linkdev,
nettype,
macaddr,
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.h
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
@@ -49,6 +49,7 @@ int virNWFilterTearOldFilter(virConnectP
int virNWFilterInstantiateFilterLate(virConnectPtr conn,
const char *ifname,
+ int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const unsigned char *macaddr,
@@ -77,6 +78,7 @@ virNWFilterTearNWFilter(virDomainNetDefP
static inline void
virNWFilterTearVMNWFilters(virDomainObjPtr vm) {
int i;
+
for (i = 0; i < vm->def->nnets; i++)
virNWFilterTearNWFilter(vm->def->nets[i]);
}
14 years, 7 months
[libvirt] [PATCH] esx: Gather some XML generation macros in esx_vi.h
by Matthias Bolte
---
src/esx/esx_vi.c | 27 ++-------------------------
src/esx/esx_vi.h | 37 +++++++++++++++++++++++++++++++++++++
src/esx/esx_vi_methods.c | 17 -----------------
src/esx/esx_vi_types.c | 20 --------------------
4 files changed, 39 insertions(+), 62 deletions(-)
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index c6854f1..e405c80 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -38,38 +38,13 @@
#define VIR_FROM_THIS VIR_FROM_ESX
-#define ESX_VI__SOAP__REQUEST_HEADER \
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
- "<soapenv:Envelope " \
- "xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
- "xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" " \
- "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
- "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" \
- "<soapenv:Body>"
-
-#define ESX_VI__SOAP__REQUEST_FOOTER \
- "</soapenv:Body>" \
- "</soapenv:Envelope>"
+
#define ESX_VI__SOAP__RESPONSE_XPATH(_type) \
((char *)"/soapenv:Envelope/soapenv:Body/" \
"vim:"_type"Response/vim:returnval")
-#define ESV_VI__XML_TAG__OPEN(_buffer, _element, _type) \
- do { \
- virBufferAddLit(_buffer, "<"); \
- virBufferAdd(_buffer, _element, -1); \
- virBufferAddLit(_buffer, " xmlns=\"urn:vim25\" xsi:type=\""); \
- virBufferAdd(_buffer, _type, -1); \
- virBufferAddLit(_buffer, "\">"); \
- } while (0)
-
-#define ESV_VI__XML_TAG__CLOSE(_buffer, _element) \
- do { \
- virBufferAddLit(_buffer, "</"); \
- virBufferAdd(_buffer, _element, -1); \
- virBufferAddLit(_buffer, ">"); \
- } while (0)
+
#define ESX_VI__TEMPLATE__ALLOC(_type) \
int \
@@ -78,6 +53,8 @@
return esxVI_Alloc((void **)ptrptr, sizeof(esxVI_##_type)); \
}
+
+
#define ESX_VI__TEMPLATE__FREE(_type, _body) \
void \
esxVI_##_type##_Free(esxVI_##_type **ptrptr) \
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index a3d9363..e0d731e 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -40,6 +40,43 @@
+#define ESX_VI__SOAP__REQUEST_HEADER \
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
+ "<soapenv:Envelope\n" \
+ " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" \
+ " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n" \
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" \
+ " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" \
+ "<soapenv:Body>\n"
+
+
+
+#define ESX_VI__SOAP__REQUEST_FOOTER \
+ "</soapenv:Body>\n" \
+ "</soapenv:Envelope>"
+
+
+
+#define ESV_VI__XML_TAG__OPEN(_buffer, _element, _type) \
+ do { \
+ virBufferAddLit(_buffer, "<"); \
+ virBufferAdd(_buffer, _element, -1); \
+ virBufferAddLit(_buffer, " xmlns=\"urn:vim25\" xsi:type=\""); \
+ virBufferAdd(_buffer, _type, -1); \
+ virBufferAddLit(_buffer, "\">"); \
+ } while (0)
+
+
+
+#define ESV_VI__XML_TAG__CLOSE(_buffer, _element) \
+ do { \
+ virBufferAddLit(_buffer, "</"); \
+ virBufferAdd(_buffer, _element, -1); \
+ virBufferAddLit(_buffer, ">"); \
+ } while (0)
+
+
+
typedef enum _esxVI_APIVersion esxVI_APIVersion;
typedef enum _esxVI_ProductVersion esxVI_ProductVersion;
typedef enum _esxVI_Occurrence esxVI_Occurrence;
diff --git a/src/esx/esx_vi_methods.c b/src/esx/esx_vi_methods.c
index 5c52167..8f841e3 100644
--- a/src/esx/esx_vi_methods.c
+++ b/src/esx/esx_vi_methods.c
@@ -34,23 +34,6 @@
-#define ESX_VI__SOAP__REQUEST_HEADER \
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
- "<soapenv:Envelope " \
- "xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
- "xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" " \
- "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
- "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" \
- "<soapenv:Body>"
-
-
-
-#define ESX_VI__SOAP__REQUEST_FOOTER \
- "</soapenv:Body>" \
- "</soapenv:Envelope>"
-
-
-
#define ESX_VI__METHOD__CHECK_OUTPUT__None \
/* nothing */
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index ed4674b..7d2c02c 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -39,26 +39,6 @@
-#define ESV_VI__XML_TAG__OPEN(_buffer, _element, _type) \
- do { \
- virBufferAddLit(_buffer, "<"); \
- virBufferAdd(_buffer, _element, -1); \
- virBufferAddLit(_buffer, " xmlns=\"urn:vim25\" xsi:type=\""); \
- virBufferAdd(_buffer, _type, -1); \
- virBufferAddLit(_buffer, "\">"); \
- } while (0)
-
-
-
-#define ESV_VI__XML_TAG__CLOSE(_buffer, _element) \
- do { \
- virBufferAddLit(_buffer, "</"); \
- virBufferAdd(_buffer, _element, -1); \
- virBufferAddLit(_buffer, ">"); \
- } while (0)
-
-
-
#define ESX_VI__TEMPLATE__ALLOC(__type) \
int \
esxVI_##__type##_Alloc(esxVI_##__type **ptrptr) \
--
1.6.3.3
14 years, 7 months
[libvirt] [RFC PATCH] Support for qemu aio drive option
by Matthias Dahl
This is a "quick" implementation to support the qemu aio drive option. I tried
to stay true to the coding style and this has been tested w/ libvirt 0.7.6 and
works just fine.
Since I am not that familiar w/ the inner workings of libvirt, I am sure I
missed a few spots, so I hope either someone will base his work on this patch
or point me into the right direction so I can finish this up for good. :-)
For everyone else, enjoy...
---
src/conf/domain_conf.c | 23 +++++++++++++++++++++++
src/conf/domain_conf.h | 10 ++++++++++
src/qemu/qemu_conf.c | 14 ++++++++++++++
src/qemu/qemu_conf.h | 2 ++
4 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 766993c..8bee7b8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -120,6 +120,11 @@ VIR_ENUM_IMPL(virDomainDiskCache,
VIR_DOMAIN_DISK_CACHE_LAST,
"writethrough",
"writeback")
+VIR_ENUM_IMPL(virDomainDiskAIO, VIR_DOMAIN_DISK_AIO_LAST,
+ "default",
+ "native",
+ "threads")
+
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide",
"fdc",
@@ -1228,6 +1233,7 @@ virDomainDiskDefParseXML(virConnectPtr conn,
char *target = NULL;
char *bus = NULL;
char *cachetag = NULL;
+ char *aiotag = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
@@ -1293,6 +1299,7 @@ virDomainDiskDefParseXML(virConnectPtr conn,
driverName = virXMLPropString(cur, "name");
driverType = virXMLPropString(cur, "type");
cachetag = virXMLPropString(cur, "cache");
+ aiotag = virXMLPropString(cur, "aio");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@@ -1409,6 +1416,13 @@ virDomainDiskDefParseXML(virConnectPtr conn,
goto error;
}
+ if (aiotag &&
+ (def->aiomode = virDomainDiskAIOTypeFromString(aiotag)) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown disk aio mode '%s'"), aiotag);
+ goto error;
+ }
+
if (devaddr) {
if (sscanf(devaddr, "%x:%x:%x",
&def->info.addr.pci.domain,
@@ -1450,6 +1464,7 @@ cleanup:
VIR_FREE(driverType);
VIR_FREE(driverName);
VIR_FREE(cachetag);
+ VIR_FREE(aiotag);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@@ -4565,6 +4580,7 @@ virDomainDiskDefFormat(virConnectPtr conn,
const char *device = virDomainDiskDeviceTypeToString(def->device);
const char *bus = virDomainDiskBusTypeToString(def->bus);
const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
+ const char *aiomode = virDomainDiskAIOTypeToString(def->aiomode);
if (!type) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -4586,6 +4602,11 @@ virDomainDiskDefFormat(virConnectPtr conn,
_("unexpected disk cache mode %d"), def-
>cachemode);
return -1;
}
+ if (!aiomode) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unexpected disk aio mode %d"), def->aiomode);
+ return -1;
+ }
virBufferVSprintf(buf,
" <disk type='%s' device='%s'>\n",
@@ -4597,6 +4618,8 @@ virDomainDiskDefFormat(virConnectPtr conn,
virBufferVSprintf(buf, " type='%s'", def->driverType);
if (def->cachemode)
virBufferVSprintf(buf, " cache='%s'", cachemode);
+ if (def->aiomode)
+ virBufferVSprintf(buf, " aio='%s'", aiomode);
virBufferVSprintf(buf, "/>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0b79e88..07805a6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -141,6 +141,14 @@ enum virDomainDiskCache {
VIR_DOMAIN_DISK_CACHE_LAST
};
+enum virDomainDiskAIO {
+ VIR_DOMAIN_DISK_AIO_DEFAULT,
+ VIR_DOMAIN_DISK_AIO_NATIVE,
+ VIR_DOMAIN_DISK_AIO_THREADS,
+
+ VIR_DOMAIN_DISK_AIO_LAST
+};
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -154,6 +162,7 @@ struct _virDomainDiskDef {
char *driverType;
char *serial;
int cachemode;
+ int aiomode;
unsigned int readonly : 1;
unsigned int shared : 1;
virDomainDeviceInfo info;
@@ -897,6 +906,7 @@ VIR_ENUM_DECL(virDomainDisk)
VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus)
VIR_ENUM_DECL(virDomainDiskCache)
+VIR_ENUM_DECL(virDomainDiskAIO)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainFS)
VIR_ENUM_DECL(virDomainNet)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 3d83a8f..fd3a670 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -83,6 +83,12 @@ VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST,
"writethrough",
"writeback");
+VIR_ENUM_DECL(qemuDiskAIO)
+VIR_ENUM_IMPL(qemuDiskAIO, VIR_DOMAIN_DISK_AIO_LAST,
+ "default",
+ "native",
+ "threads");
+
VIR_ENUM_DECL(qemuVideo)
VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
@@ -1137,6 +1143,8 @@ static unsigned int qemudComputeCmdFlags(const char
*help,
flags |= QEMUD_CMD_FLAG_DRIVE_CACHE_V2;
if (strstr(help, "format="))
flags |= QEMUD_CMD_FLAG_DRIVE_FORMAT;
+ if (strstr(help, "aio=threads|native"))
+ flags |= QEMUD_CMD_FLAG_DRIVE_AIO;
}
if (strstr(help, "-vga") && !strstr(help, "-std-vga"))
flags |= QEMUD_CMD_FLAG_VGA;
@@ -2340,6 +2348,12 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
virBufferAddLit(&opt, ",cache=off");
}
+ if (disk->aiomode && (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_AIO)) {
+ const char * mode = qemuDiskAIOTypeToString(disk->aiomode);
+
+ virBufferVSprintf(&opt, ",aio=%s", mode);
+ }
+
if (virBufferError(&opt)) {
virReportOOMError(NULL);
goto error;
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 101f187..780ae6e 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -82,6 +82,8 @@ enum qemud_cmd_flags {
QEMUD_CMD_FLAG_SDL = (1 << 27), /* Is the new -sdl arg
available */
QEMUD_CMD_FLAG_SMP_TOPOLOGY = (1 << 28), /* Is
sockets=s,cores=c,threads=t available for -smp? */
QEMUD_CMD_FLAG_NETDEV = (1 << 29), /* The -netdev flag &
netdev_add/remove monitor commands */
+
+ QEMUD_CMD_FLAG_DRIVE_AIO = (1 << 30), /* Is -drive aio= avail */
};
/* Main driver state */
--
1.7.0.4
14 years, 7 months