[libvirt] race between qemu monitor startup and blocking migrate -incoming
by Charles Duffy
Howdy, 'yall.
I'm having issues with virDomainRestore failing, particularly under load
-- even in 0.7.0, when there's no need to parse through qemu's output to
find the monitor PTY.
Digging through strace output of libvirtd and the qemu processes it
spawns, this is happening when qemu blocks on the migrate -incoming and
ceases to respond to the monitor socket -- though some versions of qemu
can go into this state before the monitor socket is even opened, leading
to libvirt timing out either while attempting to open the monitor socket
or while trying to read therefrom, and subsequently killing the qemu
instance it spawned while that instance is still attempting to migrate
in its old saved state.
Both of qemu-0.11.0-rc1 and qemu-kvm master have some form of blocking
in -incoming exec: which can prevent libvirt from successfully carrying
through a resume; I have reproduced the issue (and maintain logs from
strace, available on request) irrespective of the state of Chris
Lalancette's "Fix detached migration with exec" and "Allow monitor
interaction when using migrate -exec" patches. The qemu binaries being
used _appear_ to correctly allow monitor interaction prior to -incoming
exec:... completion when interactively invoked in the trivial case shown
below:
$ qemu-system-x86_64 \
-monitor stdio \
-nographic \
-serial file:/dev/null \
-incoming 'exec:sleep 5; echo DONE >&2; kill $PPID' \
/dev/null
QEMU 0.10.91 monitor - type 'help' for more information
(qemu) DONE
$
...however, whether these same binaries work as-expected when invoked
from libvirt by our automated test system under load is
nondeterministic. (I have yet to reproduce the issue in a low-load
environment using "virsh restore").
Is someone else working on this? Is a known-good (or believed-good)
libvirt/qemu pair available? What can I do to help in getting this issue
resolved?
Thanks!
---
libvirt-0.7.0 + qemu-kvm-0.11.0-rc1
qemudReadMonitorOutput:728 : internal error Timed out while reading
monitor startup output
libvirt-0.6.5 + qemu-kvm-0.11.0-rc1
error : qemudReadMonitorOutput:705 : internal error Timed out while
reading monitor startup output
error : qemudWaitForMonitor:1003 : internal error unable to start guest:
char device redirected to /dev/pts/9
libvir: QEMU error : internal error unable to start guest: char device
redirected to /dev/pts/9
^^ particularly interesting, as the above line should have been eaten by
qemudExtractMonitorPath rather than emitted as error text
---
<aliguori> -incoming is blocking
<aliguori> you cannot interact with the monitor during -incoming
<mDuff> ...shouldn't we always be opening the monitor before starting
the blocking -incoming bits, though? I don't always see that happening
(and have an strace handy where it certainly doesn't).
<aliguori> no
<aliguori> well, i think they added some patches for that
<aliguori> but originally, that's not how it worked
<aliguori> and i think it's silly to work that way
<aliguori> -incoming should mean, wait patiently for an incoming migration
<aliguori> there's no point in interfacing with the monitor in the interim
<mDuff> I agree that interacting may not be called for, but at least
connect()ing -- if it's a UNIX socket, the other side won't be able to
connect at all until qemu goes first...
<aliguori> heh, well....
<aliguori> that particular race condition is addressed by -daemonize
<aliguori> because that's generally true
<aliguori> you don't know how long qemu will take to open the monitor
<aliguori> but -daemonize makes gives you notification because it
doesn't daemonize the process until you've gotten to the point where all
sockets are open
<aliguori> but IIRC, libvirt doesn't use -daemonize
15 years, 1 month
[libvirt] [PATCH 0/4] Support for SPICE graphics
by Daniel P. Berrange
This series of patches adds minimal support for SPICE graphics
which is newly introduced in RHEL-5.4's fork of KVM. Since this
is not yet merged in upstream QEMU/KVM, I'm not proposing to merge
all these patches. The two XML schema patches are straightforward
to merge.
The two implementation ones are RHEL5 specific and I want to
avoid declaring them supported until we have a sign of what the
upstream merge will look like, since previous attempst to support
KVM args prior to QEMU acceptance have been very painful long
term.
Daniel
15 years, 2 months
[libvirt] [RFC] Support for CPUID masking
by Jiri Denemark
Hi,
We need to provide support for CPU ID masking. Xen and VMware ESX are examples
of current hypervisors which support such masking.
My proposal is to define new 'cpuid' feature advertised in guest
capabilities:
<guest>
...
<features>
<cpuid/>
</feature>
</guest>
When a driver supports cpuid feature, one can use it to mask/check for
specific bits returned by CPU ID as follows:
<domain>
...
<features>
<cpuid>
<mask level='hex' register='eax|ebx|ecx|edx'>MASK</mask>
</cpuid>
</features>
...
</domain>
Where
- level is a hexadecimal number used as an input to CPU ID (i.e. eax
register),
- register is one of eax, ebx, ecx or edx,
- and MASK is a string with the following format:
mmmm:mmmm:mmmm:mmmm:mmmm:mmmm:mmmm:mmmm with m being 1-bit mask for the
corresponding bit in the register.
There are three possibilities of specifying what values can be used for 'm':
- let it be driver-specific,
- define all possible values,
- define a common set of values and allow drivers to specify their own
additional values.
I think the third is the way to go as it lowers the confusion of different
values used by different drivers for the same purpose while maintaining the
flexibility to support driver-specific masks.
The following could be a good set of predefined common values:
- 1 force the bit to be 1
- 0 force the bit to be 0
- x don't care, i.e., use driver's default value
- T require the bit to be 1
- F require the bit to be 0
Some examples of what it could look like follow:
<capabilities>
...
<guest>
<os_type>xen</os_type>
...
<features>
<pae/>
<cpuid/>
</features>
</guest>
...
</capabilities>
<domain type='xen' id='42'>
...
<features>
<pae/>
<acpi/>
<apic/>
<cpuid>
<mask level='1' register='ebx'>
xxxx:xxxx:0000:1010:xxxx:xxxx:xxxx:xxxx
</mask>
<mask level='1' register='ecx'>
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx1x:xxxx
</mask>
<mask level='1' register='edx'>
xxx1:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
</mask>
<mask level='80000001' register='ecx'>
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx1x
</mask>
<mask level='80000008' register='ecx'>
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx00:1001
</mask>
</cpuid>
</features>
...
</domain>
What are your opinions about this?
Thank for all comments.
Jirka
15 years, 2 months
[libvirt] [PATCH 0/9] Support disk-hotremove and controller hotplugging
by Wolfgang Mauerer
Hi,
this patch reworks libvirt's disk-hotadd support and
introduces support for disk controller hotplugging and disk-hotremove
(see http://thread.gmane.org/gmane.comp.emulators.libvirt/15860 for
more details). Currently, it targets only qemu and also requires some
additions to qemu that have only recently been submitted, which is
why this is cross-posted to qemu-devel. Hopefully the lack of support
in qemu does not prevent the community from reviewing the code,
though ;-)
Notice that no documentation and testcases are included yet; I'll
supply those once the interface is fixed and possible issues
are settled.
Thanks for your comments,
Wolfgang
docs/schemas/domain.rng | 145 ++++++++++----
src/domain_conf.c | 208 ++++++++++++++++++++-
src/domain_conf.h | 39 ++++-
src/libvirt_private.syms | 4 +-
src/qemu_driver.c | 479 +++++++++++++++++++++++++++++++++++++++++++---
5 files changed, 802 insertions(+), 73 deletions(-)
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
15 years, 2 months
[libvirt] Resubmission #2: [PATCH 0/3] sVirt AppArmor security driver
by Jamie Strandboge
Resubmitting again based on feedback from this list. Notably, the driver
has been reworked to use:
xml = virDomainDefFormat(conn, vm->def, ...
Then the helper program uses:
ctl->def = virDomainDefParseString(... xmlStr ...);
This simplifies adding new files. Part of this process involved adding
support for kernel, initrd, loader, serial, and console. I have commented
out code for hostdev (and pci would be easy enough), but it requires a
patch to to move the _usbDevice struct fully into hostusb.h. I figure
once the AppArmor driver is in, I can submit a patch for that.
This iteration also properly works with attach/detach. While I use
virDomainDefFormat() primarily, this does not work with attach because
the definition is not updated with the information yet (neither def nor
newDef), so I pass the disk file on the command line. For now this is ok
since SetSecurityImageLabel currently only deals with a single file, but
this will need to be adjusted depending on how the storage backend patch
works out. I thought about creating a new def and inserting the disk into
it and sending it off to virt-aa-helper, but I couldn't find an easy
way to get an accurate virCapsPtr in security_apparmor.c. I had a
similar problem with virt-aa-helper, but there I just created a fake
virCapsPtr (which defaults to 'hvm', which was a compromise I was
willing to make at this time since sVirt only supports qemu right now).
The issues with virCapsPtr aside, the code is overall cleaner and much
more easily extendable, so thanks for the excellent feedback. :)
The patches are against up to date trunk, compiles with no warnings,
'make check' passes for the tests I added, and the code passes
syntax-check. With the exception of the three calls to strncpy I had to
convert to virStr*, this is the code that is currently in Ubuntu 9.10
(0.7.0-1ubuntu8). Among other things, that means 9.10 now has your
preferred licensing.
[PATCH 1]
patch_1_reenable-nonfile-labels.patch (Updated based on prior feedback):
When James Morris originally submitted his sVirt patches (as seen in
libvirt 0.6.1), he did not require on disk labelling for
virSecurityDomainRestoreImageLabel. A later commit[2] changed this
behavior to assume on disk labelling, which halts implementations for
path-based MAC systems such as AppArmor and TOMOYO where
vm->def->seclabel is required to obtain the label. This patch simply
adds the 'virDomainObjPtr vm' argument back to *RestoreImageLabel.
[PATCH 2]
patch_2_apparmor_driver.patch (updated and merged into one patch based
on prior feedback):
- Updates src/security.c for AppArmor
- Adds security_apparmor.c, security_apparmor.h, virt-aa-helper.c and
updates po/POTFILES.in. virt-aa-helper.c is a new binary which is used
exclusively by the AppArmor security driver to manipulate AppArmor.
- Adds tests for virt-aa-helper and the security driver. secaatest.c is
identical to seclabeltest.c except it initializes the 'apparmor' driver
instead of 'selinux'. These tests are integrated into 'make check' and
pass.
- Updates configure.in, Makefile.am, src/Makefile.am, tests/Makefile.am,
and tools/Makefile.am for AppArmor. It is based on and should operate
the same as the SELinux configuration.
[PATCH 3]
patch_3_docs.patch (Updated based on prior feedback):
Updates docs/drvqemu.html.in for AppArmor and adds profile examples to
examples/apparmor. Updated based on prior feedback.
Jamie
On Fri, 04 Sep 2009, Jamie Strandboge wrote:
> This patch series implements the AppArmor security driver for sVirt.
> This implementation was developed for the Ubuntu AppArmorLibvirtProfile
> specification[1], but is general enough for any AppArmor deployment
> (such as Ubuntu, *SUSE and Mandriva).
>
> This patch has seen quite a bit of real world testing in Ubuntu 9.10
> (our development release) in our 0.7.0-1ubuntu3 package. I did make a
> few small changes after going through HACKING, but mostly I got the
> tests going and added documentation.
>
> DESIGN
> ------
> When a virtual machine is started, determine if a profile is currently
> defined for the machine, and use it if available. If not, generate a new
> profile for the machine based on a template, which is by default a very
> restrictive profile allowing access to disk files, and anything else
> needed to run, such as the pid, monitor and log files.
>
> Virtual machines should have a unique profile specific to that machine.
> To ensure uniqueness, the profile name will be derived from the UUID of
> the virtual machine. These profiles should be configurable, either by
> adjusting the profile template for new machines, creating/modifying the
> VM profile directly or through the use of AppArmor abstractions. This
> will allow for administrators to fine-tune confinement for individual
> machines if desired.
>
> If enabled at compile time, the sVirt security model will be activated
> if AppArmor is available on the host OS and a profile for the libvirtd
> daemon is loaded when libvirtd is started.
>
> libvirtd should not be allowed to create arbitrary profiles or modify
> profiles directly, so as to not allow libvirtd to potentially (ie via a
> security bug in libvirtd itself) bootstrap out of AppArmor confinement.
>
> Because root privileges are needed to manipulate AppArmor profiles,
> qemu:///session will not be supported at this time, but the
> implementation must allow for a confined libvirtd with qemu:///session
> guests running unconfined. This can be revisited when AppArmor supports
> per-user profiles.
>
> Please see the specification[1] for more details.
--
Jamie Strandboge | http://www.canonical.com
15 years, 2 months
[libvirt] [PATCH] in vbox driver, interface type bridge should really be type ethernet
by Florian Vichot
If I understand correctly, the "bridge" type for an interface means
libvirt is in charge of creating a tun device and adding it to the
specified bridge in the <source bridge=".."> attribute. This is not what
the (badly named IHMO) "Bridged Networking" mode in vbox does: all it
does is read and write its packets on the specified interface. Which is
what a type "ethernet" interface does in my opinion. I joined a quick
patch for that, Pritesh could you check it ?
Also, I was about to patch to add support for the proper "bridge" mode
in the vbox driver (because it's what I need in the end), but I see no
way of storing the fact that it's not just an "ethernet" interface using
the vbox API, so that the config would persist over libvirtd restarts.
There is always the possibility of naming the interface a special way
like "br1_myTap", and assume any type "ethernet" interface with a device
containing a "br1_" prefix would actually be a type "bridge" interface
with an associated "vbox_br1" bridge. Would that be acceptable, or is it
too hackish ?
BTW, just to make sure, I can use pretty much anything as a <target> ie.
ethN, panN etc in a type "ethernet" interface, right ? If <target> is
specified, it's not going to create a tun and use that ?
Thanks,
Florian
15 years, 2 months
[libvirt] [PATCH] Fix up "make check"
by Chris Lalancette
While running make check, I noticed that it was actually using
the virsh binary from my system, in /usr/bin/virsh, and not the
one that was just compiled. This is actually caused by a bug
in Makefile.am, where we didn't update the PATH to include tools.
While here, I also updated all of the scripts to properly define
the srcdir, abs_top_srcdir, and abs_top_builddir environment
variables. This is required if you want to be able to run the
tests standalone (i.e. ./test instead of from make check). I've
tested this on both RHEL-5 and Fedora-10 machines, and make check
works on both, as does running the individual tests by hand.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
tests/Makefile.am | 2 +-
tests/cpuset | 12 ++++++++----
tests/daemon-conf | 18 +++++++++++-------
tests/define-dev-segfault | 10 ++++++----
tests/int-overflow | 20 ++++++++++----------
tests/libvirtd-fail | 10 ++++++----
tests/libvirtd-pool | 10 ++++++----
tests/read-bufsiz | 15 ++++++++-------
tests/read-non-seekable | 12 ++++++++----
tests/start | 10 ++++++----
tests/test_conf.sh | 14 ++++++++------
tests/undefine | 14 +++++++++-----
tests/vcpupin | 12 ++++++++----
tests/virsh-all | 12 +++++++-----
tests/virsh-synopsis | 11 +++++++----
15 files changed, 109 insertions(+), 73 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index abda4ad..4caca8f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -150,7 +150,7 @@ TESTS += nodedevxml2xmltest
TESTS += interfacexml2xmltest
-path_add = $$abs_top_builddir/src$(PATH_SEPARATOR)$$abs_top_builddir/daemon
+path_add = $$abs_top_builddir/src$(PATH_SEPARATOR)$$abs_top_builddir/daemon$(PATH_SEPARATOR)$$abs_top_builddir/tools
# NB, automake < 1.10 does not provide the real
# abs_top_{src/build}dir variables, so don't rely
diff --git a/tests/cpuset b/tests/cpuset
index eeb0ee2..9f43269 100755
--- a/tests/cpuset
+++ b/tests/cpuset
@@ -16,17 +16,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
fail=0
# generate input
-virsh --connect test:///default dumpxml 1 > xml || fail=1
+$abs_top_builddir/tools/virsh --connect test:///default dumpxml 1 > xml || fail=1
# require the presence of the string we'll transform
grep '<vcpu>' xml > /dev/null || fail=1
@@ -34,7 +38,7 @@ grep '<vcpu>' xml > /dev/null || fail=1
sed "s/vcpu>/vcpu cpuset='aaa'>/" xml > xml-invalid || fail=1
# Require failure and a diagnostic.
-virsh --connect test:///default define xml-invalid > out 2>&1 && fail=1
+$abs_top_builddir/tools/virsh --connect test:///default define xml-invalid > out 2>&1 && fail=1
cat <<\EOF > exp || fail=1
error: Failed to define domain from xml-invalid
error: failed Xen syscall topology cpuset syntax error
diff --git a/tests/daemon-conf b/tests/daemon-conf
index 071497e..722fe4e 100755
--- a/tests/daemon-conf
+++ b/tests/daemon-conf
@@ -1,16 +1,20 @@
#!/bin/sh
# Get coverage of libvirtd's config-parsing code.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- libvirtd --version
+ $abs_top_builddir/daemon/libvirtd --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
-test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
+
+test -z "$CONFIG_HEADER" && CONFIG_HEADER="$abs_top_builddir/config.h"
-grep '^#define WITH_QEMU 1' $CONFIG_HEADER > /dev/null ||
+grep '^#define WITH_QEMU 1' "$CONFIG_HEADER" > /dev/null ||
skip_test_ "configured without QEMU support"
conf="$abs_top_srcdir/daemon/libvirtd.conf"
@@ -40,7 +44,7 @@ while :; do
esac
# Run libvirtd, expecting it to fail.
- libvirtd --config=$f 2> err && fail=1
+ $abs_top_builddir/daemon/libvirtd --config=$f 2> err && fail=1
case $rhs in
# '"'*) msg='should be a string';;
@@ -73,7 +77,7 @@ sed 's,^log_outputs.*,log_outputs="3:file:'"$(pwd)/log"'",' tmp.conf > k \
mv k tmp.conf || fail=1
printf "running libvirtd with a valid config file ($sleep_secs seconds)\n" 1>&2
-libvirtd --pid-file=pid-file --config=tmp.conf > log 2>&1 & pid=$!
+$abs_top_builddir/daemon/libvirtd --pid-file=pid-file --config=tmp.conf > log 2>&1 & pid=$!
sleep $sleep_secs
kill $pid
diff --git a/tests/define-dev-segfault b/tests/define-dev-segfault
index 4ae286f..e0b953a 100755
--- a/tests/define-dev-segfault
+++ b/tests/define-dev-segfault
@@ -2,13 +2,15 @@
# Exercise a bug whereby defining a valid domain could kill libvirtd.
# The bug can also be exercised with a simple define/dumpxml pair to virsh.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
-test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
. "$srcdir/test-lib.sh"
fail=0
@@ -62,7 +64,7 @@ cat <<\EOF > D.xml || fail=1
EOF
url=test:///default
-virsh --connect "$url" 'define D.xml; dumpxml D' > out 2>&1 || fail=1
+$abs_top_builddir/tools/virsh --connect "$url" 'define D.xml; dumpxml D' > out 2>&1 || fail=1
cat > exp <<EOF || fail=1
Domain D defined from D.xml
diff --git a/tests/int-overflow b/tests/int-overflow
index ac3119b..c9f5de9 100755
--- a/tests/int-overflow
+++ b/tests/int-overflow
@@ -2,16 +2,16 @@
# Ensure that an invalid domain ID isn't interpreted as a valid one.
# Before, an ID of 2^32+2 would be treated just like an ID of 2.
-# Boilerplate code to set up a test directory, cd into it,
-# and to ensure we remove it upon completion.
-this_test_() { echo "./$0" | sed 's,.*/,,'; }
-t_=$(this_test_)-$$
-init_cwd_=$(pwd)
-trap 'st=$?; d='"$t_"';
- cd '"$init_cwd_"' && chmod -R u+rwx "$d" && rm -rf "$d" && exit $st' 0
-trap '(exit $?); exit $?' 1 2 13 15
-mkdir "$t_" || fail=1
-cd "$t_" || fail=1
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
+if test "$VERBOSE" = yes; then
+ set -x
+ $abs_top_builddir/tools/virsh --version
+fi
+
+. "$srcdir/test-lib.sh"
echo "error: failed to get domain '4294967298'" > exp || fail=1
echo domname 4294967298 | $abs_top_builddir/tools/virsh --quiet \
diff --git a/tests/libvirtd-fail b/tests/libvirtd-fail
index eeb1ee6..c6b6876 100755
--- a/tests/libvirtd-fail
+++ b/tests/libvirtd-fail
@@ -1,18 +1,20 @@
#!/bin/sh
# Ensure that libvirt fails when given nonexistent --config=FILE
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- libvirtd --version
+ $abs_top_builddir/daemon/libvirtd --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
-test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
. "$srcdir/test-lib.sh"
fail=0
-libvirtd --config=no-such-conf --timeout=5 2> log
+$abs_top_builddir/daemon/libvirtd --config=no-such-conf --timeout=5 2> log
RET=$?
test "$RET" != "0" && exit 0 || exit 1
diff --git a/tests/libvirtd-pool b/tests/libvirtd-pool
index 59da5a6..ca1db94 100755
--- a/tests/libvirtd-pool
+++ b/tests/libvirtd-pool
@@ -1,20 +1,22 @@
#!/bin/sh
# Get coverage of virsh pool-define-as XML formatting
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
-test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
. "$srcdir/test-lib.sh"
fail=0
pwd=$(pwd) || fail=1
-virsh --connect test:///default \
+$abs_top_builddir/tools/virsh --connect test:///default \
pool-define-as --print-xml \
P dir src-host /src/path /src/dev S /target-path \
1>out 2>&1
diff --git a/tests/read-bufsiz b/tests/read-bufsiz
index 7d53735..5baa7c5 100755
--- a/tests/read-bufsiz
+++ b/tests/read-bufsiz
@@ -16,20 +16,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=`pwd`
+test -z "$abs_top_srcdir" && abs_top_srcdir=`pwd`/..
+test -z "$abs_top_builddir" && abs_top_builddir=`pwd`/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-test -z "$srcdir" && srcdir=`pwd`
-test -z "$abs_top_srcdir" && abs_top_srcdir=`pwd`/..
-
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
fail=0
# Output a valid definition, to be used as input.
-virsh -c test:///default dumpxml 1 > xml || fail=1
+$abs_top_builddir/tools/virsh -c test:///default dumpxml 1 > xml || fail=1
for i in before after; do
# The largest BUFSIZ I've seen is 128K. This is slightly larger.
@@ -38,7 +39,7 @@ for i in before after; do
# Append or prepend enough spaces to push the size over the limit:
( test $i = before && cat sp xml || cat xml sp ) > $in || fail=1
- virsh --connect test:///default define $in > out || fail=1
+ $abs_top_builddir/tools/virsh --connect test:///default define $in > out || fail=1
printf "Domain test defined from $in\n\n" > exp || fail=1
compare exp out || fail=1
done
diff --git a/tests/read-non-seekable b/tests/read-non-seekable
index 8a7bdcd..59c2389 100755
--- a/tests/read-non-seekable
+++ b/tests/read-non-seekable
@@ -16,12 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=`pwd`
+test -z "$abs_top_srcdir" && abs_top_srcdir=`pwd`/..
+test -z "$abs_top_builddir" && abs_top_builddir=`pwd`/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
fail=0
@@ -40,11 +44,11 @@ cat <<\EOF > dom
</domain>
EOF
-virsh -c test:///default define dom > /dev/null || fail=1
+$abs_top_builddir/tools/virsh -c test:///default define dom > /dev/null || fail=1
mkfifo_or_skip_ fifo
cat dom > fifo &
-virsh -c test:///default define fifo > /dev/null || fail=1
+$abs_top_builddir/tools/virsh -c test:///default define fifo > /dev/null || fail=1
(exit $fail); exit $fail
diff --git a/tests/start b/tests/start
index f457d59..930a6d9 100755
--- a/tests/start
+++ b/tests/start
@@ -16,13 +16,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
-test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
. "$srcdir/test-lib.sh"
fail=0
@@ -30,7 +32,7 @@ fail=0
test_url=test:///default
# expect this to fail
-virsh -c $test_url start test > out 2> err && fail=1
+$abs_top_builddir/tools/virsh -c $test_url start test > out 2> err && fail=1
# stdout gets a newline
echo > exp || fail=1
diff --git a/tests/test_conf.sh b/tests/test_conf.sh
index 62c2324..682f1f5 100755
--- a/tests/test_conf.sh
+++ b/tests/test_conf.sh
@@ -1,17 +1,19 @@
#!/bin/sh
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+test -z "$abs_srcdir" && abs_srcdir=$(pwd)
+test -z "$abs_builddir" && abs_builddir=$(pwd)
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
set -e
-if test "x$abs_srcdir" = x; then
- abs_srcdir=`pwd`
- abs_builddir=`pwd`
-fi
fail=0
i=1
diff --git a/tests/undefine b/tests/undefine
index fafdae7..48b0ad9 100755
--- a/tests/undefine
+++ b/tests/undefine
@@ -16,17 +16,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
fail=0
# Attempt to undefine a running domain, by domain name.
-virsh -q -c test:///default undefine test > out 2>&1
+$abs_top_builddir/tools/virsh -q -c test:///default undefine test > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: Failed to undefine domain test
@@ -35,7 +39,7 @@ EOF
compare exp out || fail=1
# A different diagnostic when specifying a domain ID
-virsh -q -c test:///default undefine 1 > out 2>&1
+$abs_top_builddir/tools/virsh -q -c test:///default undefine 1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: a running domain like 1 cannot be undefined;
@@ -44,7 +48,7 @@ EOF
compare exp out || fail=1
# Succeed, now: first shut down, then undefine, both via name.
-virsh -q -c test:///default 'shutdown test; undefine test' > out 2>&1
+$abs_top_builddir/tools/virsh -q -c test:///default 'shutdown test; undefine test' > out 2>&1
test $? = 0 || fail=1
cat <<\EOF > exp || fail=1
Domain test is being shutdown
diff --git a/tests/vcpupin b/tests/vcpupin
index 79b02dc..a72ad4c 100755
--- a/tests/vcpupin
+++ b/tests/vcpupin
@@ -16,17 +16,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-. $srcdir/test-lib.sh
+. "$srcdir/test-lib.sh"
fail=0
# Invalid syntax.
-virsh --connect test:///default vcpupin test a 0,1 > out 2>&1
+$abs_top_builddir/tools/virsh --connect test:///default vcpupin test a 0,1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: Invalid or missing vCPU number.
@@ -35,7 +39,7 @@ EOF
compare exp out || fail=1
# An out-of-range vCPU number deserves a diagnostic, too.
-virsh --connect test:///default vcpupin test 100 0,1 > out 2>&1
+$abs_top_builddir/tools/virsh --connect test:///default vcpupin test 100 0,1 > out 2>&1
test $? = 1 || fail=1
cat <<\EOF > exp || fail=1
error: vcpupin: Invalid vCPU number.
diff --git a/tests/virsh-all b/tests/virsh-all
index 03ea466..81b3e57 100755
--- a/tests/virsh-all
+++ b/tests/virsh-all
@@ -16,27 +16,29 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
-test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
. "$srcdir/test-lib.sh"
fail=0
test_url=test:///default
-virsh -c $test_url help > cmds || framework_failure
+$abs_top_builddir/tools/virsh -c $test_url help > cmds || framework_failure
cmds=$(sed -n 's/^ \([^ ][^ ]*\) .*/\1/p' cmds) || framework_failure
test -n "$cmds" || framework_failure
for i in $cmds; do
echo testing $i... 1>&2
# For now, just run the command and ignore output and exit status.
- virsh -c $test_url $i < /dev/null > /dev/null 2>&1
+ $abs_top_builddir/tools/virsh -c $test_url $i < /dev/null > /dev/null 2>&1
done
(exit $fail); exit $fail
diff --git a/tests/virsh-synopsis b/tests/virsh-synopsis
index 24038dd..d72e887 100755
--- a/tests/virsh-synopsis
+++ b/tests/virsh-synopsis
@@ -16,24 +16,27 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+test -z "$srcdir" && srcdir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+
if test "$VERBOSE" = yes; then
set -x
- virsh --version
+ $abs_top_builddir/tools/virsh --version
fi
-test -z "$srcdir" && srcdir=$(pwd)
. "$srcdir/test-lib.sh"
fail=0
test_url=test:///default
-virsh -c $test_url help > cmds || framework_failure
+$abs_top_builddir/tools/virsh -c $test_url help > cmds || framework_failure
cmds=$(sed -n 's/^ \([^ ][^ ]*\) .*/\1/p' cmds) || framework_failure
test -n "$cmds" || framework_failure
for i in $cmds; do
- virsh -c $test_url help $i > help || fail=1
+ $abs_top_builddir/tools/virsh -c $test_url help $i > help || fail=1
grep -A1 '^ SYNOPSIS$' help > synopsis \
|| { echo 1>&2 missing or invalid help SYNOPSIS for $i; fail=1; }
sed -n 2p synopsis > s2 || framework_failure
--
1.6.0.6
15 years, 2 months
[libvirt] [PATCH] Support reporting live interface IP/netmask.
by Laine Stump
From: root <root(a)vlap.laine.org>
This patch adds the flag VIR_INTERFACE_XML_INACTIVE to
virInterfaceGetXMLDesc's flags. When it is *not* set (the default),
the live interface info will be returned in the XML. in particular,
the IP address(es) and netmask(s) will be retrieved by querying the
device directly, rather than just reporting what's in the config
file. The backend of this is in netcf's new ncf_if_xml_state()
function.
Any live interface ip address info in the xml will have the property
"source" set to "device", eg:
<ip address='10.24.0.1' prefix='24' source='device'/>
Also, if an interface is currently inactive, no ip addresses will be
returned, since an inactive interface device can't be queried for IP
addresses (effectively it has none).
A difference in the XML from previously - it is now acceptable to have
both a dhcp *and* an ip node (or neither) within the protocol
node. Before you had to have one or the other, but couldn't have both.
Note that you need at least netcf 0.1.2 for this to build and work,
and an upcoming release (patches submitted today) for it to work
exactly as described above.
---
include/libvirt/libvirt.h.in | 4 +++
src/conf/interface_conf.c | 62 ++++++++++++++++++++++-------------------
src/conf/interface_conf.h | 1 +
src/interface/netcf_driver.c | 8 ++++-
src/libvirt.c | 15 +++++++---
tools/virsh.c | 10 +++++-
6 files changed, 63 insertions(+), 37 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 4e63e48..fd0c90b 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -922,6 +922,10 @@ virInterfacePtr virInterfaceLookupByMACString (virConnectPtr conn,
const char* virInterfaceGetName (virInterfacePtr iface);
const char* virInterfaceGetMACString (virInterfacePtr iface);
+typedef enum {
+ VIR_INTERFACE_XML_INACTIVE = 1 /* dump inactive interface information */
+} virInterfaceXMLFlags;
+
char * virInterfaceGetXMLDesc (virInterfacePtr iface,
unsigned int flags);
virInterfacePtr virInterfaceDefineXML (virConnectPtr conn,
diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
index e646351..b422464 100644
--- a/src/conf/interface_conf.c
+++ b/src/conf/interface_conf.c
@@ -92,6 +92,7 @@ void virInterfaceDefFree(virInterfaceDefPtr def)
VIR_FREE(def->proto.family);
VIR_FREE(def->proto.address);
VIR_FREE(def->proto.gateway);
+ VIR_FREE(def->proto.source);
VIR_FREE(def);
}
@@ -272,6 +273,8 @@ virInterfaceDefParseIp(virConnectPtr conn, virInterfaceDefPtr def,
"%s", _("Invalid ip address prefix value"));
return(-1);
}
+ tmp = virXPathString(conn, "string(./ip[1]/@source)", ctxt);
+ def->proto.source = tmp;
}
tmp = virXPathString(conn, "string(./route[1]/@gateway)", ctxt);
def->proto.gateway = tmp;
@@ -282,22 +285,19 @@ virInterfaceDefParseIp(virConnectPtr conn, virInterfaceDefPtr def,
static int
virInterfaceDefParseProtoIPv4(virConnectPtr conn, virInterfaceDefPtr def,
xmlXPathContextPtr ctxt) {
- xmlNodePtr cur;
- int ret;
+ xmlNodePtr dhcp, ip;
+ int ret = 0;
- cur = virXPathNode(conn, "./dhcp", ctxt);
- if (cur != NULL)
- ret = virInterfaceDefParseDhcp(conn, def, cur, ctxt);
- else {
- cur = virXPathNode(conn, "./ip", ctxt);
- if (cur != NULL)
- ret = virInterfaceDefParseIp(conn, def, cur, ctxt);
- else {
- virInterfaceReportError(conn, VIR_ERR_XML_ERROR,
- "%s", _("interface miss dhcp or ip adressing"));
- ret = -1;
- }
- }
+ dhcp = virXPathNode(conn, "./dhcp", ctxt);
+ if (dhcp != NULL)
+ ret = virInterfaceDefParseDhcp(conn, def, dhcp, ctxt);
+
+ if (ret != 0)
+ return(ret);
+
+ ip = virXPathNode(conn, "./ip", ctxt);
+ if (ip != NULL)
+ ret = virInterfaceDefParseIp(conn, def, ip, ctxt);
return(ret);
}
@@ -1005,6 +1005,7 @@ virInterfaceVlanDefFormat(virConnectPtr conn, virBufferPtr buf,
static int
virInterfaceProtocolDefFormat(virConnectPtr conn ATTRIBUTE_UNUSED,
virBufferPtr buf, const virInterfaceDefPtr def) {
+ char prefixStr[16];
if (def->proto.family == NULL)
return(0);
virBufferVSprintf(buf, " <protocol family='%s'>\n", def->proto.family);
@@ -1015,20 +1016,23 @@ virInterfaceProtocolDefFormat(virConnectPtr conn ATTRIBUTE_UNUSED,
virBufferAddLit(buf, " <dhcp peerdns='yes'/>\n");
else
virBufferAddLit(buf, " <dhcp/>\n");
- } else {
- /* theorically if we don't have dhcp we should have an address */
- if (def->proto.address != NULL) {
- if (def->proto.prefix != 0)
- virBufferVSprintf(buf, " <ip address='%s' prefix='%d'/>\n",
- def->proto.address, def->proto.prefix);
- else
- virBufferVSprintf(buf, " <ip address='%s'/>\n",
- def->proto.address);
- }
- if (def->proto.gateway != NULL) {
- virBufferVSprintf(buf, " <route gateway='%s'/>\n",
- def->proto.gateway);
- }
+ }
+ if (def->proto.address != NULL) {
+ if (def->proto.prefix != 0)
+ snprintf(prefixStr, sizeof(prefixStr), "%d", def->proto.prefix);
+
+ virBufferVSprintf(buf, " <ip address='%s'%s%s%s%s%s%s/>\n",
+ def->proto.address,
+ def->proto.prefix ? " prefix='" : "",
+ def->proto.prefix ? prefixStr : "",
+ def->proto.prefix ? "'" : "",
+ def->proto.source ? " source='" : "",
+ def->proto.source ? def->proto.source : "",
+ def->proto.source ? "'" : "");
+ }
+ if (def->proto.gateway != NULL) {
+ virBufferVSprintf(buf, " <route gateway='%s'/>\n",
+ def->proto.gateway);
}
virBufferAddLit(buf, " </protocol>\n");
return(0);
diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h
index bb9dce4..df871aa 100644
--- a/src/conf/interface_conf.h
+++ b/src/conf/interface_conf.h
@@ -132,6 +132,7 @@ struct _virInterfaceProtocolDef {
char *address; /* ip address */
int prefix; /* ip prefix */
char *gateway; /* route gateway */
+ char *source; /* source of address - "device" or "config" (default) */
};
diff --git a/src/interface/netcf_driver.c b/src/interface/netcf_driver.c
index ca14fb0..b5c3664 100644
--- a/src/interface/netcf_driver.c
+++ b/src/interface/netcf_driver.c
@@ -326,7 +326,7 @@ cleanup:
}
static char *interfaceGetXMLDesc(virInterfacePtr ifinfo,
- unsigned int flags ATTRIBUTE_UNUSED)
+ unsigned int flags)
{
struct interface_driver *driver = ifinfo->conn->interfacePrivateData;
struct netcf_if *iface = NULL;
@@ -342,7 +342,11 @@ static char *interfaceGetXMLDesc(virInterfacePtr ifinfo,
goto cleanup;
}
- xmlstr = ncf_if_xml_desc(iface);
+ if ((flags & VIR_INTERFACE_XML_INACTIVE)) {
+ xmlstr = ncf_if_xml_desc(iface);
+ } else {
+ xmlstr = ncf_if_xml_state(iface);
+ }
if (!xmlstr) {
const char *errmsg, *details;
int errcode = ncf_error(driver->netcf, &errmsg, &details);
diff --git a/src/libvirt.c b/src/libvirt.c
index bcb89e1..bd712dc 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5915,10 +5915,17 @@ virInterfaceGetMACString(virInterfacePtr iface)
/**
* virInterfaceGetXMLDesc:
* @iface: an interface object
- * @flags: an OR'ed set of extraction flags, not used yet
+ * @flags: an OR'ed set of extraction flags. Current valid bits:
+ *
+ * VIR_INTERFACE_XML_INACTIVE - return the static configuration,
+ * suitable for use redefining the
+ * interface via virInterfaceDefineXML()
*
- * Provide an XML description of the interface. The description may be reused
- * later to redefine the interface with virInterfaceDefineXML().
+ * Provide an XML description of the interface. If
+ * VIR_INTERFACE_XML_INACTIVE is set, the description may be reused
+ * later to redefine the interface with virInterfaceDefineXML(). If it
+ * is not set, the ip address and netmask will be the current live
+ * setting of the interface, not the settings from the config files.
*
* Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
* the caller must free() the returned value.
@@ -5935,7 +5942,7 @@ virInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
return (NULL);
}
- if (flags != 0) {
+ if ((flags & ~VIR_INTERFACE_XML_INACTIVE) != 0) {
virLibInterfaceError(iface, VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
diff --git a/tools/virsh.c b/tools/virsh.c
index 3482389..77f1d70 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2763,7 +2763,7 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd)
char *doc = NULL;
char *doc_edited = NULL;
char *doc_reread = NULL;
- int flags = 0;
+ int flags = VIR_INTERFACE_XML_INACTIVE;
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
goto cleanup;
@@ -3297,6 +3297,7 @@ static const vshCmdInfo info_interface_dumpxml[] = {
static const vshCmdOptDef opts_interface_dumpxml[] = {
{"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface name or MAC address")},
+ {"inactive", VSH_OT_BOOL, 0, gettext_noop("show inactive defined XML")},
{NULL, 0, 0, NULL}
};
@@ -3306,6 +3307,11 @@ cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
virInterfacePtr iface;
int ret = TRUE;
char *dump;
+ int flags = 0;
+ int inactive = vshCommandOptBool(cmd, "inactive");
+
+ if (inactive)
+ flags |= VIR_INTERFACE_XML_INACTIVE;
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE;
@@ -3313,7 +3319,7 @@ cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd)
if (!(iface = vshCommandOptInterface(ctl, cmd, NULL)))
return FALSE;
- dump = virInterfaceGetXMLDesc(iface, 0);
+ dump = virInterfaceGetXMLDesc(iface, flags);
if (dump != NULL) {
printf("%s", dump);
free(dump);
--
1.6.2.5
15 years, 2 months