1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-09-29 13:44:45 +03:00

Compare commits

..

13 Commits

Author SHA1 Message Date
Ján Tomko
415cc5c064 api: disallow virConnect*HypervisorCPU on read-only connections
These APIs can be used to execute arbitrary emulators.
Forbid them on read-only connections.

Fixes: CVE-2019-10168
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit bf6c2830b6)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
fd16bd525a api: disallow virConnectGetDomainCapabilities on read-only connections
This API can be used to execute arbitrary emulators.
Forbid it on read-only connections.

Fixes: CVE-2019-10167
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 8afa68bac0)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
d025c10d54 api: disallow virDomainManagedSaveDefineXML on read-only connections
The virDomainManagedSaveDefineXML can be used to alter the domain's
config used for managedsave or even execute arbitrary emulator binaries.
Forbid it on read-only connections.

Fixes: CVE-2019-10166
Reported-by: Matthias Gerstner <mgerstner@suse.de>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit db0b78457f)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Ján Tomko
6a028b6e82 api: disallow virDomainSaveImageGetXMLDesc on read-only connections
The virDomainSaveImageGetXMLDesc API is taking a path parameter,
which can point to any path on the system. This file will then be
read and parsed by libvirtd running with root privileges.

Forbid it on read-only connections.

Fixes: CVE-2019-10161
Reported-by: Matthias Gerstner <mgerstner@suse.de>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit aed6a032ce)
Signed-off-by: Ján Tomko <jtomko@redhat.com>

Conflicts:
  src/libvirt-domain.c
  src/remote/remote_protocol.x

Upstream commit 12a51f372 which introduced the VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
alias for VIR_DOMAIN_XML_SECURE is not backported.
Just skip the commit since we now disallow the whole API on read-only
connections, regardless of the flag.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
2019-06-24 09:56:23 +02:00
Daniel P. Berrangé
ec58805400 logging: restrict sockets to mode 0600
The virtlogd daemon's only intended client is the libvirtd daemon. As
such it should never allow clients from other user accounts to connect.
The code already enforces this and drops clients from other UIDs, but
we can get earlier (and thus stronger) protection against DoS by setting
the socket permissions to 0600

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit e37bd65f99)
2019-05-21 13:30:02 +01:00
Daniel P. Berrangé
618358632b locking: restrict sockets to mode 0600
The virtlockd daemon's only intended client is the libvirtd daemon. As
such it should never allow clients from other user accounts to connect.
The code already enforces this and drops clients from other UIDs, but
we can get earlier (and thus stronger) protection against DoS by setting
the socket permissions to 0600

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f111e09468)
2019-05-21 13:30:01 +01:00
Daniel P. Berrangé
d1017aeee9 admin: reject clients unless their UID matches the current UID
The admin protocol RPC messages are only intended for use by the user
running the daemon. As such they should not be allowed for any client
UID that does not match the server UID.

Fixes CVE-2019-10132

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 96f41cd765)
2019-05-21 13:30:01 +01:00
Luyao Huang
35176b5c78 virDomainConfNWFilterInstantiate: initialize @xml to avoid random crash
If the code jump to the cleanup before assigning value to @xml
libvirtd may crash when it tries to free an uninitialized pointer.

backtrace:

0  0x00007ffff428d59c in free () from /lib64/libc.so.6
1  0x00007ffff721314a in virFree (ptrptr=ptrptr@entry=0x7fffc67f1b00) at util/viralloc.c:582
2  0x00007ffff7345ac4 in virDomainConfNWFilterInstantiate (vmname=<optimized out>,
   vmuuid=vmuuid@entry=0x7fffc0181ca8 "߉\237\\۔H\262\206z\340\302f\265\233z", net=<optimized out>,
   ignoreExists=ignoreExists@entry=true) at conf/domain_nwfilter.c:122
3  0x00007fffca5a77f6 in qemuProcessFiltersInstantiate (ignoreExists=true, def=0x7fffc0181ca0) at qemu/qemu_process.c:3028
4  qemuProcessReconnect (opaque=<optimized out>) at qemu/qemu_process.c:7653
5  0x00007ffff72c4895 in virThreadHelper (data=<optimized out>) at util/virthread.c:206
6  0x00007ffff45dcdd5 in start_thread () from /lib64/libpthread.so.0
7  0x00007ffff4305ead in clone () from /lib64/libc.so.6

Signed-off-by: Luyao Huang <lhuang@redhat.com>
(cherry picked from commit d7557f5f6f)
2018-07-06 14:31:47 +01:00
Daniel P. Berrangé
6aedf9bfad qemu: fix UNIX socket chardevs operating in client mode
When support was adding for passing a pre-opened listener socket to UNIX
chardevs, it accidentally passed the listener socket for client mode
chardevs too with predictable amounts of fail resulting. This affects
libvirt when using QEMU >= 2.12

Expand the unit test coverage to validate that we are only doing FD
passing when operating in server mode.

  https://bugzilla.redhat.com/show_bug.cgi?id=1598440

Tested-by: Richard W.M. Jones <rjones@redhat.com>
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1bc1a7e320)
2018-07-06 14:31:35 +01:00
Daniel P. Berrangé
78920738ca qemu: don't use chardev FD passing for vhostuser backend
QEMU chardevs have a bug which makes the vhostuser backend complain
about lack of support for FD passing when validating the chardev.
While this is ultimately QEMU's responsibility to fix, libvirt needs to
avoid tickling the bug.

Simply disabling chardev FD passing just for vhostuser's chardev is
the most prudent approach, avoiding need for a QEMU version number
check.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit ed5aa85f37)
2018-07-06 14:31:29 +01:00
Daniel P. Berrangé
88924317f3 qemu: consolidate parameters of qemuBuildChrChardevStr into flags
There are two boolean parameters passed to qemuBuildChrChardevStr,
and soon there will be a third. It will be clearer to understand
from callers' POV if we use named flags instead.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0140d4c59b)
2018-07-06 14:31:23 +01:00
Daniel P. Berrangé
941ca31e90 qemu: remove chardevStdioLogd param from vhostuser code path
The vhostuser network backend is only supported with the UNIX domain
socket chardev backend, so passing around chardevStdioLogd is not
required.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 4c76266bac)
2018-07-06 14:31:15 +01:00
Daniel P. Berrangé
3818514602 qemu: don't use chardev FD passing with standalone args
When using domxml-to-native, we must generate CLI args that can be used
in a standalone scenario. This means no FD passing can be used. To
achieve this we must clear the QEMU_CAPS_CHARDEV_FD_PASS capability bit.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 7ac08cc929)
2018-07-06 14:30:43 +01:00
3599 changed files with 77778 additions and 281794 deletions

1
.ctags
View File

@@ -3,4 +3,3 @@
--exclude=*.html
--exclude=*.html.in
--langmap=c:+.h.in
--c-kinds=+p

2
.gitignore vendored
View File

@@ -11,6 +11,7 @@
*.gcov
*.html
*.i
*.init
*.la
*.lo
*.loT
@@ -189,6 +190,7 @@
/tools/virt-admin
/tools/virt-*-validate
/tools/virt-sanlock-cleanup
/tools/wireshark/src/plugin.c
/tools/wireshark/src/libvirt
/update.log
GPATH

Submodule .gnulib updated: 8089c00979...d6397dde2e

View File

@@ -20,6 +20,7 @@
<jfehlig@suse.com> <jfehlig@novell.com>
<jfehlig@suse.com> <jfehlig@linux-ypgk.site>
<jclift@redhat.com> <justin@salasaga.org>
<berrange@redhat.com> <dan@berrange.com>
<soren@linux2go.dk> <soren@canonical.com>
<cfergeau@redhat.com> <teuf@gnome.org>
<wency@cn.fujitsu.com> <wency cn fujitsu com>
@@ -38,11 +39,6 @@
<zhlcindy@linux.vnet.ibm.com> <zhlcindy@gmail.com>
<serge.hallyn@canonical.com> <serue@us.ibm.com>
<pritesh.kothari@sun.com> <Pritesh.Kothari@Sun.COM>
<cbosdonnat@suse.com> <cedric.bosdonnat@free.fr>
<mnestratov@virtuozzo.com> <mnestratov@parallels.com>
<nshirokovskiy@virtuozzo.com> <nshirokovskiy@parallels.com>
<jyang@redhat.com> <osier@yunify.com>
<kkoukiou@redhat.com> <k.koukiou@googlemail.com>
# Name consolidation:
# Preferred author spelling <preferred email>
@@ -60,16 +56,9 @@ Aurelien Rougemont <beorn@binaries.fr>
Serge E. Hallyn <serge.hallyn@canonical.com>
Henrik Persson E <henrik.e.persson@ericsson.com>
Philipp Hahn <hahn@univention.de>
Marco Bozzolan <bozzolan@gmail.com>
Marco Bozzolan <redshift@gmx.com>
Pritesh Kothari <pritesh.kothari@sun.com>
Wang Yufei (James) <james.wangyufei@huawei.com>
Deepak C Shetty <dpkshetty@gmail.com>
Dave Allan <dallan@redhat.com>
Richard W.M. Jones <rjones@redhat.com>
# Non-trivial consolidation:
# see git documentation for information about the format
Daniel P. Berrangé <berrange@redhat.com>
Daniel P. Berrangé <berrange@redhat.com> <dan@berrange.com>
Michal Prívozník <mprivozn@redhat.com>
Michal Prívozník <mprivozn@redhat.com> <miso.privoznik@gmail.com>
Marco Bozzolan <bozzolan@gmail.com> <redshift@gmx.com>

View File

@@ -11,11 +11,13 @@ matrix:
- docker
env:
- IMAGE="ubuntu-18"
- DISTCHECK_CONFIGURE_FLAGS="--with-init-script=systemd"
- DOCKER_CMD="$LINUX_CMD"
- services:
- docker
env:
- IMAGE="centos-7"
- DISTCHECK_CONFIGURE_FLAGS="--with-init-script=upstart"
- DOCKER_CMD="$LINUX_CMD"
- services:
- docker
@@ -43,7 +45,8 @@ script:
-w /build
-e VIR_TEST_DEBUG="$VIR_TEST_DEBUG"
-e MINGW="$MINGW"
"quay.io/libvirt/buildenv-$IMAGE:master"
-e DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS"
"libvirt/buildenv-$IMAGE"
/bin/sh -xc "$DOCKER_CMD"
git:
@@ -55,7 +58,7 @@ env:
- LINUX_CMD="
./autogen.sh &&
make -j3 syntax-check &&
make -j3 distcheck ||
make -j3 distcheck DISTCHECK_CONFIGURE_FLAGS=\"\$DISTCHECK_CONFIGURE_FLAGS\" ||
(
echo '=== LOG FILE(S) START ===';
find -name test-suite.log | xargs cat;

View File

@@ -14,7 +14,7 @@ Christian Ehrhardt <christian.ehrhardt@canonical.com>
Christophe Fergeau <cfergeau@redhat.com>
Claudio Bley <claudio.bley@gmail.com>
Cole Robinson <crobinso@redhat.com>
Daniel P. Berrangé <berrange@redhat.com>
Daniel Berrange <berrange@redhat.com>
Daniel Veillard <veillard@redhat.com>
Doug Goldstein <cardoe@gentoo.org>
Eric Blake <eblake@redhat.com>
@@ -25,7 +25,6 @@ Ján Tomko <jtomko@redhat.com>
Jim Fehlig <jfehlig@suse.com>
Jiří Denemark <jdenemar@redhat.com>
John Ferlan <jferlan@redhat.com>
Katerina Koukiou <kkoukiou@redhat.com>
Laine Stump <laine@redhat.com>
Mark McLoughlin <markmc@redhat.com>
Martin Kletzander <mkletzan@redhat.com>
@@ -91,7 +90,9 @@ Stefan de Konink <dekonink@kinkrsoftware.nl>
Takahashi Tomohiro <takatom@jp.fujitsu.com>
Tatsuro Enokura <fj7716hz@aa.jp.fujitsu.com>
#contributorslist#
#authorslist#
[....send patches to get your name here....]
The libvirt logo was designed by Diana Fong

View File

@@ -16,15 +16,15 @@
## License along with this library. If not, see
## <http://www.gnu.org/licenses/>.
LCOV = lcov
GENHTML = genhtml
SUBDIRS = . gnulib/lib include/libvirt src tools docs gnulib/tests \
tests po examples
XZ_OPT ?= -v -T0
export XZ_OPT
# have gnulib 'make coverage' output to 'cov' dir
COVERAGE_OUT = "cov"
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = \
@@ -77,6 +77,20 @@ check-local: all tests
check-access:
@($(MAKE) $(AM_MAKEFLAGS) -C tests check-access)
cov: clean-cov
$(MKDIR_P) $(top_builddir)/coverage
$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp \
-d $(top_builddir)/src -d $(top_builddir)/daemon \
-d $(top_builddir)/tests
$(LCOV) -r $(top_builddir)/coverage/libvirt.info.tmp \
-o $(top_builddir)/coverage/libvirt.info
rm $(top_builddir)/coverage/libvirt.info.tmp
$(GENHTML) --show-details -t "libvirt" -o $(top_builddir)/coverage \
--legend $(top_builddir)/coverage/libvirt.info
clean-cov:
rm -rf $(top_builddir)/coverage
MAINTAINERCLEANFILES = .git-module-status
dist-hook: gen-ChangeLog gen-AUTHORS
@@ -95,17 +109,9 @@ gen-ChangeLog:
.PHONY: gen-AUTHORS
gen-AUTHORS:
$(AM_V_GEN)\
if test -d $(srcdir)/.git; then \
( \
cd $(srcdir) && \
git log --pretty=format:'%aN <%aE>' | sort -u \
) > all.list && \
sort -u $(srcdir)/AUTHORS.in > maint.list && \
comm -23 all.list maint.list > contrib.list && \
contrib="`cat contrib.list`" && \
perl -p -e "s/#contributorslist#// and print '$$contrib'" \
< $(srcdir)/AUTHORS.in > $(distdir)/AUTHORS-tmp && \
mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS && \
rm -f all.list maint.list contrib.list; \
$(AM_V_GEN)if test -d $(srcdir)/.git; then \
out="`cd $(srcdir) && git log --pretty=format:'%aN <%aE>' | sort -u`" && \
perl -p -e "s/#authorslist#// and print '$$out'" \
< $(srcdir)/AUTHORS.in > $(distdir)/AUTHORS-tmp && \
mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS ; \
fi

295
bootstrap
View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Print a version string.
scriptversion=2019-01-04.17; # UTC
scriptversion=2018-03-07.03; # UTC
# Bootstrap this package from checked-out sources.
# Copyright (C) 2003-2019 Free Software Foundation, Inc.
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -47,8 +47,6 @@ PERL="${PERL-perl}"
me=$0
default_gnulib_url=git://git.sv.gnu.org/gnulib
usage() {
cat <<EOF
Usage: $me [OPTION]...
@@ -78,37 +76,6 @@ contents are read as shell variables to configure the bootstrap.
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
are honored.
Gnulib sources can be fetched in various ways:
* If this package is in a git repository with a 'gnulib' submodule
configured, then that submodule is initialized and updated and sources
are fetched from there. If \$GNULIB_SRCDIR is set (directly or via
--gnulib-srcdir) and is a git repository, then it is used as a reference.
* Otherwise, if \$GNULIB_SRCDIR is set (directly or via --gnulib-srcdir),
then sources are fetched from that local directory. If it is a git
repository and \$GNULIB_REVISION is set, then that revision is checked
out.
* Otherwise, if this package is in a git repository with a 'gnulib'
submodule configured, then that submodule is initialized and updated and
sources are fetched from there.
* Otherwise, if the 'gnulib' directory does not exist, Gnulib sources are
cloned into that directory using git from \$GNULIB_URL, defaulting to
$default_gnulib_url.
If \$GNULIB_REVISION is set, then that revision is checked out.
* Otherwise, the existing Gnulib sources in the 'gnulib' directory are
used. If it is a git repository and \$GNULIB_REVISION is set, then that
revision is checked out.
If you maintain a package and want to pin a particular revision of the
Gnulib sources that has been tested with your package, then there are two
possible approaches: either configure a 'gnulib' submodule with the
appropriate revision, or set \$GNULIB_REVISION (and if necessary
\$GNULIB_URL) in $me.conf.
Running without arguments will suffice in most cases.
EOF
}
@@ -162,11 +129,18 @@ bootstrap_post_import_hook() { :; }
# Override it via your own definition in bootstrap.conf.
bootstrap_epilogue() { :; }
# The command to download all .po files for a specified domain into a
# specified directory. Fill in the first %s with the destination
# directory and the second with the domain name.
# The command to download all .po files for a specified domain into
# a specified directory. Fill in the first %s is the domain name, and
# the second with the destination directory. Use rsync's -L and -r
# options because the latest/%s directory and the .po files within are
# all symlinks.
po_download_command_format=\
"wget --mirror --level=1 -nd -q -A.po -P '%s' \
"rsync --delete --exclude '*.s1' -Lrtvz \
'translationproject.org::tp/latest/%s/' '%s'"
# Fallback for downloading .po files (if rsync fails).
po_download_command_format2=\
"wget --mirror -nd -q -np -A.po -P '%s' \
https://translationproject.org/latest/%s/"
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
@@ -196,15 +170,7 @@ source_base=lib
m4_base=m4
doc_base=doc
tests_base=tests
gnulib_extra_files="
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
doc/INSTALL
"
gnulib_extra_files=''
# Additional gnulib-tool options to use. Use "\newline" to break lines.
gnulib_tool_option_extras=
@@ -298,18 +264,24 @@ case "$0" in
*) test -r "$0.conf" && . ./"$0.conf" ;;
esac
# Extra files from gnulib, which override files from other sources.
test -z "${gnulib_extra_files}" && \
gnulib_extra_files="
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
doc/INSTALL
"
if test "$vc_ignore" = auto; then
vc_ignore=
test -d .git && vc_ignore=.gitignore
test -d CVS && vc_ignore="$vc_ignore .cvsignore"
fi
if test x"$gnulib_modules$gnulib_files$gnulib_extra_files" = x; then
use_gnulib=false
else
use_gnulib=true
fi
# Translate configuration into internal form.
# Parse options.
@@ -640,101 +612,95 @@ git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@"
}
if $use_gnulib; then
if $use_git; then
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
if $use_git; then
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
fi
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
# submodule, for use in the rest of the script.
case ${GNULIB_SRCDIR--} in
-)
# Note that $use_git is necessarily true in this case.
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init -- "$gnulib_path" || exit $?
git submodule update -- "$gnulib_path" || exit $?
elif [ ! -d "$gnulib_path" ]; then
echo "$0: getting gnulib files..."
trap cleanup_gnulib 1 2 13 15
shallow=
git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" ||
cleanup_gnulib
trap - 1 2 13 15
fi
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
# submodule, for use in the rest of the script.
case ${GNULIB_SRCDIR--} in
-)
# Note that $use_git is necessarily true in this case.
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init -- "$gnulib_path" || exit $?
git submodule update -- "$gnulib_path" || exit $?
elif [ ! -d "$gnulib_path" ]; then
echo "$0: getting gnulib files..."
trap cleanup_gnulib 1 2 13 15
shallow=
if test -z "$GNULIB_REVISION"; then
git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
GNULIB_SRCDIR=$gnulib_path
;;
*)
# Use GNULIB_SRCDIR directly or as a reference.
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
# Prefer the one-liner available in git 1.6.4 or newer.
git submodule update --init --reference "$GNULIB_SRCDIR" \
"$gnulib_path" || exit $?
else
# This fallback allows at least git 1.5.5.
if test -f "$gnulib_path"/gnulib-tool; then
# Since file already exists, assume submodule init already complete.
git submodule update -- "$gnulib_path" || exit $?
else
# Older git can't clone into an empty directory.
rmdir "$gnulib_path" 2>/dev/null
git clone --reference "$GNULIB_SRCDIR" \
"$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
&& git submodule init -- "$gnulib_path" \
&& git submodule update -- "$gnulib_path" \
|| exit $?
fi
git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \
|| cleanup_gnulib
trap - 1 2 13 15
fi
GNULIB_SRCDIR=$gnulib_path
;;
*)
# Use GNULIB_SRCDIR directly or as a reference.
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
# Prefer the one-liner available in git 1.6.4 or newer.
git submodule update --init --reference "$GNULIB_SRCDIR" \
"$gnulib_path" || exit $?
else
# This fallback allows at least git 1.5.5.
if test -f "$gnulib_path"/gnulib-tool; then
# Since file already exists, assume submodule init already complete.
git submodule update -- "$gnulib_path" || exit $?
else
# Older git can't clone into an empty directory.
rmdir "$gnulib_path" 2>/dev/null
git clone --reference "$GNULIB_SRCDIR" \
"$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
&& git submodule init -- "$gnulib_path" \
&& git submodule update -- "$gnulib_path" \
|| exit $?
fi
fi
GNULIB_SRCDIR=$gnulib_path
fi
;;
esac
if test -d "$GNULIB_SRCDIR"/.git && test -n "$GNULIB_REVISION" \
&& ! git_modules_config submodule.gnulib.url >/dev/null; then
(cd "$GNULIB_SRCDIR" && git checkout "$GNULIB_REVISION") || cleanup_gnulib
fi
;;
esac
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
if $bootstrap_sync; then
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
echo "$0: updating bootstrap and restarting..."
case $(sh -c 'echo "$1"' -- a) in
a) ignored=--;;
*) ignored=ignored;;
esac
exec sh -c \
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
"$0" "$@" --no-bootstrap-sync
}
fi
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit $?
if $bootstrap_sync; then
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
echo "$0: updating bootstrap and restarting..."
case $(sh -c 'echo "$1"' -- a) in
a) ignored=--;;
*) ignored=ignored;;
esac
exec sh -c \
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
"$0" "$@" --no-bootstrap-sync
}
fi
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit $?
# Get translations.
download_po_files() {
subdir=$1
domain=$2
echo "$me: getting translations into $subdir for $domain..."
cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
cmd=$(printf "$po_download_command_format" "$domain" "$subdir")
eval "$cmd" && return
# Fallback to HTTPS.
cmd=$(printf "$po_download_command_format2" "$subdir" "$domain")
eval "$cmd"
}
@@ -932,47 +898,36 @@ fi
# Import from gnulib.
if $use_gnulib; then
gnulib_tool_options="\
--no-changelog\
--aux-dir=$build_aux\
--doc-base=$doc_base\
--lib=$gnulib_name\
--m4-base=$m4_base/\
--source-base=$source_base/\
--tests-base=$tests_base\
--local-dir=$local_gl_dir\
$gnulib_tool_option_extras\
"
if test $use_libtool = 1; then
case "$gnulib_tool_options " in
*' --libtool '*) ;;
*) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
esac
fi
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
$gnulib_tool $gnulib_tool_options --import $gnulib_modules \
|| die "gnulib-tool failed"
for file in $gnulib_files; do
symlink_to_dir "$GNULIB_SRCDIR" $file \
|| die "failed to symlink $file"
done
gnulib_tool_options="\
--import\
--no-changelog\
--aux-dir $build_aux\
--doc-base $doc_base\
--lib $gnulib_name\
--m4-base $m4_base/\
--source-base $source_base/\
--tests-base $tests_base\
--local-dir $local_gl_dir\
$gnulib_tool_option_extras\
"
if test $use_libtool = 1; then
case "$gnulib_tool_options " in
*' --libtool '*) ;;
*) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
esac
fi
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
$gnulib_tool $gnulib_tool_options --import $gnulib_modules \
|| die "gnulib-tool failed"
for file in $gnulib_files; do
symlink_to_dir "$GNULIB_SRCDIR" $file \
|| die "failed to symlink $file"
done
bootstrap_post_import_hook \
|| die "bootstrap_post_import_hook failed"
# Don't proceed if there are uninitialized submodules. In particular,
# the next step will remove dangling links, which might be links into
# uninitialized submodules.
#
# Uninitialized submodules are listed with an initial dash.
if $use_git && git submodule | grep '^-' >/dev/null; then
die "some git submodules are not initialized. " \
"Run 'git submodule init' and bootstrap again."
fi
# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
# gnulib-populated directories. Such .m4 files would cause aclocal to fail.
# The following requires GNU find 4.2.3 or newer. Considering the usual

View File

@@ -10,7 +10,7 @@
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# GNU General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see
@@ -126,7 +126,6 @@ vc-list-files
vsnprintf
waitpid
warnings
wcwidth
'
SKIP_PO=true

View File

@@ -16,6 +16,9 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
# Authors:
# Daniel P. Berrange <berrange@redhat.com>
use strict;
use warnings;

View File

@@ -16,6 +16,9 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
# Authors:
# Daniel P. Berrange <berrange@redhat.com>
use strict;
use warnings;
@@ -42,6 +45,9 @@ foreach my $file (@ARGV) {
# Kill any quoted strings
$data =~ s,"(?:[^\\\"]|\\.)*","XXX",g;
# Kill any C++ style comments
$data =~ s,//.*$,//,;
next if $data =~ /^#/;
# Kill contents of multi-line comments

View File

@@ -1,156 +0,0 @@
#!/usr/bin/perl
#
# Validate that header files follow a standard layout:
#
# /*
# ...copyright header...
# */
# <one blank line>
# #ifndef SYMBOL
# # define SYMBOL
# ....content....
# #endif /* SYMBOL */
#
# For any file ending priv.h, before the #ifndef
# We will have a further section
#
# #ifndef SYMBOL_ALLOW
# # error ....
# #endif /* SYMBOL_ALLOW */
# <one blank line>
use strict;
use warnings;
my $STATE_COPYRIGHT_COMMENT = 0;
my $STATE_COPYRIGHT_BLANK = 1;
my $STATE_PRIV_START = 2;
my $STATE_PRIV_ERROR = 3;
my $STATE_PRIV_END = 4;
my $STATE_PRIV_BLANK = 5;
my $STATE_GUARD_START = 6;
my $STATE_GUARD_DEFINE = 7;
my $STATE_GUARD_END = 8;
my $STATE_EOF = 9;
my $file = " ";
my $ret = 0;
my $ifdef = "";
my $ifdefpriv = "";
my $state = $STATE_EOF;
my $mistake = 0;
sub mistake {
my $msg = shift;
warn $msg;
$mistake = 1;
$ret = 1;
}
while (<>) {
if (not $file eq $ARGV) {
if ($state == $STATE_COPYRIGHT_COMMENT) {
&mistake("$file: missing copyright comment");
} elsif ($state == $STATE_COPYRIGHT_BLANK) {
&mistake("$file: missing blank line after copyright header");
} elsif ($state == $STATE_PRIV_START) {
&mistake("$file: missing '#ifndef $ifdefpriv'");
} elsif ($state == $STATE_PRIV_ERROR) {
&mistake("$file: missing '# error ...priv allow...'");
} elsif ($state == $STATE_PRIV_END) {
&mistake("$file: missing '#endif /* $ifdefpriv */'");
} elsif ($state == $STATE_PRIV_BLANK) {
&mistake("$file: missing blank line after priv header check");
} elsif ($state == $STATE_GUARD_START) {
&mistake("$file: missing '#ifndef $ifdef'");
} elsif ($state == $STATE_GUARD_DEFINE) {
&mistake("$file: missing '# define $ifdef'");
} elsif ($state == $STATE_GUARD_END) {
&mistake("$file: missing '#endif /* $ifdef */'");
}
$ifdef = uc $ARGV;
$ifdef =~ s,.*/,,;
$ifdef =~ s,[^A-Z0-9],_,g;
$ifdef =~ s,__+,_,g;
unless ($ifdef =~ /^LIBVIRT_/ && $ARGV !~ /libvirt_internal.h/) {
$ifdef = "LIBVIRT_" . $ifdef;
}
$ifdefpriv = $ifdef . "_ALLOW";
$file = $ARGV;
$state = $STATE_COPYRIGHT_COMMENT;
$mistake = 0;
}
if ($mistake ||
$ARGV =~ /config-post\.h$/ ||
$ARGV =~ /vbox_(CAPI|XPCOM)/) {
$state = $STATE_EOF;
next;
}
if ($state == $STATE_COPYRIGHT_COMMENT) {
if (m,\*/,) {
$state = $STATE_COPYRIGHT_BLANK;
}
} elsif ($state == $STATE_COPYRIGHT_BLANK) {
if (! /^$/) {
&mistake("$file: missing blank line after copyright header");
}
if ($ARGV =~ /priv\.h$/) {
$state = $STATE_PRIV_START;
} else {
$state = $STATE_GUARD_START;
}
} elsif ($state == $STATE_PRIV_START) {
if (/^$/) {
&mistake("$file: too many blank lines after coyright header");
} elsif (/#ifndef $ifdefpriv$/) {
$state = $STATE_PRIV_ERROR;
} else {
&mistake("$file: missing '#ifndef $ifdefpriv'");
}
} elsif ($state == $STATE_PRIV_ERROR) {
if (/# error ".*"$/) {
$state = $STATE_PRIV_END;
} else {
&mistake("$file: missing '#error ...priv allow...'");
}
} elsif ($state == $STATE_PRIV_END) {
if (m,#endif /\* $ifdefpriv \*/,) {
$state = $STATE_PRIV_BLANK;
} else {
&mistake("$file: missing '#endif /* $ifdefpriv */'");
}
} elsif ($state == $STATE_PRIV_BLANK) {
if (! /^$/) {
&mistake("$file: missing blank line after priv guard");
}
$state = $STATE_GUARD_START;
} elsif ($state == $STATE_GUARD_START) {
if (/^$/) {
&mistake("$file: too many blank lines after coyright header");
} elsif (/#ifndef $ifdef$/) {
$state = $STATE_GUARD_DEFINE;
} else {
&mistake("$file: missing '#ifndef $ifdef'");
}
} elsif ($state == $STATE_GUARD_DEFINE) {
if (/# define $ifdef$/) {
$state = $STATE_GUARD_END;
} else {
&mistake("$file: missing '# define $ifdef'");
}
} elsif ($state == $STATE_GUARD_END) {
if (m,#endif /\* $ifdef \*/$,) {
$state = $STATE_EOF;
}
} elsif ($state == $STATE_EOF) {
die "$file: unexpected content after '#endif /* $ifdef */'";
} else {
die "$file: unexpected state $state";
}
}
exit $ret;

140
cfg.mk
View File

@@ -1,5 +1,5 @@
# Customize Makefile.maint. -*- makefile -*-
# Copyright (C) 2008-2019 Red Hat, Inc.
# Copyright (C) 2008-2015 Red Hat, Inc.
# Copyright (C) 2003-2008 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
@@ -120,6 +120,7 @@ useless_free_options = \
--name=virConfFreeValue \
--name=virDomainActualNetDefFree \
--name=virDomainChrDefFree \
--name=virDomainChrSourceDefFree \
--name=virDomainControllerDefFree \
--name=virDomainDefFree \
--name=virDomainDeviceDefFree \
@@ -304,11 +305,10 @@ sc_flags_usage:
$(srcdir)/include/libvirt/libvirt-qemu.h \
$(srcdir)/include/libvirt/libvirt-lxc.h \
$(srcdir)/include/libvirt/libvirt-admin.h \
| $(GREP) -c '\(long\|unsigned\) flags')" != 4 && \
| grep -c '\(long\|unsigned\) flags')" != 4 && \
{ echo '$(ME): new API should use "unsigned int flags"' 1>&2; \
exit 1; } || :
@prohibit=' flags ATTRIBUTE_UNUSED' \
exclude='virSecurityDomainImageLabelFlags' \
halt='flags should be checked with virCheckFlags' \
$(_sc_search_regexp)
@prohibit='^[^@]*([^d] (int|long long)|[^dg] long) flags[;,)]' \
@@ -472,7 +472,6 @@ sc_prohibit_canonicalize_file_name:
# Insist on correct types for [pug]id.
sc_correct_id_types:
@prohibit='\<(int|long) *[pug]id\>' \
exclude='exempt from syntax-check' \
halt='use pid_t for pid, uid_t for uid, gid_t for gid' \
$(_sc_search_regexp)
@@ -639,12 +638,10 @@ sc_libvirt_unmarked_diagnostics:
exclude='_\(' \
halt='found unmarked diagnostic(s)' \
$(_sc_search_regexp)
@{ $(VC_LIST_EXCEPT) | xargs \
$(GREP) -nE '\<$(func_re) *\(.*;$$' /dev/null; \
$(VC_LIST_EXCEPT) | xargs \
$(GREP) -A1 -nE '\<$(func_re) *\(.*,$$' /dev/null; } \
| $(SED) -E 's/_\("([^\"]|\\.)+"//;s/"%s"//' \
| $(GREP) '"' && \
@{ grep -nE '\<$(func_re) *\(.*;$$' $$($(VC_LIST_EXCEPT)); \
grep -A1 -nE '\<$(func_re) *\(.*,$$' $$($(VC_LIST_EXCEPT)); } \
| $(SED) 's/_("\([^\"]\|\\.\)\+"//;s/[ ]"%s"//' \
| grep '[ ]"' && \
{ echo '$(ME): found unmarked diagnostic(s)' 1>&2; \
exit 1; } || :
@@ -656,9 +653,9 @@ sc_libvirt_unmarked_diagnostics:
# there are functions to which this one applies but that do not get marked
# diagnostics.
sc_prohibit_newline_at_end_of_diagnostic:
@$(VC_LIST_EXCEPT) | xargs $(GREP) -A2 -nE \
'\<$(func_re) *\(' /dev/null \
| $(GREP) '\\n"' \
@grep -A2 -nE \
'\<$(func_re) *\(' $$($(VC_LIST_EXCEPT)) \
| grep '\\n"' \
&& { echo '$(ME): newline at end of message(s)' 1>&2; \
exit 1; } || :
@@ -666,14 +663,12 @@ sc_prohibit_newline_at_end_of_diagnostic:
# allow VIR_ERROR to do this, and ignore functions that take a single
# string rather than a format argument.
sc_prohibit_diagnostic_without_format:
@{ $(VC_LIST_EXCEPT) | xargs \
$(GREP) -nE '\<$(func_re) *\(.*;$$' /dev/null; \
$(VC_LIST_EXCEPT) | xargs \
$(GREP) -A2 -nE '\<$(func_re) *\(.*,$$' /dev/null; } \
@{ grep -nE '\<$(func_re) *\(.*;$$' $$($(VC_LIST_EXCEPT)); \
grep -A2 -nE '\<$(func_re) *\(.*,$$' $$($(VC_LIST_EXCEPT)); } \
| $(SED) -rn -e ':l; /[,"]$$/ {N;b l;}' \
-e '/(xenapiSessionErrorHandler|vah_(error|warning))/d' \
-e '/\<$(func_re) *\([^"]*"([^%"]|"\n[^"]*")*"[,)]/p' \
| $(GREP) -vE 'VIR_ERROR' && \
| grep -vE 'VIR_ERROR' && \
{ echo '$(ME): found diagnostic without %' 1>&2; \
exit 1; } || :
@@ -691,16 +686,16 @@ sc_prohibit_useless_translation:
# When splitting a diagnostic across lines, ensure that there is a space
# or \n on one side of the split.
sc_require_whitespace_in_translation:
@$(VC_LIST_EXCEPT) | xargs $(GREP) -n -A1 '"$$' /dev/null \
@grep -n -A1 '"$$' $$($(VC_LIST_EXCEPT)) \
| $(SED) -ne ':l; /"$$/ {N;b l;}; s/"\n[^"]*"/""/g; s/\\n/ /g' \
-e '/_(.*[^\ ]""[^\ ]/p' | $(GREP) . && \
-e '/_(.*[^\ ]""[^\ ]/p' | grep . && \
{ echo '$(ME): missing whitespace at line split' 1>&2; \
exit 1; } || :
# Enforce recommended preprocessor indentation style.
sc_preprocessor_indentation:
@if cppi --version >/dev/null 2>&1; then \
$(VC_LIST_EXCEPT) | $(GREP) -E '\.[ch](\.in)?$$' | xargs cppi -a -c \
$(VC_LIST_EXCEPT) | grep -E '\.[ch](\.in)?$$' | xargs cppi -a -c \
|| { echo '$(ME): incorrect preprocessor indentation' 1>&2; \
exit 1; }; \
else \
@@ -711,13 +706,13 @@ sc_preprocessor_indentation:
# (comment-only) C file that mirrors the same layout as the spec file.
sc_spec_indentation:
@if cppi --version >/dev/null 2>&1; then \
for f in $$($(VC_LIST_EXCEPT) | $(GREP) '\.spec\.in$$'); do \
for f in $$($(VC_LIST_EXCEPT) | grep '\.spec\.in$$'); do \
$(SED) -e 's|#|// #|; s|%ifn*\(arch\)* |#if a // |' \
-e 's/%\(else\|endif\|define\)/#\1/' \
-e 's/^\( *\)\1\1\1#/#\1/' \
-e 's|^\( *[^#/ ]\)|// \1|; s|^\( */[^/]\)|// \1|' $$f \
| cppi -a -c 2>&1 | $(SED) "s|standard input|$$f|"; \
done | { if $(GREP) . >&2; then false; else :; fi; } \
done | { if grep . >&2; then false; else :; fi; } \
|| { echo '$(ME): incorrect preprocessor indentation' 1>&2; \
exit 1; }; \
else \
@@ -807,12 +802,11 @@ sc_prohibit_cross_inclusion:
# When converting an enum to a string, make sure that we track any new
# elements added to the enum by using a _LAST marker.
sc_require_enum_last_marker:
@$(VC_LIST_EXCEPT) | xargs \
$(GREP) -A1 -nE '^[^#]*VIR_ENUM_IMPL *\(' /dev/null \
@grep -A1 -nE '^[^#]*VIR_ENUM_IMPL *\(' $$($(VC_LIST_EXCEPT)) \
| $(SED) -ne '/VIR_ENUM_IMPL[^,]*,$$/N' \
-e '/VIR_ENUM_IMPL[^,]*,[^,]*[^_,][^L,][^A,][^S,][^T,],/p' \
-e '/VIR_ENUM_IMPL[^,]*,[^,]\{0,4\},/p' \
| $(GREP) . && \
| grep . && \
{ echo '$(ME): enum impl needs to use _LAST marker' 1>&2; \
exit 1; } || :
@@ -871,7 +865,8 @@ sc_prohibit_atoi:
$(_sc_search_regexp)
sc_prohibit_wrong_filename_in_comment:
@$(VC_LIST_EXCEPT) | $(GREP) '\.[ch]$$' | xargs awk 'BEGIN { \
@fail=0; \
awk 'BEGIN { \
fail=0; \
} FNR < 3 { \
n=match($$0, /[[:space:]][^[:space:]]*[.][ch][[:space:]:]/); \
@@ -887,8 +882,11 @@ sc_prohibit_wrong_filename_in_comment:
if (fail == 1) { \
exit 1; \
} \
}' || { echo '$(ME): The file name in comments must match the' \
'actual file name' 1>&2; exit 1; }
}' $$($(VC_LIST_EXCEPT) | grep '\.[ch]$$') || fail=1; \
if test $$fail -eq 1; then \
{ echo '$(ME): The file name in comments must match the' \
'actual file name' 1>&2; exit 1; } \
fi;
sc_prohibit_virConnectOpen_in_virsh:
@prohibit='\bvirConnectOpen[a-zA-Z]* *\(' \
@@ -919,21 +917,22 @@ sc_require_if_else_matching_braces:
$(_sc_search_regexp)
sc_curly_braces_style:
@if $(VC_LIST_EXCEPT) | $(GREP) '\.[ch]$$' | xargs $(GREP) -nHP \
@files=$$($(VC_LIST_EXCEPT) | grep '\.[ch]$$'); \
if $(GREP) -nHP \
'^\s*(?!([a-zA-Z_]*for_?each[a-zA-Z_]*) ?\()([_a-zA-Z0-9]+( [_a-zA-Z0-9]+)* ?\()?(\*?[_a-zA-Z0-9]+(,? \*?[_a-zA-Z0-9\[\]]+)+|void)\) ?\{' \
/dev/null; then \
$$files; then \
echo '$(ME): Non-K&R style used for curly braces around' \
'function body' 1>&2; exit 1; \
fi; \
if $(VC_LIST_EXCEPT) | $(GREP) '\.[ch]$$' | xargs \
$(GREP) -A1 -En ' ((if|for|while|switch) \(|(else|do)\b)[^{]*$$' \
/dev/null | $(GREP) '^[^ ]*- *{'; then \
if $(GREP) -A1 -En ' ((if|for|while|switch) \(|(else|do)\b)[^{]*$$'\
$$files | $(GREP) '^[^ ]*- *{'; then \
echo '$(ME): Use hanging braces for compound statements' 1>&2; exit 1; \
fi
sc_prohibit_windows_special_chars_in_filename:
@$(VC_LIST_EXCEPT) | $(GREP) '[:*?"<>|]' && \
{ echo '$(ME): Windows special chars in filename not allowed' 1>&2; echo exit 1; } || :
@files=$$($(VC_LIST_EXCEPT) | grep '[:*?"<>|]'); \
test -n "$$files" && { echo '$(ME): Windows special chars' \
'in filename not allowed:' 1>&2; echo $$files 1>&2; exit 1; } || :
sc_prohibit_mixed_case_abbreviations:
@prohibit='Pci|Usb|Scsi' \
@@ -949,11 +948,11 @@ sc_require_locale_h:
$(_sc_search_regexp)
sc_prohibit_empty_first_line:
@$(VC_LIST_EXCEPT) | xargs awk 'BEGIN { fail=0; } \
@awk 'BEGIN { fail=0; } \
FNR == 1 { if ($$0 == "") { print FILENAME ":1:"; fail=1; } } \
END { if (fail == 1) { \
print "$(ME): Prohibited empty first line" > "/dev/stderr"; \
} exit fail; }'
} exit fail; }' $$($(VC_LIST_EXCEPT));
sc_prohibit_paren_brace:
@prohibit='\)\{$$' \
@@ -996,9 +995,8 @@ sc_prohibit_sysconf_pagesize:
$(_sc_search_regexp)
sc_prohibit_virSecurity:
@$(VC_LIST_EXCEPT) | $(GREP) 'src/qemu/' | \
$(GREP) -v 'src/qemu/qemu_security' | \
xargs $(GREP) -Pn 'virSecurityManager(?!Ptr)' /dev/null && \
@grep -Pn 'virSecurityManager(?!Ptr)' $$($(VC_LIST_EXCEPT) | grep 'src/qemu/' | \
grep -v 'src/qemu/qemu_security') && \
{ echo '$(ME): prefer qemuSecurity wrappers' 1>&2; exit 1; } || :
sc_prohibit_pthread_create:
@@ -1051,11 +1049,6 @@ sc_prohibit_http_urls:
halt='Links must use https:// protocol' \
$(_sc_search_regexp)
sc_prohibit_author:
@prohibit="(\*|#)\s*(A|a)uthors?:" \
halt="Author: statements are prohibited in source comments" \
$(_sc_search_regexp)
# Alignment is usually achieved through spaces (at least two of them)
# or tabs (at least one of them) right before the trailing backslash
sc_prohibit_backslash_alignment:
@@ -1064,26 +1057,6 @@ sc_prohibit_backslash_alignment:
halt='Do not attempt to right-align backslashes' \
$(_sc_search_regexp)
# Some syntax rules pertaining to the usage of cleanup macros
# implementing GNU C's cleanup attribute
# Rule to ensure that variables declared using a cleanup macro are
# always initialized.
sc_require_attribute_cleanup_initialization:
@prohibit='VIR_AUTO((FREE|PTR|UNREF|CLEAN)\(.+\)|CLOSE|STRINGLIST) *[^=]+;' \
in_vc_files='\.[chx]$$' \
halt='variable declared with a cleanup macro must be initialized' \
$(_sc_search_regexp)
# "class" in headers is not good because by default Vim treats it as a keyword
# Let's prohibit it in source files as well.
sc_prohibit_class:
@prohibit=' +_?class *;' \
in_vc_files='\.[chx]$$' \
halt='use klass instead of class or _class' \
$(_sc_search_regexp)
# We don't use this feature of maint.mk.
prev_version_file = /dev/null
@@ -1132,34 +1105,29 @@ _autogen_error:
ifneq ($(_gl-Makefile),)
syntax-check: spacing-check test-wrap-argv \
prohibit-duplicate-header mock-noinline group-qemu-caps \
header-ifdef
prohibit-duplicate-header mock-noinline group-qemu-caps
endif
# Don't include duplicate header in the source (either *.c or *.h)
prohibit-duplicate-header:
$(AM_V_GEN)$(VC_LIST_EXCEPT) | $(GREP) '\.[chx]$$' | xargs \
$(PERL) -W $(top_srcdir)/build-aux/prohibit-duplicate-header.pl
$(AM_V_GEN)files=$$($(VC_LIST_EXCEPT) | grep '\.[chx]$$'); \
$(PERL) -W $(top_srcdir)/build-aux/prohibit-duplicate-header.pl $$files
spacing-check:
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.c$$' | xargs \
$(PERL) $(top_srcdir)/build-aux/check-spacing.pl || \
$(AM_V_GEN)files=`$(VC_LIST) | grep '\.c$$'`; \
$(PERL) $(top_srcdir)/build-aux/check-spacing.pl $$files || \
{ echo '$(ME): incorrect formatting' 1>&2; exit 1; }
mock-noinline:
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[ch]$$' | xargs \
$(PERL) $(top_srcdir)/build-aux/mock-noinline.pl
header-ifdef:
$(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[h]$$' | xargs \
$(PERL) $(top_srcdir)/build-aux/header-ifdef.pl
$(AM_V_GEN)files=`$(VC_LIST) | grep '\.[ch]$$'`; \
$(PERL) $(top_srcdir)/build-aux/mock-noinline.pl $$files
test-wrap-argv:
$(AM_V_GEN)$(VC_LIST) | $(GREP) -E '\.(ldargs|args)' | xargs \
$(PERL) $(top_srcdir)/tests/test-wrap-argv.pl --check
$(AM_V_GEN)files=`$(VC_LIST) | grep -E '\.(ldargs|args)'`; \
$(PERL) $(top_srcdir)/tests/test-wrap-argv.pl --check $$files
group-qemu-caps:
$(AM_V_GEN)$(PERL) $(top_srcdir)/tests/group-qemu-caps.pl --check $(top_srcdir)/
$(PERL) $(top_srcdir)/tests/group-qemu-caps.pl --check $(top_srcdir)/
# sc_po_check can fail if generated files are not built first
sc_po_check: \
@@ -1198,7 +1166,7 @@ exclude_file_name_regexp--sc_copyright_usage = \
^COPYING(|\.LESSER)$$
exclude_file_name_regexp--sc_flags_usage = \
^(cfg\.mk|docs/|src/util/virnetdevtap\.c$$|tests/((vir(cgroup|pci|test|usb)|nss|qemuxml2argv|qemusecurity)mock|virfilewrapper)\.c$$)
^(cfg\.mk|docs/|src/util/virnetdevtap\.c$$|tests/((vir(cgroup|pci|test|usb)|nss|qemuxml2argv)mock|virfilewrapper)\.c$$)
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
^(src/rpc/gendispatch\.pl$$|tests/)
@@ -1221,7 +1189,7 @@ exclude_file_name_regexp--sc_prohibit_strdup = \
^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c|tests/commandhelper\.c$$)
exclude_file_name_regexp--sc_prohibit_close = \
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c))$$)
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir.+mock\.c|tests/commandhelper\.c)$$)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
(^tests/(virhostcpu|virpcitest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
@@ -1242,13 +1210,13 @@ exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
^src/rpc/gendispatch\.pl$$
exclude_file_name_regexp--sc_prohibit_nonreentrant = \
^((po|tests|examples/admin)/|docs/.*(py|js|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
^((po|tests)/|docs/.*(py|js|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
exclude_file_name_regexp--sc_prohibit_select = \
^cfg\.mk$$
exclude_file_name_regexp--sc_prohibit_canonicalize_file_name = \
^(cfg\.mk|tests/virfilemock\.c)$$
^cfg\.mk$$
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
^(docs/hacking\.html\.in|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock|commandhelper)\.c|tools/wireshark/src/packet-libvirt\.c)$$
@@ -1291,7 +1259,7 @@ exclude_file_name_regexp--sc_correct_id_types = \
exclude_file_name_regexp--sc_m4_quote_check = m4/virt-lib.m4
exclude_file_name_regexp--sc_prohibit_include_public_headers_quote = \
^(src/internal\.h$$|tools/wireshark/src/packet-libvirt.c$$)
^(src/internal\.h$$|tools/wireshark/src/packet-libvirt.h$$)
exclude_file_name_regexp--sc_prohibit_include_public_headers_brackets = \
^(tools/|examples/|include/libvirt/(virterror|libvirt(-(admin|qemu|lxc))?)\.h$$)

View File

@@ -19,7 +19,7 @@
/*
* Since virt-login-shell will be setuid, we must do everything
* we can to avoid linking to other libraries. Many of them do
* unsafe things in functions marked __attribute__((constructor)).
* unsafe things in functions marked __atttribute__((constructor)).
* The only way to avoid such deps is to re-compile the
* functions with the code in question disabled, and for that we
* must override the main config.h rules. Hence this file :-(
@@ -69,6 +69,7 @@
# undef WITH_VIRTUALPORT
# undef WITH_SECDRIVER_SELINUX
# undef WITH_SECDRIVER_APPARMOR
# undef WITH_CAPNG
#endif /* LIBVIRT_NSS */
#ifndef __GNUC__

View File

@@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU Lesser General Public
dnl License along with this library. If not, see
dnl <http://www.gnu.org/licenses/>.
AC_INIT([libvirt], [5.2.0], [libvir-list@redhat.com], [], [https://libvirt.org])
AC_INIT([libvirt], [4.5.0], [libvir-list@redhat.com], [], [https://libvirt.org])
AC_CONFIG_SRCDIR([src/libvirt.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
@@ -225,6 +225,7 @@ if test "$with_libvirtd" = "no" ; then
with_qemu=no
with_lxc=no
with_libxl=no
with_uml=no
with_vbox=no
fi
@@ -246,11 +247,9 @@ LIBVIRT_ARG_CAPNG
LIBVIRT_ARG_CURL
LIBVIRT_ARG_DBUS
LIBVIRT_ARG_FIREWALLD
LIBVIRT_ARG_FIREWALLD_ZONE
LIBVIRT_ARG_FUSE
LIBVIRT_ARG_GLUSTER
LIBVIRT_ARG_HAL
LIBVIRT_ARG_LIBISCSI
LIBVIRT_ARG_LIBPCAP
LIBVIRT_ARG_LIBSSH
LIBVIRT_ARG_LIBXML
@@ -287,12 +286,10 @@ LIBVIRT_CHECK_DBUS
LIBVIRT_CHECK_DEVMAPPER
LIBVIRT_CHECK_DLOPEN
LIBVIRT_CHECK_FIREWALLD
LIBVIRT_CHECK_FIREWALLD_ZONE
LIBVIRT_CHECK_FUSE
LIBVIRT_CHECK_GLUSTER
LIBVIRT_CHECK_GNUTLS
LIBVIRT_CHECK_HAL
LIBVIRT_CHECK_LIBISCSI
LIBVIRT_CHECK_LIBNL
LIBVIRT_CHECK_LIBPARTED
LIBVIRT_CHECK_LIBPCAP
@@ -323,49 +320,17 @@ AC_CHECK_SIZEOF([long])
dnl Availability of various common functions (non-fatal if missing),
dnl and various less common threadsafe functions
AC_CHECK_FUNCS_ONCE([\
cfmakeraw \
fallocate \
geteuid \
getgid \
getifaddrs \
getmntent_r \
getpwuid_r \
getrlimit \
getuid \
if_indextoname \
mmap \
newlocale \
posix_fallocate \
posix_memalign \
prlimit \
sched_getaffinity \
sched_setscheduler \
setgroups \
setns \
setrlimit \
symlink \
sysctlbyname \
unshare \
])
AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r \
getmntent_r getpwuid_r getrlimit getuid if_indextoname kill mmap \
newlocale posix_fallocate posix_memalign prlimit regexec \
sched_getaffinity setgroups setns setrlimit symlink sysctlbyname \
getifaddrs sched_setscheduler unshare])
dnl Availability of various common headers (non-fatal if missing).
AC_CHECK_HEADERS([\
ifaddrs.h \
libtasn1.h \
linux/magic.h \
mntent.h \
net/ethernet.h \
netinet/tcp.h \
pwd.h \
stdarg.h \
syslog.h \
sys/mount.h \
sys/syscall.h \
sys/sysctl.h \
sys/ucred.h \
sys/un.h \
])
AC_CHECK_HEADERS([pwd.h regex.h sys/un.h \
sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \
sys/un.h sys/syscall.h sys/sysctl.h netinet/tcp.h ifaddrs.h \
libtasn1.h sys/ucred.h sys/mount.h stdarg.h])
dnl Check whether endian provides handy macros.
AC_CHECK_DECLS([htole64], [], [], [[#include <endian.h>]])
AC_CHECK_FUNCS([stat stat64 __xstat __xstat64 lstat lstat64 __lxstat __lxstat64])
@@ -446,6 +411,7 @@ LIBVIRT_DRIVER_ARG_VBOX
LIBVIRT_DRIVER_ARG_LXC
LIBVIRT_DRIVER_ARG_VZ
LIBVIRT_DRIVER_ARG_BHYVE
LIBVIRT_DRIVER_ARG_UML
LIBVIRT_DRIVER_ARG_ESX
LIBVIRT_DRIVER_ARG_HYPERV
LIBVIRT_DRIVER_ARG_TEST
@@ -464,6 +430,7 @@ LIBVIRT_DRIVER_CHECK_VBOX
LIBVIRT_DRIVER_CHECK_LXC
LIBVIRT_DRIVER_CHECK_VZ
LIBVIRT_DRIVER_CHECK_BHYVE
LIBVIRT_DRIVER_CHECK_UML
LIBVIRT_DRIVER_CHECK_ESX
LIBVIRT_DRIVER_CHECK_HYPERV
LIBVIRT_DRIVER_CHECK_TEST
@@ -595,7 +562,6 @@ LIBVIRT_STORAGE_ARG_DIR
LIBVIRT_STORAGE_ARG_FS
LIBVIRT_STORAGE_ARG_LVM
LIBVIRT_STORAGE_ARG_ISCSI
LIBVIRT_STORAGE_ARG_ISCSI_DIRECT
LIBVIRT_STORAGE_ARG_SCSI
LIBVIRT_STORAGE_ARG_MPATH
LIBVIRT_STORAGE_ARG_DISK
@@ -610,7 +576,6 @@ if test "$with_libvirtd" = "no"; then
with_storage_fs=no
with_storage_lvm=no
with_storage_iscsi=no
with_storage_iscsi_direct=no
with_storage_scsi=no
with_storage_mpath=no
with_storage_disk=no
@@ -631,7 +596,6 @@ LIBVIRT_STORAGE_CHECK_DIR
LIBVIRT_STORAGE_CHECK_FS
LIBVIRT_STORAGE_CHECK_LVM
LIBVIRT_STORAGE_CHECK_ISCSI
LIBVIRT_STORAGE_CHECK_ISCSI_DIRECT
LIBVIRT_STORAGE_CHECK_SCSI
LIBVIRT_STORAGE_CHECK_MPATH
LIBVIRT_STORAGE_CHECK_DISK
@@ -642,7 +606,7 @@ LIBVIRT_STORAGE_CHECK_ZFS
LIBVIRT_STORAGE_CHECK_VSTORAGE
with_storage=no
for backend in dir fs lvm iscsi iscsi_direct scsi mpath rbd disk; do
for backend in dir fs lvm iscsi scsi mpath rbd disk; do
if eval test \$with_storage_$backend = yes; then
with_storage=yes
break
@@ -661,13 +625,6 @@ if test "$with_linux" = "yes"; then
AC_CHECK_HEADERS([linux/btrfs.h])
fi
dnl
dnl check for xfs dev headers required by xfs ioctl
dnl
if test "$with_linux" = "yes"; then
AC_CHECK_HEADERS([xfs/xfs.h])
fi
dnl
dnl check for DEVLINK_CMD_ESWITCH_GET
dnl
@@ -738,6 +695,23 @@ fi
AC_SUBST([VIR_TEST_EXPENSIVE_DEFAULT])
AM_CONDITIONAL([WITH_EXPENSIVE_TESTS], [test $VIR_TEST_EXPENSIVE_DEFAULT = 1])
LIBVIRT_ARG_ENABLE([TEST_COVERAGE], [turn on code coverage instrumentation], [no])
case "$enable_test_coverage" in
yes|no) ;;
*) AC_MSG_ERROR([bad value ${enable_test_coverga} for test-coverage option]) ;;
esac
if test "$enable_test_coverage" = yes; then
save_WARN_CFLAGS=$WARN_CFLAGS
WARN_CFLAGS=
gl_WARN_ADD([-fprofile-arcs])
gl_WARN_ADD([-ftest-coverage])
COVERAGE_FLAGS=$WARN_CFLAGS
AC_SUBST([COVERAGE_CFLAGS], [$COVERAGE_FLAGS])
AC_SUBST([COVERAGE_LDFLAGS], [$COVERAGE_FLAGS])
WARN_CFLAGS=$save_WARN_CFLAGS
fi
LIBVIRT_ARG_ENABLE([TEST_OOM], [memory allocation failure checking], [no])
case "$enable_test_oom" in
yes|no) ;;
@@ -929,6 +903,7 @@ AC_MSG_NOTICE([])
AC_MSG_NOTICE([Drivers])
AC_MSG_NOTICE([])
LIBVIRT_DRIVER_RESULT_QEMU
LIBVIRT_DRIVER_RESULT_UML
LIBVIRT_DRIVER_RESULT_OPENVZ
LIBVIRT_DRIVER_RESULT_VMWARE
LIBVIRT_DRIVER_RESULT_VBOX
@@ -952,7 +927,6 @@ LIBVIRT_STORAGE_RESULT_DIR
LIBVIRT_STORAGE_RESULT_FS
LIBVIRT_STORAGE_RESULT_LVM
LIBVIRT_STORAGE_RESULT_ISCSI
LIBVIRT_STORAGE_RESULT_ISCSI_DIRECT
LIBVIRT_STORAGE_RESULT_SCSI
LIBVIRT_STORAGE_RESULT_MPATH
LIBVIRT_STORAGE_RESULT_DISK
@@ -985,12 +959,10 @@ LIBVIRT_RESULT_CURL
LIBVIRT_RESULT_DBUS
LIBVIRT_RESULT_DLOPEN
LIBVIRT_RESULT_FIREWALLD
LIBVIRT_RESULT_FIREWALLD_ZONE
LIBVIRT_RESULT_FUSE
LIBVIRT_RESULT_GLUSTER
LIBVIRT_RESULT_GNUTLS
LIBVIRT_RESULT_HAL
LIBVIRT_RESULT_LIBISCSI
LIBVIRT_RESULT_LIBNL
LIBVIRT_RESULT_LIBPCAP
LIBVIRT_RESULT_LIBSSH
@@ -1024,6 +996,7 @@ LIBVIRT_WIN_RESULT_WINDRES
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Test suite])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ Coverage: $enable_test_coverage])
AC_MSG_NOTICE([ Alloc OOM: $enable_test_oom])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Miscellaneous])

View File

@@ -132,6 +132,8 @@ dot_php_in = $(notdir $(wildcard $(srcdir)/*.php.in))
dot_php_code_in = $(dot_php_in:%.php.in=%.php.code.in)
dot_php = $(dot_php_in:%.php.in=%.php)
patches = $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/api_extension/*.patch))
xml = \
libvirt-api.xml \
libvirt-refs.xml
@@ -175,7 +177,7 @@ EXTRA_DIST= \
$(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
$(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
$(xml) $(qemu_xml) $(lxc_xml) $(admin_xml) $(fig) $(png) $(css) \
$(logofiles) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
$(logofiles) $(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
$(internals_html_in) $(internals_html) $(fonts) \
aclperms.htmlinc \
hvsupport.pl \

View File

@@ -287,119 +287,6 @@
</tbody>
</table>
<h2><a id="connect_driver">Hypervisor Driver connect_driver</a></h2>
<p>
The <code>connect_driver</code> parameter describes the
client's <a href="remote.html">remote Connection Driver</a>
name based on the <a href="uri.html">URI</a> used for the
connection.
</p>
<p>
<span class="since">Since 4.1.0</span>, when calling an API
outside the scope of the primary connection driver, the
primary driver will attempt to open a secondary connection
to the specific API driver in order to process the API. For
example, when hypervisor domain processing needs to make an
API call within the storage driver or the network filter driver
an attempt to open a connection to the "storage" or "nwfilter"
driver will be made. Similarly, a "storage" primary connection
may need to create a connection to the "secret" driver in order
to process secrets for the API. If successful, then calls to
those API's will occur in the <code>connect_driver</code> context
of the secondary connection driver rather than in the context of
the primary driver. This affects the <code>connect_driver</code>
returned from rule generation from the <code>action.loookup</code>
function. The following table provides a list of the various
connection drivers and the <code>connect_driver</code> name
used by each regardless of primary or secondary connection.
The access denied error message from libvirt will list the
connection driver by name that denied the access.
</p>
<h3><a id="object_connect_driver">Connection Driver Name</a></h3>
<table class="acl">
<thead>
<tr>
<th>Connection Driver</th>
<th><code>connect_driver</code> name</th>
</tr>
</thead>
<tbody>
<tr>
<td>bhyve</td>
<td>bhyve</td>
</tr>
<tr>
<td>esx</td>
<td>ESX</td>
</tr>
<tr>
<td>hyperv</td>
<td>Hyper-V</td>
</tr>
<tr>
<td>interface</td>
<td>interface</td>
</tr>
<tr>
<td>libxl</td>
<td>xenlight</td>
</tr>
<tr>
<td>lxc</td>
<td>LXC</td>
</tr>
<tr>
<td>network</td>
<td>network</td>
</tr>
<tr>
<td>nodedev</td>
<td>nodedev</td>
</tr>
<tr>
<td>nwfilter</td>
<td>NWFilter</td>
</tr>
<tr>
<td>openvz</td>
<td>OPENVZ</td>
</tr>
<tr>
<td>phyp</td>
<td>PHYP</td>
</tr>
<tr>
<td>qemu</td>
<td>QEMU</td>
</tr>
<tr>
<td>secret</td>
<td>secret</td>
</tr>
<tr>
<td>storage</td>
<td>storage</td>
</tr>
<tr>
<td>vbox</td>
<td>VBOX</td>
</tr>
<tr>
<td>vmware</td>
<td>VMWARE</td>
</tr>
<tr>
<td>vz</td>
<td>vz</td>
</tr>
<tr>
<td>xenapi</td>
<td>XenAPI</td>
</tr>
</tbody>
</table>
<h2><a id="user">User identity attributes</a></h2>

View File

@@ -8,9 +8,14 @@
<p>
This document walks you through the process of implementing a new
API in libvirt. Remember that new API consists of any new public
functions, as well as the addition of flags or extensions of XML used by
existing functions.
API in libvirt. It uses as an example the addition of an API for
separating maximum from current vcpu usage of a domain, over
the course of a fifteen-patch series.
Remember that new API consists of any new public functions, as
well as the addition of flags or extensions of XML used by
existing functions. The example in this document adds both new
functions and an XML extension. Not all libvirt API additions
require quite as many patches.
</p>
<p>
@@ -22,7 +27,12 @@
added to libvirt. Someone may already be working on the feature you
want. Also, recognize that everything you write is likely to undergo
significant rework as you discuss it with the other developers, so
don't wait too long before getting feedback.
don't wait too long before getting feedback. In the vcpu example
below, list feedback was first requested
<a href="https://www.redhat.com/archives/libvir-list/2010-September/msg00423.html">here</a>
and resulted in several rounds of improvements before coding
began. In turn, this example is slightly rearranged from the actual
order of the commits.
</p>
<p>
@@ -71,12 +81,14 @@
</p>
<p>
Submit new code in the form of one patch per step. That's not to say
submit patches before you have working functionality--get the whole thing
working and make sure you're happy with it. Then use git to break the
changes into pieces so you don't drop a big blob of code on the
mailing list in one go. Also, you should follow the upstream tree, and
rebase your series to adapt your patches to work with any other changes
Submit new code in the form shown in the example code: one patch
per step. That's not to say submit patches before you have working
functionality--get the whole thing working and make sure you're happy
with it. Then use git or some other version control system that lets
you rewrite your commit history and break patches into pieces so you
don't drop a big blob of code on the mailing list in one go.
Also, you should follow the upstream tree, and rebase your
series to adapt your patches to work with any other changes
that were accepted upstream during your development.
</p>
@@ -89,6 +101,8 @@
separately.
</p>
<p>With that said, let's begin.</p>
<h2><a name='publicapi'>Defining the public API</a></h2>
<p>The first task is to define the public API. If the new API
@@ -96,7 +110,7 @@
schema and document the new elements or attributes:</p>
<p><code>
docs/schemas/domaincommon.rng<br/>
docs/schemas/domain.rng<br/>
docs/formatdomain.html.in
</code></p>
@@ -106,7 +120,7 @@
libvirt library and call the new function:</p>
<p><code>
include/libvirt/libvirt-$MODULE.h.in
include/libvirt/libvirt.h.in
src/libvirt_public.syms
</code></p>
@@ -119,6 +133,10 @@
rework it as you go through the process of implementing it.
</p>
<p class="example">See <a href="api_extension/0001-add-to-xml.patch">0001-add-to-xml.patch</a>
and <a href="api_extension/0002-add-new-public-API.patch">0002-add-new-public-API.patch</a>
for example code.</p>
<h2><a name='internalapi'>Defining the internal API</a></h2>
<p>
@@ -137,7 +155,7 @@
<p>The driver structs are defined in:</p>
<p><code>src/driver-$MODULE.h</code></p>
<p><code>src/driver.h</code></p>
<p>
To define the internal API, first typedef the driver function
@@ -146,6 +164,8 @@
provide a <code>NULL</code> stub for the new function.
</p>
<p class="example">See <a href="api_extension/0003-define-internal-driver-API.patch">0003-define-internal-driver-API.patch</a></p>
<h2><a name='implpublic'>Implementing the public API</a></h2>
<p>
@@ -177,16 +197,22 @@
<p>The public API calls are implemented in:</p>
<p><code>src/libvirt-$MODULE.c</code></p>
<p><code>src/libvirt.c</code></p>
<p class="example">See <a href="api_extension/0004-implement-the-public-APIs.patch">0004-implement-the-public-APIs.patch</a></p>
<h2><a name='remoteproto'>Implementing the remote protocol</a></h2>
<p>
Implementing the remote protocol is essentially a
straightforward exercise which is probably most easily
understood by referring to the existing code.
understood by referring to the existing code and the example
patch. It involves several related changes, including the
regeneration of derived files, with further details below.
</p>
<p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch">0005-implement-the-remote-protocol.patch</a></p>
<h3><a name='wireproto'>Defining the wire protocol format</a></h3>
<p>
@@ -219,9 +245,9 @@
</p>
<p><code>
src/remote/remote_daemon_dispatch_stubs.h
src/remote/remote_daemon_dispatch.h
src/remote/remote_daemon_dispatch.c
daemon/remote_dispatch_args.h
daemon/remote_dispatch_prototypes.h
daemon/remote_dispatch_table.h
src/remote/remote_protocol.c
src/remote/remote_protocol.h
</code></p>
@@ -233,7 +259,7 @@
method calls go in:
</p>
<p><code>src/remote/remote_driver.c</code></p>
<p><code>src/remote/remote_internal.c</code></p>
<p>Each remote method invocation does the following:</p>
@@ -256,7 +282,7 @@
The server side dispatchers are implemented in:
</p>
<p><code>src/remote/daemon_dispatch.c</code></p>
<p><code>daemon/remote.c</code></p>
<p>Again, this step uses the .h files generated by make rpcgen.</p>
@@ -272,6 +298,8 @@
existing lines probably imply a backwards-incompatible API change.
</p>
<p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch">0005-implement-the-remote-protocol.patch</a></p>
<h2><a id="internaluseapi">Use the new API internally</a></h2>
<p>
@@ -284,6 +312,8 @@
not necessary if the new API has no relation to existing API.
</p>
<p class="example">See <a href="api_extension/0006-make-old-API-trivially-wrap-to-new-API.patch">0006-make-old-API-trivially-wrap-to-new-API.patch</a></p>
<h2><a id="virshuseapi">Expose the new API in virsh</a></h2>
<p>
@@ -309,10 +339,12 @@
</p>
<p><code>
tools/virsh-$MODULE.c<br/>
tools/virsh.c<br/>
tools/virsh.pod
</code></p>
<p class="example">See <a href="api_extension/0007-add-virsh-support.patch">0007-add-virsh-support.patch</a></p>
<h2><a id="driverimpl">Implement the driver methods</a></h2>
<p>
@@ -339,6 +371,8 @@
the same way as the older API wrappers.
</p>
<p class="example">See <a href="api_extension/0008-support-new-xml.patch">0008-support-new-xml.patch</a></p>
<h3><a id="drivercode">Implement driver handling</a></h3>
<p>
@@ -350,14 +384,41 @@
</p>
<p>
It is always a good idea to patch the test driver in addition to the
target driver, to prove that the API can be used for more than one
driver.
In the example patches, three separate drivers are supported:
test, qemu, and xen. It is always a good idea to patch the test
driver in addition to the target driver, to prove that the API
can be used for more than one driver. The example updates the
test driver in one patch:
</p>
<p class="example">See <a href="api_extension/0009-support-all-flags-in-test-driver.patch">0009-support-all-flags-in-test-driver.patch</a></p>
<p>
Any cleanups resulting from the changes should be added as separate
patches at the end of the series.
The qemu changes were easier to split into two phases, one for
updating the mapping between the new XML and the hypervisor
command line arguments, and one for supporting all possible
flags of the new API:
</p>
<p class="example">See <a href="api_extension/0010-improve-vcpu-support-in-qemu-command-line.patch">0010-improve-vcpu-support-in-qemu-command-line.patch</a>
and <a href="api_extension/0011-complete-vcpu-support-in-qemu-driver.patch">0011-complete-vcpu-support-in-qemu-driver.patch</a></p>
<p>
Finally, the example breaks the xen driver changes across four
patches. One maps the XML changes to the hypervisor command,
the next two are independently implementing the getter and
setter APIs, and the last one provides cleanup of code that was
rendered dead by the new API.
</p>
<p class="example">See <a href="api_extension/0012-improve-vcpu-support-in-xen-command-line.patch">0012-improve-vcpu-support-in-xen-command-line.patch</a>,
<a href="api_extension/0013-improve-getting-xen-vcpu-counts.patch">0013-improve-getting-xen-vcpu-counts.patch</a>,
<a href="api_extension/0014-improve-setting-xen-vcpu-counts.patch">0014-improve-setting-xen-vcpu-counts.patch</a>,
and <a href="api_extension/0015-remove-dead-xen-code.patch">0015-remove-dead-xen-code.patch</a></p>
<p>
The exact details of the example code are probably uninteresting
unless you're concerned with virtual cpu management.
</p>
<p>

View File

@@ -0,0 +1,145 @@
From a74f4e44649906dcd82151f7ef837f66d7fa2ab1 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 17:36:06 -0600
Subject: [PATCH 01/15] vcpu: add current attribute to <vcpu> element
Syntax agreed on in
https://www.redhat.com/archives/libvir-list/2010-September/msg00476.html
<domain ...>
<vcpu current='x'>y</vcpu>
...
can now be used to specify 1 <= x <= y current vcpus, in relation
to the boot-time max of y vcpus. If current is omitted, then
current and max are assumed to be the same value.
* docs/schemas/domain.rng: Add new attribute.
* docs/formatdomain.html.in: Document it.
* tests/qemuxml2argvdata/qemuxml2argv-smp.xml: Add to
domainschematest.
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml: Likewise.
---
docs/formatdomain.html.in | 9 +++++--
docs/schemas/domain.rng | 5 ++++
tests/qemuxml2argvdata/qemuxml2argv-smp.xml | 28 +++++++++++++++++++++++++++
tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml | 22 +++++++++++++++++++++
4 files changed, 61 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.xml
create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a8a1fac..96de121 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -200,7 +200,7 @@
&lt;swap_hard_limit&gt;2097152&lt;/swap_hard_limit&gt;
&lt;min_guarantee&gt;65536&lt;/min_guarantee&gt;
&lt;/memtune&gt;
- &lt;vcpu cpuset="1-4,^3,6"&gt;2&lt;/vcpu&gt;
+ &lt;vcpu cpuset="1-4,^3,6" current="1"&gt;2&lt;/vcpu&gt;
...</pre>
<dl>
@@ -238,7 +238,7 @@
minimum memory allocation for the guest. The units for this value are
kilobytes (i.e. blocks of 1024 bytes)</dd>
<dt><code>vcpu</code></dt>
- <dd>The content of this element defines the number of virtual
+ <dd>The content of this element defines the maximum number of virtual
CPUs allocated for the guest OS, which must be between 1 and
the maximum supported by the hypervisor. <span class="since">Since
0.4.4</span>, this element can contain an optional
@@ -246,7 +246,10 @@
list of physical CPU numbers that virtual CPUs can be pinned
to. Each element in that list is either a single CPU number,
a range of CPU numbers, or a caret followed by a CPU number to
- be excluded from a previous range.
+ be excluded from a previous range. <span class="since">Since
+ 0.8.5</span>, the optional attribute <code>current</code> can
+ be used to specify whether fewer than the maximum number of
+ virtual CPUs should be enabled.
</dd>
</dl>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index f230263..a934a77 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -337,6 +337,11 @@
<ref name="cpuset"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="current">
+ <ref name="countCPU"/>
+ </attribute>
+ </optional>
<ref name="countCPU"/>
</element>
</optional>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.xml b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
new file mode 100644
index 0000000..975f873
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu current='1'>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
new file mode 100644
index 0000000..d061e11
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
@@ -0,0 +1,22 @@
+<domain type='xen' id='15'>
+ <name>pvtest</name>
+ <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid>
+ <os>
+ <type>linux</type>
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline>
+ </os>
+ <memory>430080</memory>
+ <vcpu current='2'>4</vcpu>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <source file='/root/some.img'/>
+ <target dev='xvda'/>
+ </disk>
+ <console tty='/dev/pts/4'/>
+ </devices>
+</domain>
--
1.7.2.3

View File

@@ -0,0 +1,62 @@
From ea3f5c68093429c6ad507b45689cdf209c2c257b Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 24 Sep 2010 16:48:45 -0600
Subject: [PATCH 02/15] vcpu: add new public API
API agreed on in
https://www.redhat.com/archives/libvir-list/2010-September/msg00456.html,
but modified for enum names to be consistent with virDomainDeviceModifyFlags.
* include/libvirt/libvirt.h.in (virDomainVcpuFlags)
(virDomainSetVcpusFlags, virDomainGetVcpusFlags): New
declarations.
* src/libvirt_public.syms: Export new symbols.
---
include/libvirt/libvirt.h.in | 15 +++++++++++++++
src/libvirt_public.syms | 2 ++
2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 2eba61e..d0cc4c0 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -915,8 +915,23 @@ struct _virVcpuInfo {
};
typedef virVcpuInfo *virVcpuInfoPtr;
+/* Flags for controlling virtual CPU hot-plugging. */
+typedef enum {
+ /* Must choose at least one of these two bits; SetVcpus can choose both */
+ VIR_DOMAIN_VCPU_LIVE = (1 << 0), /* Affect active domain */
+ VIR_DOMAIN_VCPU_CONFIG = (1 << 1), /* Affect next boot */
+
+ /* Additional flags to be bit-wise OR'd in */
+ VIR_DOMAIN_VCPU_MAXIMUM = (1 << 2), /* Max rather than current count */
+} virDomainVcpuFlags;
+
int virDomainSetVcpus (virDomainPtr domain,
unsigned int nvcpus);
+int virDomainSetVcpusFlags (virDomainPtr domain,
+ unsigned int nvcpus,
+ unsigned int flags);
+int virDomainGetVcpusFlags (virDomainPtr domain,
+ unsigned int flags);
int virDomainPinVcpu (virDomainPtr domain,
unsigned int vcpu,
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index fceb516..a8091b1 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -409,6 +409,8 @@ LIBVIRT_0.8.5 {
global:
virDomainSetMemoryParameters;
virDomainGetMemoryParameters;
+ virDomainGetVcpusFlags;
+ virDomainSetVcpusFlags;
} LIBVIRT_0.8.2;
# .... define new API here using predicted next version number ....
--
1.7.2.3

View File

@@ -0,0 +1,222 @@
From dd255d64053e9960cd375994ce8f056522e12acc Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 09:18:22 -0600
Subject: [PATCH 03/15] vcpu: define internal driver API
* src/driver.h (virDrvDomainSetVcpusFlags)
(virDrvDomainGetVcpusFlags): New typedefs.
(_virDriver): New callback members.
* src/esx/esx_driver.c (esxDriver): Add stub for driver.
* src/lxc/lxc_driver.c (lxcDriver): Likewise.
* src/opennebula/one_driver.c (oneDriver): Likewise.
* src/openvz/openvz_driver.c (openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemuDriver): Likewise.
* src/remote/remote_driver.c (remote_driver): Likewise.
* src/test/test_driver.c (testDriver): Likewise.
* src/uml/uml_driver.c (umlDriver): Likewise.
* src/vbox/vbox_tmpl.c (Driver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDriver): Likewise.
---
src/driver.h | 9 +++++++++
src/esx/esx_driver.c | 2 ++
src/lxc/lxc_driver.c | 2 ++
src/opennebula/one_driver.c | 2 ++
src/openvz/openvz_driver.c | 2 ++
src/phyp/phyp_driver.c | 2 ++
src/qemu/qemu_driver.c | 2 ++
src/remote/remote_driver.c | 2 ++
src/test/test_driver.c | 2 ++
src/uml/uml_driver.c | 2 ++
src/vbox/vbox_tmpl.c | 2 ++
src/xen/xen_driver.c | 2 ++
src/xenapi/xenapi_driver.c | 2 ++
13 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/src/driver.h b/src/driver.h
index 32aeb04..79a96c1 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -185,6 +185,13 @@ typedef int
(*virDrvDomainSetVcpus) (virDomainPtr domain,
unsigned int nvcpus);
typedef int
+ (*virDrvDomainSetVcpusFlags) (virDomainPtr domain,
+ unsigned int nvcpus,
+ unsigned int flags);
+typedef int
+ (*virDrvDomainGetVcpusFlags) (virDomainPtr domain,
+ unsigned int flags);
+typedef int
(*virDrvDomainPinVcpu) (virDomainPtr domain,
unsigned int vcpu,
unsigned char *cpumap,
@@ -520,6 +527,8 @@ struct _virDriver {
virDrvDomainRestore domainRestore;
virDrvDomainCoreDump domainCoreDump;
virDrvDomainSetVcpus domainSetVcpus;
+ virDrvDomainSetVcpusFlags domainSetVcpusFlags;
+ virDrvDomainGetVcpusFlags domainGetVcpusFlags;
virDrvDomainPinVcpu domainPinVcpu;
virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 1b4ee29..2a32374 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4160,6 +4160,8 @@ static virDriver esxDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
esxDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
esxDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index df814da..7563a8c 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2768,6 +2768,8 @@ static virDriver lxcDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
NULL, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
index ced9a38..199fca3 100644
--- a/src/opennebula/one_driver.c
+++ b/src/opennebula/one_driver.c
@@ -751,6 +751,8 @@ static virDriver oneDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
NULL, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 92cf4a1..9d19aeb 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1590,6 +1590,8 @@ static virDriver openvzDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
openvzDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index e63d8d9..6e0a5e9 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -3941,6 +3941,8 @@ static virDriver phypDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
phypDomainSetCPU, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
phypGetLparCPUMAX, /* domainGetMaxVcpus */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index abd8e9d..3d17e04 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12938,6 +12938,8 @@ static virDriver qemuDriver = {
qemudDomainRestore, /* domainRestore */
qemudDomainCoreDump, /* domainCoreDump */
qemudDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
qemudDomainPinVcpu, /* domainPinVcpu */
qemudDomainGetVcpus, /* domainGetVcpus */
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 0b10406..1a687ad 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -10468,6 +10468,8 @@ static virDriver remote_driver = {
remoteDomainRestore, /* domainRestore */
remoteDomainCoreDump, /* domainCoreDump */
remoteDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
remoteDomainPinVcpu, /* domainPinVcpu */
remoteDomainGetVcpus, /* domainGetVcpus */
remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 7d4d119..6a00558 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -5260,6 +5260,8 @@ static virDriver testDriver = {
testDomainRestore, /* domainRestore */
testDomainCoreDump, /* domainCoreDump */
testSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
testDomainPinVcpu, /* domainPinVcpu */
testDomainGetVcpus, /* domainGetVcpus */
testDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 3dcd321..5161012 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -2129,6 +2129,8 @@ static virDriver umlDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
NULL, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 7e7d8e4..cb9193a 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -8267,6 +8267,8 @@ virDriver NAME(Driver) = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
vboxDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index c2a4de3..7d67ced 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1951,6 +1951,8 @@ static virDriver xenUnifiedDriver = {
xenUnifiedDomainRestore, /* domainRestore */
xenUnifiedDomainCoreDump, /* domainCoreDump */
xenUnifiedDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
xenUnifiedDomainPinVcpu, /* domainPinVcpu */
xenUnifiedDomainGetVcpus, /* domainGetVcpus */
xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index e62a139..753169c 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -1754,6 +1754,8 @@ static virDriver xenapiDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
xenapiDomainSetVcpus, /* domainSetVcpus */
+ NULL, /* domainSetVcpusFlags */
+ NULL, /* domainGetVcpusFlags */
xenapiDomainPinVcpu, /* domainPinVcpu */
xenapiDomainGetVcpus, /* domainGetVcpus */
xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
--
1.7.2.3

View File

@@ -0,0 +1,188 @@
From 9d2c60799271d605f82dfd4bfa6ed7d14ad87e26 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 09:37:22 -0600
Subject: [PATCH 04/15] vcpu: implement the public APIs
Factors common checks (such as nonzero vcpu count) up front, but
drivers will still need to do additional flag checks.
* src/libvirt.c (virDomainSetVcpusFlags, virDomainGetVcpusFlags):
New functions.
(virDomainSetVcpus, virDomainGetMaxVcpus): Refer to new API.
---
src/libvirt.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 134 insertions(+), 6 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 629d97b..1b39210 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5192,7 +5192,9 @@ error:
* This function requires privileged access to the hypervisor.
*
* This command only changes the runtime configuration of the domain,
- * so can only be called on an active domain.
+ * so can only be called on an active domain. It is hypervisor-dependent
+ * whether it also affects persistent configuration; for more control,
+ * use virDomainSetVcpusFlags().
*
* Returns 0 in case of success, -1 in case of failure.
*/
@@ -5237,13 +5239,139 @@ error:
}
/**
+ * virDomainSetVcpusFlags:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1
+ * @flags: an OR'ed set of virDomainVcpuFlags
+ *
+ * Dynamically change the number of virtual CPUs used by the domain.
+ * Note that this call may fail if the underlying virtualization hypervisor
+ * does not support it or if growing the number is arbitrary limited.
+ * This function requires privileged access to the hypervisor.
+ *
+ * @flags must include VIR_DOMAIN_VCPU_LIVE to affect a running
+ * domain (which may fail if domain is not active), or
+ * VIR_DOMAIN_VCPU_CONFIG to affect the next boot via the XML
+ * description of the domain. Both flags may be set.
+ *
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then
+ * VIR_DOMAIN_VCPU_LIVE must be clear, and only the maximum virtual
+ * CPU limit is altered; generally, this value must be less than or
+ * equal to virConnectGetMaxVcpus(). Otherwise, this call affects the
+ * current virtual CPU limit, which must be less than or equal to the
+ * maximum limit.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+
+int
+virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DEBUG("domain=%p, nvcpus=%u, flags=%u", domain, nvcpus, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ /* Perform some argument validation common to all implementations. */
+ if (nvcpus < 1 || (unsigned short) nvcpus != nvcpus ||
+ (flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainSetVcpusFlags) {
+ int ret;
+ ret = conn->driver->domainSetVcpusFlags (domain, nvcpus, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+/**
+ * virDomainGetVcpusFlags:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @flags: an OR'ed set of virDomainVcpuFlags
+ *
+ * Query the number of virtual CPUs used by the domain. Note that
+ * this call may fail if the underlying virtualization hypervisor does
+ * not support it. This function requires privileged access to the
+ * hypervisor.
+ *
+ * @flags must include either VIR_DOMAIN_VCPU_ACTIVE to query a
+ * running domain (which will fail if domain is not active), or
+ * VIR_DOMAIN_VCPU_PERSISTENT to query the XML description of the
+ * domain. It is an error to set both flags.
+ *
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum
+ * virtual CPU limit is queried. Otherwise, this call queries the
+ * current virtual CPU limit.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+
+int
+virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DEBUG("domain=%p, flags=%u", domain, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return (-1);
+ }
+
+ /* Exactly one of these two flags should be set. */
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainGetVcpusFlags) {
+ int ret;
+ ret = conn->driver->domainGetVcpusFlags (domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+/**
* virDomainPinVcpu:
* @domain: pointer to domain object, or NULL for Domain0
* @vcpu: virtual CPU number
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
- * Each bit set to 1 means that corresponding CPU is usable.
- * Bytes are stored in little-endian order: CPU0-7, 8-15...
- * In each byte, lowest CPU number is least significant bit.
+ * Each bit set to 1 means that corresponding CPU is usable.
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
+ * In each byte, lowest CPU number is least significant bit.
* @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
* underlying virtualization system (Xen...).
* If maplen < size, missing bytes are set to zero.
@@ -5371,9 +5499,9 @@ error:
*
* Provides the maximum number of virtual CPUs supported for
* the guest VM. If the guest is inactive, this is basically
- * the same as virConnectGetMaxVcpus. If the guest is running
+ * the same as virConnectGetMaxVcpus(). If the guest is running
* this will reflect the maximum number of virtual CPUs the
- * guest was booted with.
+ * guest was booted with. For more details, see virDomainGetVcpusFlags().
*
* Returns the maximum of virtual CPU or -1 in case of error.
*/
--
1.7.2.3

View File

@@ -0,0 +1,421 @@
From eb826444f90c2563dadf148630b0cd6a9b41ba1e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 10:10:06 -0600
Subject: [PATCH 05/15] vcpu: implement the remote protocol
Done by editing the first three files, then running
'make -C src rpcgen', then editing src/remote_protocol-structs
to match.
* daemon/remote.c (remoteDispatchDomainSetVcpusFlags)
(remoteDispatchDomainGetVcpusFlags): New functions.
* src/remote/remote_driver.c (remoteDomainSetVcpusFlags)
(remoteDomainGetVcpusFlags, remote_driver): Client side
serialization.
* src/remote/remote_protocol.x
(remote_domain_set_vcpus_flags_args)
(remote_domain_get_vcpus_flags_args)
(remote_domain_get_vcpus_flags_ret)
(REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS)
(REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS): Define wire format.
* daemon/remote_dispatch_args.h: Regenerate.
* daemon/remote_dispatch_prototypes.h: Likewise.
* daemon/remote_dispatch_table.h: Likewise.
* src/remote/remote_protocol.c: Likewise.
* src/remote/remote_protocol.h: Likewise.
* src/remote_protocol-structs: Likewise.
---
daemon/remote.c | 53 ++++++++++++++++++++++++++++++++
daemon/remote_dispatch_args.h | 2 +
daemon/remote_dispatch_prototypes.h | 16 ++++++++++
daemon/remote_dispatch_ret.h | 1 +
daemon/remote_dispatch_table.h | 10 ++++++
src/remote/remote_driver.c | 57 +++++++++++++++++++++++++++++++++-
src/remote/remote_protocol.c | 33 ++++++++++++++++++++
src/remote/remote_protocol.h | 26 ++++++++++++++++
src/remote/remote_protocol.x | 19 +++++++++++-
src/remote_protocol-structs | 12 +++++++
10 files changed, 226 insertions(+), 3 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 7a96e29..323f00c 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1751,6 +1751,33 @@ oom:
}
static int
+remoteDispatchDomainGetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ remote_domain_get_vcpus_flags_args *args,
+ remote_domain_get_vcpus_flags_ret *ret)
+{
+ virDomainPtr dom;
+
+ dom = get_nonnull_domain (conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ ret->num = virDomainGetVcpusFlags (dom, args->flags);
+ if (ret->num == -1) {
+ virDomainFree(dom);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virDomainFree(dom);
+ return 0;
+}
+
+static int
remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
@@ -2568,6 +2595,32 @@ remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
}
static int
+remoteDispatchDomainSetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ remote_domain_set_vcpus_flags_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virDomainPtr dom;
+
+ dom = get_nonnull_domain (conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virDomainSetVcpusFlags (dom, args->nvcpus, args->flags) == -1) {
+ virDomainFree(dom);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virDomainFree(dom);
+ return 0;
+}
+
+static int
remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index d8528b6..9583e9c 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -167,3 +167,5 @@
remote_domain_create_with_flags_args val_remote_domain_create_with_flags_args;
remote_domain_set_memory_parameters_args val_remote_domain_set_memory_parameters_args;
remote_domain_get_memory_parameters_args val_remote_domain_get_memory_parameters_args;
+ remote_domain_set_vcpus_flags_args val_remote_domain_set_vcpus_flags_args;
+ remote_domain_get_vcpus_flags_args val_remote_domain_get_vcpus_flags_args;
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
index b674bb4..6b35851 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -306,6 +306,14 @@ static int remoteDispatchDomainGetVcpus(
remote_error *err,
remote_domain_get_vcpus_args *args,
remote_domain_get_vcpus_ret *ret);
+static int remoteDispatchDomainGetVcpusFlags(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_message_header *hdr,
+ remote_error *err,
+ remote_domain_get_vcpus_flags_args *args,
+ remote_domain_get_vcpus_flags_ret *ret);
static int remoteDispatchDomainHasCurrentSnapshot(
struct qemud_server *server,
struct qemud_client *client,
@@ -554,6 +562,14 @@ static int remoteDispatchDomainSetVcpus(
remote_error *err,
remote_domain_set_vcpus_args *args,
void *ret);
+static int remoteDispatchDomainSetVcpusFlags(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_message_header *hdr,
+ remote_error *err,
+ remote_domain_set_vcpus_flags_args *args,
+ void *ret);
static int remoteDispatchDomainShutdown(
struct qemud_server *server,
struct qemud_client *client,
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
index 17c9bca..3723b00 100644
--- a/daemon/remote_dispatch_ret.h
+++ b/daemon/remote_dispatch_ret.h
@@ -136,3 +136,4 @@
remote_domain_get_block_info_ret val_remote_domain_get_block_info_ret;
remote_domain_create_with_flags_ret val_remote_domain_create_with_flags_ret;
remote_domain_get_memory_parameters_ret val_remote_domain_get_memory_parameters_ret;
+ remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret;
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index 47d95eb..dd2adc7 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -997,3 +997,13 @@
.args_filter = (xdrproc_t) xdr_remote_domain_get_memory_parameters_args,
.ret_filter = (xdrproc_t) xdr_remote_domain_get_memory_parameters_ret,
},
+{ /* DomainSetVcpusFlags => 199 */
+ .fn = (dispatch_fn) remoteDispatchDomainSetVcpusFlags,
+ .args_filter = (xdrproc_t) xdr_remote_domain_set_vcpus_flags_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
+{ /* DomainGetVcpusFlags => 200 */
+ .fn = (dispatch_fn) remoteDispatchDomainGetVcpusFlags,
+ .args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args,
+ .ret_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret,
+},
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 1a687ad..37c37ef 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2580,6 +2580,59 @@ done:
}
static int
+remoteDomainSetVcpusFlags (virDomainPtr domain, unsigned int nvcpus,
+ unsigned int flags)
+{
+ int rv = -1;
+ remote_domain_set_vcpus_flags_args args;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain (&args.dom, domain);
+ args.nvcpus = nvcpus;
+ args.flags = flags;
+
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS,
+ (xdrproc_t) xdr_remote_domain_set_vcpus_flags_args,
+ (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteDomainGetVcpusFlags (virDomainPtr domain, unsigned int flags)
+{
+ int rv = -1;
+ remote_domain_get_vcpus_flags_args args;
+ remote_domain_get_vcpus_flags_ret ret;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain (&args.dom, domain);
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS,
+ (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args, (char *) &args,
+ (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret, (char *) &ret) == -1)
+ goto done;
+
+ rv = ret.num;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
remoteDomainPinVcpu (virDomainPtr domain,
unsigned int vcpu,
unsigned char *cpumap,
@@ -10468,8 +10521,8 @@ static virDriver remote_driver = {
remoteDomainRestore, /* domainRestore */
remoteDomainCoreDump, /* domainCoreDump */
remoteDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ remoteDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ remoteDomainGetVcpusFlags, /* domainGetVcpusFlags */
remoteDomainPinVcpu, /* domainPinVcpu */
remoteDomainGetVcpus, /* domainGetVcpus */
remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
index 5c55713..38ea050 100644
--- a/src/remote/remote_protocol.c
+++ b/src/remote/remote_protocol.c
@@ -1355,6 +1355,39 @@ xdr_remote_domain_set_vcpus_args (XDR *xdrs, remote_domain_set_vcpus_args *objp)
}
bool_t
+xdr_remote_domain_set_vcpus_flags_args (XDR *xdrs, remote_domain_set_vcpus_flags_args *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->nvcpus))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_domain_get_vcpus_flags_args (XDR *xdrs, remote_domain_get_vcpus_flags_args *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->flags))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_domain_get_vcpus_flags_ret (XDR *xdrs, remote_domain_get_vcpus_flags_ret *objp)
+{
+
+ if (!xdr_int (xdrs, &objp->num))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_domain_pin_vcpu_args (XDR *xdrs, remote_domain_pin_vcpu_args *objp)
{
char **objp_cpp0 = (char **) (void *) &objp->cpumap.cpumap_val;
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
index 756da11..d75e76c 100644
--- a/src/remote/remote_protocol.h
+++ b/src/remote/remote_protocol.h
@@ -750,6 +750,24 @@ struct remote_domain_set_vcpus_args {
};
typedef struct remote_domain_set_vcpus_args remote_domain_set_vcpus_args;
+struct remote_domain_set_vcpus_flags_args {
+ remote_nonnull_domain dom;
+ u_int nvcpus;
+ u_int flags;
+};
+typedef struct remote_domain_set_vcpus_flags_args remote_domain_set_vcpus_flags_args;
+
+struct remote_domain_get_vcpus_flags_args {
+ remote_nonnull_domain dom;
+ u_int flags;
+};
+typedef struct remote_domain_get_vcpus_flags_args remote_domain_get_vcpus_flags_args;
+
+struct remote_domain_get_vcpus_flags_ret {
+ int num;
+};
+typedef struct remote_domain_get_vcpus_flags_ret remote_domain_get_vcpus_flags_ret;
+
struct remote_domain_pin_vcpu_args {
remote_nonnull_domain dom;
int vcpu;
@@ -2281,6 +2299,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS = 196,
REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
+ REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
+ REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200,
};
typedef enum remote_procedure remote_procedure;
@@ -2422,6 +2442,9 @@ extern bool_t xdr_remote_domain_define_xml_args (XDR *, remote_domain_define_xm
extern bool_t xdr_remote_domain_define_xml_ret (XDR *, remote_domain_define_xml_ret*);
extern bool_t xdr_remote_domain_undefine_args (XDR *, remote_domain_undefine_args*);
extern bool_t xdr_remote_domain_set_vcpus_args (XDR *, remote_domain_set_vcpus_args*);
+extern bool_t xdr_remote_domain_set_vcpus_flags_args (XDR *, remote_domain_set_vcpus_flags_args*);
+extern bool_t xdr_remote_domain_get_vcpus_flags_args (XDR *, remote_domain_get_vcpus_flags_args*);
+extern bool_t xdr_remote_domain_get_vcpus_flags_ret (XDR *, remote_domain_get_vcpus_flags_ret*);
extern bool_t xdr_remote_domain_pin_vcpu_args (XDR *, remote_domain_pin_vcpu_args*);
extern bool_t xdr_remote_domain_get_vcpus_args (XDR *, remote_domain_get_vcpus_args*);
extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*);
@@ -2762,6 +2785,9 @@ extern bool_t xdr_remote_domain_define_xml_args ();
extern bool_t xdr_remote_domain_define_xml_ret ();
extern bool_t xdr_remote_domain_undefine_args ();
extern bool_t xdr_remote_domain_set_vcpus_args ();
+extern bool_t xdr_remote_domain_set_vcpus_flags_args ();
+extern bool_t xdr_remote_domain_get_vcpus_flags_args ();
+extern bool_t xdr_remote_domain_get_vcpus_flags_ret ();
extern bool_t xdr_remote_domain_pin_vcpu_args ();
extern bool_t xdr_remote_domain_get_vcpus_args ();
extern bool_t xdr_remote_domain_get_vcpus_ret ();
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index e80fb5f..d57e6d0 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -768,6 +768,21 @@ struct remote_domain_set_vcpus_args {
int nvcpus;
};
+struct remote_domain_set_vcpus_flags_args {
+ remote_nonnull_domain dom;
+ unsigned int nvcpus;
+ unsigned int flags;
+};
+
+struct remote_domain_get_vcpus_flags_args {
+ remote_nonnull_domain dom;
+ unsigned int flags;
+};
+
+struct remote_domain_get_vcpus_flags_ret {
+ int num;
+};
+
struct remote_domain_pin_vcpu_args {
remote_nonnull_domain dom;
int vcpu;
@@ -2062,7 +2077,9 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON = 195,
REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS = 196,
REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
- REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198
+ REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
+ REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
+ REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 838423e..d505886 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -461,6 +461,18 @@ struct remote_domain_set_vcpus_args {
remote_nonnull_domain dom;
int nvcpus;
};
+struct remote_domain_set_vcpus_flags_args {
+ remote_nonnull_domain dom;
+ u_int nvcpus;
+ u_int flags;
+};
+struct remote_domain_get_vcpus_flags_args {
+ remote_nonnull_domain dom;
+ u_int flags;
+};
+struct remote_domain_get_vcpus_flags_ret {
+ int num;
+};
struct remote_domain_pin_vcpu_args {
remote_nonnull_domain dom;
int vcpu;
--
1.7.2.3

View File

@@ -0,0 +1,735 @@
From 50c51f13e2af04afac46e181c4ed62581545a488 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 27 Sep 2010 16:37:53 -0600
Subject: [PATCH 06/15] vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
---
src/esx/esx_driver.c | 32 +++++++++++++++++++---
src/openvz/openvz_driver.c | 34 +++++++++++++++++++++---
src/phyp/phyp_driver.c | 32 ++++++++++++++++++++---
src/qemu/qemu_driver.c | 38 +++++++++++++++++++++++++---
src/test/test_driver.c | 36 ++++++++++++++++++++++---
src/vbox/vbox_tmpl.c | 36 +++++++++++++++++++++++---
src/xen/xen_driver.c | 34 ++++++++++++++++++++++---
src/xenapi/xenapi_driver.c | 60 ++++++++++++++++++++++++++++++++++++++------
8 files changed, 263 insertions(+), 39 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 2a32374..b3e1284 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2384,7 +2384,8 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
static int
-esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
+esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
+ unsigned int flags)
{
int result = -1;
esxPrivate *priv = domain->conn->privateData;
@@ -2394,6 +2395,11 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
if (nvcpus < 1) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
_("Requested number of virtual CPUs must at least be 1"));
@@ -2453,15 +2459,26 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
}
+static int
+esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
+{
+ return esxDomainSetVcpusFlags(domain, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
static int
-esxDomainGetMaxVcpus(virDomainPtr domain)
+esxDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
esxPrivate *priv = domain->conn->privateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *hostSystem = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
if (priv->maxVcpus > 0) {
return priv->maxVcpus;
}
@@ -2507,7 +2524,12 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
return priv->maxVcpus;
}
-
+static int
+esxDomainGetMaxVcpus(virDomainPtr domain)
+{
+ return esxDomainGetVcpusFlags(domain, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
static char *
esxDomainDumpXML(virDomainPtr domain, int flags)
@@ -4160,8 +4182,8 @@ static virDriver esxDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
esxDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ esxDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ esxDomainGetVcpusFlags, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
esxDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 9d19aeb..0f3cfdf 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -67,7 +67,6 @@
static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid);
static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
static int openvzDomainGetMaxVcpus(virDomainPtr dom);
-static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus);
static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
unsigned int nvcpus);
static int openvzDomainSetMemoryInternal(virDomainObjPtr vm,
@@ -1211,11 +1210,24 @@ static int openvzGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
return -1;
}
+static int
+openvzDomainGetVcpusFlags(virDomainPtr dom ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ openvzError(VIR_ERR_INVALID_ARG, _("unsupported flags (0x%x)"), flags);
+ return -1;
+ }
-static int openvzDomainGetMaxVcpus(virDomainPtr dom ATTRIBUTE_UNUSED) {
return openvzGetMaxVCPUs(NULL, "openvz");
}
+static int openvzDomainGetMaxVcpus(virDomainPtr dom)
+{
+ return openvzDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
unsigned int nvcpus)
{
@@ -1241,12 +1253,18 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
return 0;
}
-static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
+static int openvzDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
+ unsigned int flags)
{
virDomainObjPtr vm;
struct openvz_driver *driver = dom->conn->privateData;
int ret = -1;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ openvzError(VIR_ERR_INVALID_ARG, _("unsupported flags (0x%x)"), flags);
+ return -1;
+ }
+
openvzDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
openvzDriverUnlock(driver);
@@ -1272,6 +1290,12 @@ cleanup:
return ret;
}
+static int
+openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
+{
+ return openvzDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
static virDrvOpenStatus openvzOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED)
@@ -1590,8 +1614,8 @@ static virDriver openvzDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
openvzDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ openvzDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ openvzDomainGetVcpusFlags, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 6e0a5e9..e284ae0 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -1497,15 +1497,27 @@ phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
}
static int
-phypGetLparCPUMAX(virDomainPtr dom)
+phypDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
{
phyp_driverPtr phyp_driver = dom->conn->privateData;
char *managed_system = phyp_driver->managed_system;
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ PHYP_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1);
}
static int
+phypGetLparCPUMAX(virDomainPtr dom)
+{
+ return phypDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
+static int
phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
const char *lpar_name)
{
@@ -3831,7 +3843,8 @@ phypConnectGetCapabilities(virConnectPtr conn)
}
static int
-phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
+phypDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
+ unsigned int flags)
{
ConnectionData *connection_data = dom->conn->networkPrivateData;
phyp_driverPtr phyp_driver = dom->conn->privateData;
@@ -3846,6 +3859,11 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
unsigned int amount = 0;
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ PHYP_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
return 0;
@@ -3891,6 +3909,12 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
}
+static int
+phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
+{
+ return phypDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
static virDrvOpenStatus
phypVIOSDriverOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
@@ -3941,8 +3965,8 @@ static virDriver phypDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
phypDomainSetCPU, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ phypDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ phypDomainGetVcpusFlags, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
phypGetLparCPUMAX, /* domainGetMaxVcpus */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3d17e04..7a2ea8f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5934,13 +5934,22 @@ unsupported:
}
-static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
+static int
+qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
+ unsigned int flags)
+{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
const char * type;
int max;
int ret = -1;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
+ flags);
+ return -1;
+ }
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
@@ -5994,6 +6003,12 @@ cleanup:
return ret;
}
+static int
+qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
+{
+ return qemudDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
static int
qemudDomainPinVcpu(virDomainPtr dom,
@@ -6150,12 +6165,20 @@ cleanup:
}
-static int qemudDomainGetMaxVcpus(virDomainPtr dom) {
+static int
+qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
const char *type;
int ret = -1;
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
+ flags);
+ return -1;
+ }
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
@@ -6183,6 +6206,13 @@ cleanup:
return ret;
}
+static int
+qemudDomainGetMaxVcpus(virDomainPtr dom)
+{
+ return qemudDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel)
{
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
@@ -12938,8 +12968,8 @@ static virDriver qemuDriver = {
qemudDomainRestore, /* domainRestore */
qemudDomainCoreDump, /* domainCoreDump */
qemudDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */
qemudDomainPinVcpu, /* domainPinVcpu */
qemudDomainGetVcpus, /* domainGetVcpus */
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 6a00558..b70c80d 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -2029,17 +2029,37 @@ cleanup:
return ret;
}
-static int testDomainGetMaxVcpus(virDomainPtr domain)
+static int
+testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
return testGetMaxVCPUs(domain->conn, "test");
}
-static int testSetVcpus(virDomainPtr domain,
- unsigned int nrCpus) {
+static int
+testDomainGetMaxVcpus(virDomainPtr domain)
+{
+ return testDomainGetVcpusFlags(domain, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
+static int
+testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
+ unsigned int flags)
+{
testConnPtr privconn = domain->conn->privateData;
virDomainObjPtr privdom = NULL;
int ret = -1, maxvcpus;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
/* Do this first before locking */
maxvcpus = testDomainGetMaxVcpus(domain);
if (maxvcpus < 0)
@@ -2082,6 +2102,12 @@ cleanup:
return ret;
}
+static int
+testSetVcpus(virDomainPtr domain, unsigned int nrCpus)
+{
+ return testDomainSetVcpusFlags(domain, nrCpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
static int testDomainGetVcpus(virDomainPtr domain,
virVcpuInfoPtr info,
int maxinfo,
@@ -5260,8 +5286,8 @@ static virDriver testDriver = {
testDomainRestore, /* domainRestore */
testDomainCoreDump, /* domainCoreDump */
testSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ testDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ testDomainGetVcpusFlags, /* domainGetVcpusFlags */
testDomainPinVcpu, /* domainPinVcpu */
testDomainGetVcpus, /* domainGetVcpus */
testDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index cb9193a..0cbe8b3 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -1839,13 +1839,21 @@ cleanup:
return ret;
}
-static int vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
+static int
+vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
+ unsigned int flags)
+{
VBOX_OBJECT_CHECK(dom->conn, int, -1);
IMachine *machine = NULL;
vboxIID *iid = NULL;
PRUint32 CPUCount = nvcpus;
nsresult rc;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ vboxError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
#if VBOX_API_VERSION == 2002
if (VIR_ALLOC(iid) < 0) {
virReportOOMError();
@@ -1887,11 +1895,24 @@ cleanup:
return ret;
}
-static int vboxDomainGetMaxVcpus(virDomainPtr dom) {
+static int
+vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
+{
+ return vboxDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
+static int
+vboxDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+{
VBOX_OBJECT_CHECK(dom->conn, int, -1);
ISystemProperties *systemProperties = NULL;
PRUint32 maxCPUCount = 0;
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ vboxError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ return -1;
+ }
+
/* Currently every domain supports the same number of max cpus
* as that supported by vbox and thus take it directly from
* the systemproperties.
@@ -1909,6 +1930,13 @@ static int vboxDomainGetMaxVcpus(virDomainPtr dom) {
return ret;
}
+static int
+vboxDomainGetMaxVcpus(virDomainPtr dom)
+{
+ return vboxDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
virDomainDefPtr def = NULL;
@@ -8267,8 +8295,8 @@ virDriver NAME(Driver) = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
vboxDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ vboxDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ vboxDomainGetVcpusFlags, /* domainGetVcpusFlags */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 7d67ced..d6c9c57 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1069,11 +1069,18 @@ xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
}
static int
-xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
+xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
+ unsigned int flags)
{
GET_PRIVATE(dom->conn);
int i;
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
+ flags);
+ return -1;
+ }
+
/* Try non-hypervisor methods first, then hypervisor direct method
* as a last resort.
*/
@@ -1093,6 +1100,12 @@ xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
}
static int
+xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
+{
+ return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
+static int
xenUnifiedDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
unsigned char *cpumap, int maplen)
{
@@ -1126,11 +1139,17 @@ xenUnifiedDomainGetVcpus (virDomainPtr dom,
}
static int
-xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
+xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
{
GET_PRIVATE(dom->conn);
int i, ret;
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
+ flags);
+ return -1;
+ }
+
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
ret = drivers[i]->domainGetMaxVcpus (dom);
@@ -1140,6 +1159,13 @@ xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
return -1;
}
+static int
+xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
+{
+ return xenUnifiedDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
static char *
xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
{
@@ -1951,8 +1977,8 @@ static virDriver xenUnifiedDriver = {
xenUnifiedDomainRestore, /* domainRestore */
xenUnifiedDomainCoreDump, /* domainCoreDump */
xenUnifiedDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ xenUnifiedDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ xenUnifiedDomainGetVcpusFlags, /* domainGetVcpusFlags */
xenUnifiedDomainPinVcpu, /* domainPinVcpu */
xenUnifiedDomainGetVcpus, /* domainGetVcpus */
xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 753169c..7d4ab8d 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -40,6 +40,11 @@
#include "xenapi_driver_private.h"
#include "xenapi_utils.h"
+#define VIR_FROM_THIS VIR_FROM_XENAPI
+
+#define xenapiError(code, ...) \
+ virReportErrorHelper(NULL, VIR_FROM_THIS, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
/*
* getCapsObject
@@ -987,19 +992,26 @@ xenapiDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
/*
- * xenapiDomainSetVcpus
+ * xenapiDomainSetVcpusFlags
*
* Sets the VCPUs on the domain
* Return 0 on success or -1 in case of error
*/
static int
-xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
+xenapiDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
+ unsigned int flags)
{
-
/* vm.set_vcpus_max */
xen_vm vm;
xen_vm_set *vms;
xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
+
+ if (flags != VIR_DOMAIN_VCPU_LIVE) {
+ xenapiError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
+ flags);
+ return -1;
+ }
+
if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
if (vms->size != 1) {
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
@@ -1019,6 +1031,18 @@ xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
}
/*
+ * xenapiDomainSetVcpus
+ *
+ * Sets the VCPUs on the domain
+ * Return 0 on success or -1 in case of error
+ */
+static int
+xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
+{
+ return xenapiDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+}
+
+/*
* xenapiDomainPinVcpu
*
* Dynamically change the real CPUs which can be allocated to a virtual CPU
@@ -1140,19 +1164,26 @@ xenapiDomainGetVcpus (virDomainPtr dom,
}
/*
- * xenapiDomainGetMaxVcpus
+ * xenapiDomainGetVcpusFlags
*
*
- * Returns maximum number of Vcpus on success or -1 in case of error
+ * Returns Vcpus count on success or -1 in case of error
*/
static int
-xenapiDomainGetMaxVcpus (virDomainPtr dom)
+xenapiDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
{
xen_vm vm;
xen_vm_set *vms;
int64_t maxvcpu = 0;
enum xen_vm_power_state state;
xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
+
+ if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
+ xenapiError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
+ flags);
+ return -1;
+ }
+
if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
if (vms->size != 1) {
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
@@ -1176,6 +1207,19 @@ xenapiDomainGetMaxVcpus (virDomainPtr dom)
}
/*
+ * xenapiDomainGetMaxVcpus
+ *
+ *
+ * Returns maximum number of Vcpus on success or -1 in case of error
+ */
+static int
+xenapiDomainGetMaxVcpus (virDomainPtr dom)
+{
+ return xenapiDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
+/*
* xenapiDomainDumpXML
*
*
@@ -1754,8 +1798,8 @@ static virDriver xenapiDriver = {
NULL, /* domainRestore */
NULL, /* domainCoreDump */
xenapiDomainSetVcpus, /* domainSetVcpus */
- NULL, /* domainSetVcpusFlags */
- NULL, /* domainGetVcpusFlags */
+ xenapiDomainSetVcpusFlags, /* domainSetVcpusFlags */
+ xenapiDomainGetVcpusFlags, /* domainGetVcpusFlags */
xenapiDomainPinVcpu, /* domainPinVcpu */
xenapiDomainGetVcpus, /* domainGetVcpus */
xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
--
1.7.2.3

View File

@@ -0,0 +1,388 @@
From bf945ee97b72d3b0c4fc2da04530f5294f529d66 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 29 Sep 2010 15:20:23 -0600
Subject: [PATCH 08/15] vcpu: add virsh support
* tools/virsh.c (cmdSetvcpus): Add new flags. Let invalid
commands through to driver, to ease testing of hypervisor argument
validation.
(cmdMaxvcpus, cmdVcpucount): New commands.
(commands): Add new commands.
* tools/virsh.pod (setvcpus, vcpucount, maxvcpus): Document new
behavior.
---
tools/virsh.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
tools/virsh.pod | 38 ++++++++-
2 files changed, 262 insertions(+), 23 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 4f8c495..7fb7fbd 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2281,10 +2281,216 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd)
}
/*
+ * "maxvcpus" command
+ */
+static const vshCmdInfo info_maxvcpus[] = {
+ {"help", N_("connection vcpu maximum")},
+ {"desc", N_("Show maximum number of virtual CPUs for guests on this connection.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_maxvcpus[] = {
+ {"type", VSH_OT_STRING, 0, N_("domain type")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
+{
+ char *type;
+ int vcpus;
+
+ type = vshCommandOptString(cmd, "type", NULL);
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ return FALSE;
+
+ vcpus = virConnectGetMaxVcpus(ctl->conn, type);
+ if (vcpus < 0)
+ return FALSE;
+ vshPrint(ctl, "%d\n", vcpus);
+
+ return TRUE;
+}
+
+/*
+ * "vcpucount" command
+ */
+static const vshCmdInfo info_vcpucount[] = {
+ {"help", N_("domain vcpu counts")},
+ {"desc", N_("Returns the number of virtual CPUs used by the domain.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_vcpucount[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"maximum", VSH_OT_BOOL, 0, N_("get maximum cap on vcpus")},
+ {"current", VSH_OT_BOOL, 0, N_("get current vcpu usage")},
+ {"config", VSH_OT_BOOL, 0, N_("get value to be used on next boot")},
+ {"live", VSH_OT_BOOL, 0, N_("get value from running domain")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdVcpucount(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom;
+ int ret = TRUE;
+ int maximum = vshCommandOptBool(cmd, "maximum");
+ int current = vshCommandOptBool(cmd, "current");
+ int config = vshCommandOptBool(cmd, "config");
+ int live = vshCommandOptBool(cmd, "live");
+ bool all = maximum + current + config + live == 0;
+ int count;
+
+ if (maximum && current) {
+ vshError(ctl, "%s",
+ _("--maximum and --current cannot both be specified"));
+ return FALSE;
+ }
+ if (config && live) {
+ vshError(ctl, "%s",
+ _("--config and --live cannot both be specified"));
+ return FALSE;
+ }
+ /* We want one of each pair of mutually exclusive options; that
+ * is, use of flags requires exactly two options. */
+ if (maximum + current + config + live == 1) {
+ vshError(ctl,
+ _("when using --%s, either --%s or --%s must be specified"),
+ (maximum ? "maximum" : current ? "current"
+ : config ? "config" : "live"),
+ maximum + current ? "config" : "maximum",
+ maximum + current ? "live" : "current");
+ return FALSE;
+ }
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return FALSE;
+
+ /* In all cases, try the new API first; if it fails because we are
+ * talking to an older client, try a fallback API before giving
+ * up. */
+ if (all || (maximum && config)) {
+ count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
+ VIR_DOMAIN_VCPU_CONFIG));
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
+ char *tmp;
+ char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
+ if (xml && (tmp = strstr(xml, "<vcpu"))) {
+ tmp = strchr(tmp, '>');
+ if (!tmp || virStrToLong_i(tmp + 1, &tmp, 10, &count) < 0)
+ count = -1;
+ }
+ VIR_FREE(xml);
+ }
+
+ if (count < 0) {
+ virshReportError(ctl);
+ ret = FALSE;
+ } else if (all) {
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("config"),
+ count);
+ } else {
+ vshPrint(ctl, "%d\n", count);
+ }
+ virFreeError(last_error);
+ last_error = NULL;
+ }
+
+ if (all || (maximum && live)) {
+ count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
+ VIR_DOMAIN_VCPU_LIVE));
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
+ count = virDomainGetMaxVcpus(dom);
+ }
+
+ if (count < 0) {
+ virshReportError(ctl);
+ ret = FALSE;
+ } else if (all) {
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("live"),
+ count);
+ } else {
+ vshPrint(ctl, "%d\n", count);
+ }
+ virFreeError(last_error);
+ last_error = NULL;
+ }
+
+ if (all || (current && config)) {
+ count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_CONFIG);
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
+ char *tmp, *end;
+ char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
+ if (xml && (tmp = strstr(xml, "<vcpu"))) {
+ end = strchr(tmp, '>');
+ if (end) {
+ *end = '\0';
+ tmp = strstr(tmp, "current=");
+ if (!tmp)
+ tmp = end + 1;
+ else {
+ tmp += strlen("current=");
+ tmp += *tmp == '\'' || *tmp == '"';
+ }
+ }
+ if (!tmp || virStrToLong_i(tmp, &tmp, 10, &count) < 0)
+ count = -1;
+ }
+ VIR_FREE(xml);
+ }
+
+ if (count < 0) {
+ virshReportError(ctl);
+ ret = FALSE;
+ } else if (all) {
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("config"),
+ count);
+ } else {
+ vshPrint(ctl, "%d\n", count);
+ }
+ virFreeError(last_error);
+ last_error = NULL;
+ }
+
+ if (all || (current && live)) {
+ count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_LIVE);
+ if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
+ || last_error->code == VIR_ERR_INVALID_ARG)) {
+ virDomainInfo info;
+ if (virDomainGetInfo(dom, &info) == 0)
+ count = info.nrVirtCpu;
+ }
+
+ if (count < 0) {
+ virshReportError(ctl);
+ ret = FALSE;
+ } else if (all) {
+ vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("live"),
+ count);
+ } else {
+ vshPrint(ctl, "%d\n", count);
+ }
+ virFreeError(last_error);
+ last_error = NULL;
+ }
+
+ virDomainFree(dom);
+ return ret;
+}
+
+/*
* "vcpuinfo" command
*/
static const vshCmdInfo info_vcpuinfo[] = {
- {"help", N_("domain vcpu information")},
+ {"help", N_("detailed domain vcpu information")},
{"desc", N_("Returns basic information about the domain virtual CPUs.")},
{NULL, NULL}
};
@@ -2514,6 +2720,9 @@ static const vshCmdInfo info_setvcpus[] = {
static const vshCmdOptDef opts_setvcpus[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
{"count", VSH_OT_DATA, VSH_OFLAG_REQ, N_("number of virtual CPUs")},
+ {"maximum", VSH_OT_BOOL, 0, N_("set maximum limit on next boot")},
+ {"config", VSH_OT_BOOL, 0, N_("affect next boot")},
+ {"live", VSH_OT_BOOL, 0, N_("affect running domain")},
{NULL, 0, 0, NULL}
};
@@ -2522,8 +2731,13 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom;
int count;
- int maxcpu;
int ret = TRUE;
+ int maximum = vshCommandOptBool(cmd, "maximum");
+ int config = vshCommandOptBool(cmd, "config");
+ int live = vshCommandOptBool(cmd, "live");
+ int flags = ((maximum ? VIR_DOMAIN_VCPU_MAXIMUM : 0) |
+ (config ? VIR_DOMAIN_VCPU_CONFIG : 0) |
+ (live ? VIR_DOMAIN_VCPU_LIVE : 0));
if (!vshConnectionUsability(ctl, ctl->conn))
return FALSE;
@@ -2532,26 +2746,15 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
return FALSE;
count = vshCommandOptInt(cmd, "count", &count);
- if (count <= 0) {
- vshError(ctl, "%s", _("Invalid number of virtual CPUs."));
- virDomainFree(dom);
- return FALSE;
- }
-
- maxcpu = virDomainGetMaxVcpus(dom);
- if (maxcpu <= 0) {
- virDomainFree(dom);
- return FALSE;
- }
-
- if (count > maxcpu) {
- vshError(ctl, "%s", _("Too many virtual CPUs."));
- virDomainFree(dom);
- return FALSE;
- }
- if (virDomainSetVcpus(dom, count) != 0) {
- ret = FALSE;
+ if (!flags) {
+ if (virDomainSetVcpus(dom, count) != 0) {
+ ret = FALSE;
+ }
+ } else {
+ if (virDomainSetVcpusFlags(dom, count, flags) < 0) {
+ ret = FALSE;
+ }
}
virDomainFree(dom);
@@ -9642,6 +9845,7 @@ static const vshCmdDef commands[] = {
{"freecell", cmdFreecell, opts_freecell, info_freecell},
{"hostname", cmdHostname, NULL, info_hostname},
{"list", cmdList, opts_list, info_list},
+ {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus},
{"migrate", cmdMigrate, opts_migrate, info_migrate},
{"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
@@ -9748,6 +9952,7 @@ static const vshCmdDef commands[] = {
{"vol-name", cmdVolName, opts_vol_name, info_vol_name},
{"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
+ {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount},
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
{"version", cmdVersion, NULL, info_version},
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 943a563..dbcc680 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -443,7 +443,14 @@ Remove the managed save file for a domain if it exists. The next time the
domain is started it will not restore to its previous state but instead will
do a full boot.
-=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi> I<migrateuri>
+=item B<maxvcpus> optional I<type>
+
+Provide the maximum number of virtual CPUs supported for a guest VM on
+this connection. If provided, the I<type> parameter must be a valid
+type attribute for the <domain> element of XML.
+
+=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi>
+I<migrateuri>
Migrate domain to another host. Add --live for live migration; --suspend
leaves the domain paused on the destination host. The I<desturi> is the
@@ -521,7 +528,8 @@ Displays the domain memory parameters.
Allows you to set the domain memory parameters. LXC and QEMU/KVM supports these parameters.
-=item B<setvcpus> I<domain-id> I<count>
+=item B<setvcpus> I<domain-id> I<count> optional I<--maximum> I<--config>
+I<--live>
Change the number of virtual CPUs active in the guest domain. Note that
I<count> may be limited by host, hypervisor or limit coming from the
@@ -530,6 +538,17 @@ original description of domain.
For Xen, you can only adjust the virtual CPUs of a running domain if
the domain is paravirtualized.
+If I<--config> is specified, the change will only affect the next
+boot of a domain. If I<--live> is specified, the domain must be
+running, and the change takes place immediately. Both flags may be
+specified, if supported by the hypervisor. If neither flag is given,
+then I<--live> is implied and it is up to the hypervisor whether
+I<--config> is also implied.
+
+If I<--maximum> is specified, then you must use I<--config> and
+avoid I<--live>; this flag controls the maximum limit of vcpus that
+can be hot-plugged the next time the domain is booted.
+
=item B<shutdown> I<domain-id>
Gracefully shuts down a domain. This coordinates with the domain OS
@@ -568,6 +587,21 @@ is not available the processes will provide an exit code of 1.
Undefine the configuration for an inactive domain. Since it's not running
the domain name or UUID must be used as the I<domain-id>.
+=item B<vcpucount> I<domain-id> optional I<--maximum> I<--current>
+I<--config> I<--live>
+
+Print information about the virtual cpu counts of the given
+I<domain-id>. If no flags are specified, all possible counts are
+listed in a table; otherwise, the output is limited to just the
+numeric value requested.
+
+I<--maximum> requests information on the maximum cap of vcpus that a
+domain can add via B<setvcpus>, while I<--current> shows the current
+usage; these two flags cannot both be specified. I<--config>
+requests information regarding the next time the domain will be
+booted, while I<--live> requires a running domain and lists current
+values; these two flags cannot both be specified.
+
=item B<vcpuinfo> I<domain-id>
Returns basic information about the domain virtual CPUs, like the number of
--
1.7.2.3

View File

@@ -0,0 +1,519 @@
From 4617eedfaeee2b187a1f14691d25746ba3ff31b6 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 29 Sep 2010 10:20:07 -0600
Subject: [PATCH 07/15] vcpu: support maxvcpu in domain_conf
Although this patch adds a distinction between maximum vcpus and
current vcpus in the XML, the values should be identical for all
drivers at this point. Only in subsequent per-driver patches will
a distinction be made.
In general, virDomainGetInfo should prefer the current vcpus.
* src/conf/domain_conf.h (_virDomainDef): Adjust vcpus to unsigned
short, to match virDomainGetInfo limit. Add maxvcpus member.
* src/conf/domain_conf.c (virDomainDefParseXML)
(virDomainDefFormat): parse and print out vcpu details.
* src/xen/xend_internal.c (xenDaemonParseSxpr)
(xenDaemonFormatSxpr): Manage both vcpu numbers, and require them
to be equal for now.
* src/xen/xm_internal.c (xenXMDomainConfigParse)
(xenXMDomainConfigFormat): Likewise.
* src/phyp/phyp_driver.c (phypDomainDumpXML): Likewise.
* src/openvz/openvz_conf.c (openvzLoadDomains): Likewise.
* src/openvz/openvz_driver.c (openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainSetVcpusInternal): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxDomainDefineXML):
Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/esx/esx_vmx.c (esxVMX_ParseConfig, esxVMX_FormatConfig):
Likewise.
* src/qemu/qemu_conf.c (qemuBuildSmpArgStr)
(qemuParseCommandLineSmp, qemuParseCommandLine): Likewise.
* src/qemu/qemu_driver.c (qemudDomainHotplugVcpus): Likewise.
* src/opennebula/one_conf.c (xmlOneTemplate): Likewise.
---
src/conf/domain_conf.c | 45 +++++++++++++++++++++++++++++++++++++------
src/conf/domain_conf.h | 3 +-
src/esx/esx_vmx.c | 24 ++++++++++++++--------
src/opennebula/one_conf.c | 9 +++++--
src/openvz/openvz_conf.c | 7 +++--
src/openvz/openvz_driver.c | 15 +++++++++----
src/phyp/phyp_driver.c | 2 +-
src/qemu/qemu_conf.c | 14 +++++++++++-
src/qemu/qemu_driver.c | 5 ++-
src/vbox/vbox_tmpl.c | 12 +++++++---
src/xen/xend_internal.c | 9 ++++---
src/xen/xm_internal.c | 11 ++++++---
src/xenapi/xenapi_driver.c | 2 +-
src/xenapi/xenapi_utils.c | 4 +-
14 files changed, 114 insertions(+), 48 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 78d7a6a..a997e06 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4203,6 +4203,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
int i, n;
long id = -1;
virDomainDefPtr def;
+ unsigned long count;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -4287,8 +4288,37 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
&def->mem.swap_hard_limit) < 0)
def->mem.swap_hard_limit = 0;
- if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0)
- def->vcpus = 1;
+ n = virXPathULong("string(./vcpu[1])", ctxt, &count);
+ if (n == -2) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("maximum vcpus must be an integer"));
+ goto error;
+ } else if (n < 0) {
+ def->maxvcpus = 1;
+ } else {
+ def->maxvcpus = count;
+ if (def->maxvcpus != count || count == 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("invalid maxvcpus %lu"), count);
+ goto error;
+ }
+ }
+
+ n = virXPathULong("string(./vcpu[1]/@current)", ctxt, &count);
+ if (n == -2) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("current vcpus must be an integer"));
+ goto error;
+ } else if (n < 0) {
+ def->vcpus = def->maxvcpus;
+ } else {
+ def->vcpus = count;
+ if (def->vcpus != count || count == 0 || def->maxvcpus < count) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("invalid current vcpus %lu"), count);
+ goto error;
+ }
+ }
tmp = virXPathString("string(./vcpu[1]/@cpuset)", ctxt);
if (tmp) {
@@ -6462,17 +6492,18 @@ char *virDomainDefFormat(virDomainDefPtr def,
if (def->cpumask[n] != 1)
allones = 0;
- if (allones) {
- virBufferAsprintf(&buf, " <vcpu>%lu</vcpu>\n", def->vcpus);
- } else {
+ virBufferAddLit(&buf, " <vcpu");
+ if (!allones) {
char *cpumask = NULL;
if ((cpumask =
virDomainCpuSetFormat(def->cpumask, def->cpumasklen)) == NULL)
goto cleanup;
- virBufferAsprintf(&buf, " <vcpu cpuset='%s'>%lu</vcpu>\n",
- cpumask, def->vcpus);
+ virBufferAsprintf(&buf, " cpuset='%s'", cpumask);
VIR_FREE(cpumask);
}
+ if (def->vcpus != def->maxvcpus)
+ virBufferAsprintf(&buf, " current='%u'", def->vcpus);
+ virBufferAsprintf(&buf, ">%u</vcpu>\n", def->maxvcpus);
if (def->os.bootloader) {
virBufferEscapeString(&buf, " <bootloader>%s</bootloader>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index db09c23..5499f28 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -885,7 +885,8 @@ struct _virDomainDef {
unsigned long min_guarantee;
unsigned long swap_hard_limit;
} mem;
- unsigned long vcpus;
+ unsigned short vcpus;
+ unsigned short maxvcpus;
int cpumasklen;
char *cpumask;
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
index 7ec8c0e..0a26614 100644
--- a/src/esx/esx_vmx.c
+++ b/src/esx/esx_vmx.c
@@ -50,7 +50,7 @@ def->uuid = <value> <=> uuid.bios = "<value>"
def->name = <value> <=> displayName = "<value>"
def->mem.max_balloon = <value kilobyte> <=> memsize = "<value megabyte>" # must be a multiple of 4, defaults to 32
def->mem.cur_balloon = <value kilobyte> <=> sched.mem.max = "<value megabyte>" # defaults to "unlimited" -> def->mem.cur_balloon = def->mem.max_balloon
-def->vcpus = <value> <=> numvcpus = "<value>" # must be 1 or a multiple of 2, defaults to 1
+def->maxvcpus = <value> <=> numvcpus = "<value>" # must be 1 or a multiple of 2, defaults to 1
def->cpumask = <uint list> <=> sched.cpu.affinity = "<uint list>"
@@ -1075,7 +1075,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
goto cleanup;
}
- def->vcpus = numvcpus;
+ def->maxvcpus = def->vcpus = numvcpus;
/* vmx:sched.cpu.affinity -> def:cpumask */
// VirtualMachine:config.cpuAffinity.affinitySet
@@ -2609,16 +2609,22 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
(int)(def->mem.cur_balloon / 1024));
}
- /* def:vcpus -> vmx:numvcpus */
- if (def->vcpus <= 0 || (def->vcpus % 2 != 0 && def->vcpus != 1)) {
+ /* def:maxvcpus -> vmx:numvcpus */
+ if (def->vcpus != def->maxvcpus) {
+ ESX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("No support for domain XML entry 'vcpu' attribute "
+ "'current'"));
+ goto cleanup;
+ }
+ if (def->maxvcpus <= 0 || (def->maxvcpus % 2 != 0 && def->maxvcpus != 1)) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Expecting domain XML entry 'vcpu' to be an unsigned "
"integer (1 or a multiple of 2) but found %d"),
- (int)def->vcpus);
+ def->maxvcpus);
goto cleanup;
}
- virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", (int)def->vcpus);
+ virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", def->maxvcpus);
/* def:cpumask -> vmx:sched.cpu.affinity */
if (def->cpumasklen > 0) {
@@ -2632,11 +2638,11 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
}
}
- if (sched_cpu_affinity_length < def->vcpus) {
+ if (sched_cpu_affinity_length < def->maxvcpus) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Expecting domain XML attribute 'cpuset' of entry "
- "'vcpu' to contains at least %d CPU(s)"),
- (int)def->vcpus);
+ "'vcpu' to contain at least %d CPU(s)"),
+ def->maxvcpus);
goto cleanup;
}
diff --git a/src/opennebula/one_conf.c b/src/opennebula/one_conf.c
index 44e28dc..2079c51 100644
--- a/src/opennebula/one_conf.c
+++ b/src/opennebula/one_conf.c
@@ -1,5 +1,7 @@
/*----------------------------------------------------------------------------------*/
-/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* This library is free software; you can redistribute it and/or
@@ -169,9 +171,10 @@ char* xmlOneTemplate(virDomainDefPtr def)
{
int i;
virBuffer buf= VIR_BUFFER_INITIALIZER;
- virBufferAsprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
+ virBufferAsprintf(&buf,"#OpenNebula Template automatically generated "
+ "by libvirt\nNAME = %s\nCPU = %d\nMEMORY = %ld\n",
def->name,
- def->vcpus,
+ def->maxvcpus,
(def->mem.max_balloon)/1024);
/*Optional Booting OpenNebula Information:*/
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index ec11bbc..c84a6f3 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -507,11 +507,12 @@ int openvzLoadDomains(struct openvz_driver *driver) {
veid);
goto cleanup;
} else if (ret > 0) {
- dom->def->vcpus = strtoI(temp);
+ dom->def->maxvcpus = strtoI(temp);
}
- if (ret == 0 || dom->def->vcpus == 0)
- dom->def->vcpus = openvzGetNodeCPUs();
+ if (ret == 0 || dom->def->maxvcpus == 0)
+ dom->def->maxvcpus = openvzGetNodeCPUs();
+ dom->def->vcpus = dom->def->maxvcpus;
/* XXX load rest of VM config data .... */
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 0f3cfdf..b7c2754 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -925,8 +925,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
goto cleanup;
- if (vm->def->vcpus > 0) {
- if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
+ if (vm->def->vcpus != vm->def->maxvcpus) {
+ openvzError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("current vcpu count must equal maximum"));
+ goto cleanup;
+ }
+ if (vm->def->maxvcpus > 0) {
+ if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not set number of virtual cpu"));
goto cleanup;
@@ -1019,8 +1024,8 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
vm->def->id = vm->pid;
vm->state = VIR_DOMAIN_RUNNING;
- if (vm->def->vcpus > 0) {
- if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
+ if (vm->def->maxvcpus > 0) {
+ if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not set number of virtual cpu"));
goto cleanup;
@@ -1249,7 +1254,7 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
return -1;
}
- vm->def->vcpus = nvcpus;
+ vm->def->maxvcpus = vm->def->vcpus = nvcpus;
return 0;
}
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index e284ae0..3d0ed11 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -3540,7 +3540,7 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
goto err;
}
- if ((def.vcpus =
+ if ((def.maxvcpus = def.vcpus =
phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
VIR_ERROR0(_("Unable to determine domain's CPU."));
goto err;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 83c0f83..38c8351 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -3711,7 +3711,7 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- virBufferAsprintf(&buf, "%lu", def->vcpus);
+ virBufferAsprintf(&buf, "%u", def->vcpus);
if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
/* sockets, cores, and threads are either all zero
@@ -3722,11 +3722,18 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
}
else {
- virBufferAsprintf(&buf, ",sockets=%lu", def->vcpus);
+ virBufferAsprintf(&buf, ",sockets=%u", def->maxvcpus);
virBufferAsprintf(&buf, ",cores=%u", 1);
virBufferAsprintf(&buf, ",threads=%u", 1);
}
}
+ if (def->vcpus != def->maxvcpus) {
+ virBufferFreeAndReset(&buf);
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("setting current vcpu count less than maximum is "
+ "not supported yet"));
+ return NULL;
+ }
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
@@ -6178,6 +6185,8 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
}
}
+ dom->maxvcpus = dom->vcpus;
+
if (sockets && cores && threads) {
virCPUDefPtr cpu;
@@ -6247,6 +6256,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
def->id = -1;
def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024;
+ def->maxvcpus = 1;
def->vcpus = 1;
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7a2ea8f..c66dc04 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2425,8 +2425,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver,
if (ncpupids != vm->def->vcpus) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("got wrong number of vCPU pids from QEMU monitor. got %d, wanted %d"),
- ncpupids, (int)vm->def->vcpus);
+ _("got wrong number of vCPU pids from QEMU monitor. "
+ "got %d, wanted %d"),
+ ncpupids, vm->def->vcpus);
VIR_FREE(cpupids);
return -1;
}
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 0cbe8b3..5a859a4 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -2028,7 +2028,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
def->mem.max_balloon = memorySize * 1024;
machine->vtbl->GetCPUCount(machine, &CPUCount);
- def->vcpus = CPUCount;
+ def->maxvcpus = def->vcpus = CPUCount;
/* Skip cpumasklen, cpumask, onReboot, onPoweroff, onCrash */
@@ -4598,11 +4598,15 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
def->mem.cur_balloon, (unsigned)rc);
}
- rc = machine->vtbl->SetCPUCount(machine, def->vcpus);
+ if (def->vcpus != def->maxvcpus) {
+ vboxError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("current vcpu count must equal maximum"));
+ }
+ rc = machine->vtbl->SetCPUCount(machine, def->maxvcpus);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_INTERNAL_ERROR,
- _("could not set the number of virtual CPUs to: %lu, rc=%08x"),
- def->vcpus, (unsigned)rc);
+ _("could not set the number of virtual CPUs to: %u, rc=%08x"),
+ def->maxvcpus, (unsigned)rc);
}
#if VBOX_API_VERSION < 3001
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 5ffc3c8..456b477 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -2190,7 +2190,8 @@ xenDaemonParseSxpr(virConnectPtr conn,
}
}
- def->vcpus = sexpr_int(root, "domain/vcpus");
+ def->maxvcpus = sexpr_int(root, "domain/vcpus");
+ def->vcpus = def->maxvcpus;
tmp = sexpr_node(root, "domain/on_poweroff");
if (tmp != NULL) {
@@ -5649,7 +5650,7 @@ xenDaemonFormatSxprInput(virDomainInputDefPtr input,
*
* Generate an SEXPR representing the domain configuration.
*
- * Returns the 0 terminatedi S-Expr string or NULL in case of error.
+ * Returns the 0 terminated S-Expr string or NULL in case of error.
* the caller must free() the returned value.
*/
char *
@@ -5666,7 +5667,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferAsprintf(&buf, "(name '%s')", def->name);
virBufferAsprintf(&buf, "(memory %lu)(maxmem %lu)",
def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
- virBufferAsprintf(&buf, "(vcpus %lu)", def->vcpus);
+ virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
if (def->cpumask) {
char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
@@ -5761,7 +5762,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
else
virBufferAsprintf(&buf, "(kernel '%s')", def->os.loader);
- virBufferAsprintf(&buf, "(vcpus %lu)", def->vcpus);
+ virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
for (i = 0 ; i < def->os.nBootDevs ; i++) {
switch (def->os.bootDevs[i]) {
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 8e42a1c..bf20a64 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -678,6 +678,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
int i;
const char *defaultArch, *defaultMachine;
int vmlocaltime = 0;
+ unsigned long count;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -770,9 +771,11 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
def->mem.cur_balloon *= 1024;
def->mem.max_balloon *= 1024;
-
- if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
+ if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
+ (unsigned short) count != count)
goto cleanup;
+ def->maxvcpus = count;
+ def->vcpus = def->maxvcpus;
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
goto cleanup;
@@ -1650,7 +1653,7 @@ int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
- entry->def->vcpus = vcpus;
+ entry->def->maxvcpus = entry->def->vcpus = vcpus;
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
@@ -2241,7 +2244,7 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
if (xenXMConfigSetInt(conf, "memory", def->mem.cur_balloon / 1024) < 0)
goto no_memory;
- if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
+ if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
goto no_memory;
if ((def->cpumask != NULL) &&
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 7d4ab8d..5ccdede 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -1335,7 +1335,7 @@ xenapiDomainDumpXML (virDomainPtr dom, int flags ATTRIBUTE_UNUSED)
} else {
defPtr->mem.cur_balloon = memory;
}
- defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
+ defPtr->maxvcpus = defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
enum xen_on_normal_exit action;
if (xen_vm_get_actions_after_shutdown(session, &action, vm)) {
defPtr->onPoweroff = xenapiNormalExitEnum2virDomainLifecycle(action);
diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c
index be55491..a7e2a4b 100644
--- a/src/xenapi/xenapi_utils.c
+++ b/src/xenapi/xenapi_utils.c
@@ -510,8 +510,8 @@ createVMRecordFromXml (virConnectPtr conn, virDomainDefPtr def,
else
(*record)->memory_dynamic_max = (*record)->memory_static_max;
- if (def->vcpus) {
- (*record)->vcpus_max = (int64_t) def->vcpus;
+ if (def->maxvcpus) {
+ (*record)->vcpus_max = (int64_t) def->maxvcpus;
(*record)->vcpus_at_startup = (int64_t) def->vcpus;
}
if (def->onPoweroff)
--
1.7.2.3

View File

@@ -0,0 +1,197 @@
From 6c9e6b956453d0f0c4ff542ef8a184d663a39266 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 4 Oct 2010 17:01:12 -0600
Subject: [PATCH 09/15] vcpu: support all flags in test driver
* src/test/test_driver.c (testDomainGetVcpusFlags)
(testDomainSetVcpusFlags): Support all flags.
(testDomainUpdateVCPUs): Update cpu count here.
---
src/test/test_driver.c | 128 ++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 109 insertions(+), 19 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index b70c80d..a9d3d89 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -450,6 +450,7 @@ testDomainUpdateVCPUs(virConnectPtr conn,
goto cleanup;
}
+ dom->def->vcpus = nvcpus;
ret = 0;
cleanup:
return ret;
@@ -2032,12 +2033,51 @@ cleanup:
static int
testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
- testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ testConnPtr privconn = domain->conn->privateData;
+ virDomainObjPtr vm;
+ virDomainDefPtr def;
+ int ret = -1;
+
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+ /* Exactly one of LIVE or CONFIG must be set. */
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
+ testError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
return -1;
}
- return testGetMaxVCPUs(domain->conn, "test");
+ testDriverLock(privconn);
+ vm = virDomainFindByUUID(&privconn->domains, domain->uuid);
+ testDriverUnlock(privconn);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(domain->uuid, uuidstr);
+ testError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
+ if (!virDomainObjIsActive(vm)) {
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain not active"));
+ goto cleanup;
+ }
+ def = vm->def;
+ } else {
+ def = vm->newDef ? vm->newDef : vm->def;
+ }
+
+ ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
}
static int
@@ -2053,21 +2093,30 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
{
testConnPtr privconn = domain->conn->privateData;
virDomainObjPtr privdom = NULL;
+ virDomainDefPtr def;
int ret = -1, maxvcpus;
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
- testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+ /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
+ * mixed with LIVE. */
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
+ (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
+ (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
+ testError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+ if (!nrCpus || (maxvcpus = testGetMaxVCPUs(domain->conn, NULL)) < nrCpus) {
+ testError(VIR_ERR_INVALID_ARG,
+ _("argument out of range: %d"), nrCpus);
return -1;
}
-
- /* Do this first before locking */
- maxvcpus = testDomainGetMaxVcpus(domain);
- if (maxvcpus < 0)
- goto cleanup;
testDriverLock(privconn);
- privdom = virDomainFindByName(&privconn->domains,
- domain->name);
+ privdom = virDomainFindByUUID(&privconn->domains, domain->uuid);
testDriverUnlock(privconn);
if (privdom == NULL) {
@@ -2075,13 +2124,17 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
goto cleanup;
}
- if (!virDomainObjIsActive(privdom)) {
+ if (!virDomainObjIsActive(privdom) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
testError(VIR_ERR_OPERATION_INVALID,
"%s", _("cannot hotplug vcpus for an inactive domain"));
goto cleanup;
}
- /* We allow more cpus in guest than host */
+ /* We allow more cpus in guest than host, but not more than the
+ * domain's starting limit. */
+ if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
+ VIR_DOMAIN_VCPU_LIVE && privdom->def->maxvcpus < maxvcpus)
+ maxvcpus = privdom->def->maxvcpus;
if (nrCpus > maxvcpus) {
testError(VIR_ERR_INVALID_ARG,
"requested cpu amount exceeds maximum (%d > %d)",
@@ -2089,12 +2142,49 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
goto cleanup;
}
- /* Update VCPU state for the running domain */
- if (testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0) < 0)
- goto cleanup;
+ switch (flags) {
+ case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
+ def = privdom->def;
+ if (virDomainObjIsActive(privdom)) {
+ if (privdom->newDef)
+ def = privdom->newDef;
+ else {
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("no persistent state"));
+ goto cleanup;
+ }
+ }
+ def->maxvcpus = nrCpus;
+ if (nrCpus < def->vcpus)
+ def->vcpus = nrCpus;
+ ret = 0;
+ break;
- privdom->def->vcpus = nrCpus;
- ret = 0;
+ case VIR_DOMAIN_VCPU_CONFIG:
+ def = privdom->def;
+ if (virDomainObjIsActive(privdom)) {
+ if (privdom->newDef)
+ def = privdom->newDef;
+ else {
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("no persistent state"));
+ goto cleanup;
+ }
+ }
+ def->vcpus = nrCpus;
+ ret = 0;
+ break;
+
+ case VIR_DOMAIN_VCPU_LIVE:
+ ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
+ break;
+
+ case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
+ ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
+ if (ret == 0 && privdom->newDef)
+ privdom->newDef->vcpus = nrCpus;
+ break;
+ }
cleanup:
if (privdom)
--
1.7.2.3

View File

@@ -0,0 +1,122 @@
From d67c189e80e6aef7adf13e5763365555cfc1a02a Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 29 Sep 2010 15:58:47 -0600
Subject: [PATCH 10/15] vcpu: improve vcpu support in qemu command line
* src/qemu/qemu_conf.c (qemuParseCommandLineSmp): Distinguish
between vcpus and maxvcpus, for new enough qemu.
* tests/qemuargv2xmltest.c (mymain): Add new test.
* tests/qemuxml2argvtest.c (mymain): Likewise.
* tests/qemuxml2xmltest.c (mymain): Likewise.
* tests/qemuxml2argvdata/qemuxml2argv-smp.args: New file.
---
src/qemu/qemu_conf.c | 13 +++++++++----
tests/qemuargv2xmltest.c | 2 ++
tests/qemuxml2argvdata/qemuxml2argv-smp.args | 1 +
tests/qemuxml2argvtest.c | 2 ++
tests/qemuxml2xmltest.c | 2 ++
5 files changed, 16 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.args
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 38c8351..ffe184b 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -3714,6 +3714,8 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
virBufferAsprintf(&buf, "%u", def->vcpus);
if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
+ if (def->vcpus != def->maxvcpus)
+ virBufferAsprintf(&buf, ",maxcpus=%u", def->maxvcpus);
/* sockets, cores, and threads are either all zero
* or all non-zero, thus checking one of them is enough */
if (def->cpu && def->cpu->sockets) {
@@ -3726,12 +3728,12 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
virBufferAsprintf(&buf, ",cores=%u", 1);
virBufferAsprintf(&buf, ",threads=%u", 1);
}
- }
- if (def->vcpus != def->maxvcpus) {
+ } else if (def->vcpus != def->maxvcpus) {
virBufferFreeAndReset(&buf);
+ /* FIXME - consider hot-unplugging cpus after boot for older qemu */
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("setting current vcpu count less than maximum is "
- "not supported yet"));
+ "not supported with this QEMU binary"));
return NULL;
}
@@ -6153,6 +6155,7 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
unsigned int sockets = 0;
unsigned int cores = 0;
unsigned int threads = 0;
+ unsigned int maxcpus = 0;
int i;
int nkws;
char **kws;
@@ -6180,12 +6183,14 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
cores = n;
else if (STREQ(kws[i], "threads"))
threads = n;
+ else if (STREQ(kws[i], "maxcpus"))
+ maxcpus = n;
else
goto syntax;
}
}
- dom->maxvcpus = dom->vcpus;
+ dom->maxvcpus = maxcpus ? maxcpus : dom->vcpus;
if (sockets && cores && threads) {
virCPUDefPtr cpu;
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 4f9ec84..d941b0b 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -221,6 +221,8 @@ mymain(int argc, char **argv)
DO_TEST("hostdev-pci-address");
+ DO_TEST("smp");
+
DO_TEST_FULL("restore-v1", 0, "stdio");
DO_TEST_FULL("restore-v2", 0, "stdio");
DO_TEST_FULL("restore-v2", 0, "exec:cat");
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.args b/tests/qemuxml2argvdata/qemuxml2argv-smp.args
new file mode 100644
index 0000000..3ec8f15
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1,maxcpus=2,sockets=2,cores=1,threads=1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 92d5b18..551d6c4 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -385,6 +385,8 @@ mymain(int argc, char **argv)
DO_TEST("qemu-ns", 0);
+ DO_TEST("smp", QEMUD_CMD_FLAG_SMP_TOPOLOGY);
+
free(driver.stateDir);
virCapabilitiesFree(driver.caps);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index a33d435..cdc4390 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -180,6 +180,8 @@ mymain(int argc, char **argv)
DO_TEST("encrypted-disk");
DO_TEST("memtune");
+ DO_TEST("smp");
+
/* These tests generate different XML */
DO_TEST_DIFFERENT("balloon-device-auto");
DO_TEST_DIFFERENT("channel-virtio-auto");
--
1.7.2.3

View File

@@ -0,0 +1,169 @@
From 28a3605906385cba43df77051dc26e865f237b09 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 29 Sep 2010 17:40:45 -0600
Subject: [PATCH 11/15] vcpu: complete vcpu support in qemu driver
* src/qemu/qemu_driver.c (qemudDomainSetVcpusFlags)
(qemudDomainGetVcpusFlags): Support all feasible flag
combinations.
---
src/qemu/qemu_driver.c | 100 ++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 85 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c66dc04..a9e057f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5941,13 +5941,27 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
+ virDomainDefPtr def;
const char * type;
int max;
int ret = -1;
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
- qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
- flags);
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+ /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
+ * mixed with LIVE. */
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
+ (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
+ (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+ if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("argument out of range: %d"), nvcpus);
return -1;
}
@@ -5966,7 +5980,7 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
if (qemuDomainObjBeginJob(vm) < 0)
goto cleanup;
- if (!virDomainObjIsActive(vm)) {
+ if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
@@ -5985,6 +5999,11 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
goto endjob;
}
+ if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
+ VIR_DOMAIN_VCPU_LIVE && vm->def->maxvcpus < max) {
+ max = vm->def->maxvcpus;
+ }
+
if (nvcpus > max) {
qemuReportError(VIR_ERR_INVALID_ARG,
_("requested vcpus is greater than max allowable"
@@ -5992,7 +6011,49 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
goto endjob;
}
- ret = qemudDomainHotplugVcpus(vm, nvcpus);
+ switch (flags) {
+ case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
+ def = vm->def;
+ if (virDomainObjIsActive(vm)) {
+ if (vm->newDef)
+ def = vm->newDef;
+ else{
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("no persistent state"));
+ goto endjob;
+ }
+ }
+ def->maxvcpus = nvcpus;
+ if (nvcpus < vm->newDef->vcpus)
+ def->vcpus = nvcpus;
+ ret = 0;
+ break;
+
+ case VIR_DOMAIN_VCPU_CONFIG:
+ def = vm->def;
+ if (virDomainObjIsActive(vm)) {
+ if (vm->newDef)
+ def = vm->newDef;
+ else {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("no persistent state"));
+ goto endjob;
+ }
+ }
+ def->vcpus = nvcpus;
+ ret = 0;
+ break;
+
+ case VIR_DOMAIN_VCPU_LIVE:
+ ret = qemudDomainHotplugVcpus(vm, nvcpus);
+ break;
+
+ case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
+ ret = qemudDomainHotplugVcpus(vm, nvcpus);
+ if (ret == 0 && vm->newDef)
+ vm->newDef->vcpus = nvcpus;
+ break;
+ }
endjob:
if (qemuDomainObjEndJob(vm) == 0)
@@ -6171,12 +6232,17 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
- const char *type;
+ virDomainDefPtr def;
int ret = -1;
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
- qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
- flags);
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+ /* Exactly one of LIVE or CONFIG must be set. */
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
return -1;
}
@@ -6192,14 +6258,18 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
goto cleanup;
}
- if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("unknown virt type in domain definition '%d'"),
- vm->def->virtType);
- goto cleanup;
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain not active"));
+ goto cleanup;
+ }
+ def = vm->def;
+ } else {
+ def = vm->newDef ? vm->newDef : vm->def;
}
- ret = qemudGetMaxVCPUs(NULL, type);
+ ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
cleanup:
if (vm)
--
1.7.2.3

View File

@@ -0,0 +1,294 @@
From 0fab10e5ed971ab4f960a53e9640b0672f4b8ac3 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Tue, 5 Oct 2010 08:18:52 -0600
Subject: [PATCH 12/15] vcpu: improve vcpu support in xen command line
This patch series focuses on xendConfigVersion 2 (xm_internal) and 3
(xend_internal), but leaves out changes for xenapi drivers.
See this link for more details about vcpu_avail for xm usage.
http://lists.xensource.com/archives/html/xen-devel/2009-11/msg01061.html
This relies on the fact that def->maxvcpus can be at most 32 with xen.
* src/xen/xend_internal.c (xenDaemonParseSxpr)
(sexpr_to_xend_domain_info, xenDaemonFormatSxpr): Use vcpu_avail
when current vcpus is less than maximum.
* src/xen/xm_internal.c (xenXMDomainConfigParse)
(xenXMDomainConfigFormat): Likewise.
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr: New file.
* tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr: Likewise.
* tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml: Likewise.
* tests/xmconfigdata/test-paravirt-vcpu.cfg: Likewise.
* tests/xmconfigdata/test-paravirt-vcpu.xml: Likewise.
* tests/xml2sexprtest.c (mymain): New test.
* tests/sexpr2xmltest.c (mymain): Likewise.
* tests/xmconfigtest.c (mymain): Likewise.
---
src/xen/xend_internal.c | 19 +++++++++++++--
src/xen/xm_internal.c | 10 ++++++-
tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr | 1 +
tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml | 27 +++++++++++++++++++++
tests/sexpr2xmltest.c | 1 +
tests/xmconfigdata/test-paravirt-vcpu.cfg | 17 +++++++++++++
tests/xmconfigdata/test-paravirt-vcpu.xml | 32 ++++++++++++++++++++++++++
tests/xmconfigtest.c | 1 +
tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr | 1 +
tests/xml2sexprtest.c | 1 +
10 files changed, 105 insertions(+), 5 deletions(-)
create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
create mode 100644 tests/xmconfigdata/test-paravirt-vcpu.cfg
create mode 100644 tests/xmconfigdata/test-paravirt-vcpu.xml
create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 456b477..dfc6415 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -44,6 +44,7 @@
#include "xen_hypervisor.h"
#include "xs_internal.h" /* To extract VNC port & Serial console TTY */
#include "memory.h"
+#include "count-one-bits.h"
/* required for cpumap_t */
#include <xen/dom0_ops.h>
@@ -2191,7 +2192,9 @@ xenDaemonParseSxpr(virConnectPtr conn,
}
def->maxvcpus = sexpr_int(root, "domain/vcpus");
- def->vcpus = def->maxvcpus;
+ def->vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
+ if (!def->vcpus || def->maxvcpus < def->vcpus)
+ def->vcpus = def->maxvcpus;
tmp = sexpr_node(root, "domain/on_poweroff");
if (tmp != NULL) {
@@ -2433,7 +2436,7 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
virDomainInfoPtr info)
{
const char *flags;
-
+ int vcpus;
if ((root == NULL) || (info == NULL))
return (-1);
@@ -2464,7 +2467,11 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
info->state = VIR_DOMAIN_NOSTATE;
}
info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000;
- info->nrVirtCpu = sexpr_int(root, "domain/vcpus");
+ vcpus = sexpr_int(root, "domain/vcpus");
+ info->nrVirtCpu = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
+ if (!info->nrVirtCpu || vcpus < info->nrVirtCpu)
+ info->nrVirtCpu = vcpus;
+
return (0);
}
@@ -5668,6 +5675,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferAsprintf(&buf, "(memory %lu)(maxmem %lu)",
def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
+ /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is 32. */
+ if (def->vcpus < def->maxvcpus)
+ virBufferAsprintf(&buf, "(vcpu_avail %u)", (1U << def->vcpus) - 1);
if (def->cpumask) {
char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
@@ -5763,6 +5773,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferAsprintf(&buf, "(kernel '%s')", def->os.loader);
virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
+ if (def->vcpus < def->maxvcpus)
+ virBufferAsprintf(&buf, "(vcpu_avail %u)",
+ (1U << def->vcpus) - 1);
for (i = 0 ; i < def->os.nBootDevs ; i++) {
switch (def->os.bootDevs[i]) {
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index bf20a64..f7121ab 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -46,6 +46,7 @@
#include "util.h"
#include "memory.h"
#include "logging.h"
+#include "count-one-bits.h"
#define VIR_FROM_THIS VIR_FROM_XENXM
@@ -772,10 +773,12 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
def->mem.max_balloon *= 1024;
if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
- (unsigned short) count != count)
+ MAX_VIRT_CPUS < count)
goto cleanup;
def->maxvcpus = count;
- def->vcpus = def->maxvcpus;
+ if (xenXMConfigGetULong(conf, "vcpu_avail", &count, -1) < 0)
+ goto cleanup;
+ def->vcpus = MIN(count_one_bits(count), def->maxvcpus);
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
goto cleanup;
@@ -2246,6 +2249,9 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
goto no_memory;
+ if (def->vcpus < def->maxvcpus &&
+ xenXMConfigSetInt(conf, "vcpu_avail", (1U << def->vcpus) - 1) < 0)
+ goto no_memory;
if ((def->cpumask != NULL) &&
((cpus = virDomainCpuSetFormat(def->cpumask,
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
new file mode 100644
index 0000000..2be6822
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
@@ -0,0 +1 @@
+(domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w'))))
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
new file mode 100644
index 0000000..0d6bf11
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
@@ -0,0 +1,27 @@
+<domain type='xen' id='6'>
+ <name>pvtest</name>
+ <uuid>596a5d21-71f4-8fb2-e068-e2386a5c413e</uuid>
+ <memory>430080</memory>
+ <currentMemory>430080</currentMemory>
+ <vcpu current='2'>4</vcpu>
+ <os>
+ <type>linux</type>
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file'/>
+ <source file='/root/some.img'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <console type='pty'>
+ <target type='xen' port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
index d62b44f..f100dd8 100644
--- a/tests/sexpr2xmltest.c
+++ b/tests/sexpr2xmltest.c
@@ -132,6 +132,7 @@ mymain(int argc, char **argv)
DO_TEST("pv-vfb-type-crash", "pv-vfb-type-crash", 3);
DO_TEST("fv-autoport", "fv-autoport", 3);
DO_TEST("pv-bootloader", "pv-bootloader", 1);
+ DO_TEST("pv-vcpus", "pv-vcpus", 1);
DO_TEST("disk-file", "disk-file", 2);
DO_TEST("disk-block", "disk-block", 2);
diff --git a/tests/xmconfigdata/test-paravirt-vcpu.cfg b/tests/xmconfigdata/test-paravirt-vcpu.cfg
new file mode 100644
index 0000000..24c78f4
--- /dev/null
+++ b/tests/xmconfigdata/test-paravirt-vcpu.cfg
@@ -0,0 +1,17 @@
+name = "XenGuest1"
+uuid = "c7a5fdb0-cdaf-9455-926a-d65c16db1809"
+maxmem = 579
+memory = 394
+vcpus = 4
+vcpu_avail = 3
+bootloader = "/usr/bin/pygrub"
+on_poweroff = "destroy"
+on_reboot = "restart"
+on_crash = "restart"
+sdl = 0
+vnc = 1
+vncunused = 1
+vnclisten = "127.0.0.1"
+vncpasswd = "123poi"
+disk = [ "phy:/dev/HostVG/XenGuest1,xvda,w" ]
+vif = [ "mac=00:16:3e:66:94:9c,bridge=br0,script=vif-bridge" ]
diff --git a/tests/xmconfigdata/test-paravirt-vcpu.xml b/tests/xmconfigdata/test-paravirt-vcpu.xml
new file mode 100644
index 0000000..0be9456
--- /dev/null
+++ b/tests/xmconfigdata/test-paravirt-vcpu.xml
@@ -0,0 +1,32 @@
+<domain type='xen'>
+ <name>XenGuest1</name>
+ <uuid>c7a5fdb0-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory>592896</memory>
+ <currentMemory>403456</currentMemory>
+ <vcpu current='2'>4</vcpu>
+ <bootloader>/usr/bin/pygrub</bootloader>
+ <os>
+ <type arch='i686' machine='xenpv'>linux</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <disk type='block' device='disk'>
+ <driver name='phy'/>
+ <source dev='/dev/HostVG/XenGuest1'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:66:94:9c'/>
+ <source bridge='br0'/>
+ <script path='vif-bridge'/>
+ </interface>
+ <console type='pty'>
+ <target type='xen' port='0'/>
+ </console>
+ <input type='mouse' bus='xen'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ </devices>
+</domain>
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
index 221b322..ea00747 100644
--- a/tests/xmconfigtest.c
+++ b/tests/xmconfigtest.c
@@ -210,6 +210,7 @@ mymain(int argc, char **argv)
DO_TEST("paravirt-new-pvfb-vncdisplay", 3);
DO_TEST("paravirt-net-e1000", 3);
DO_TEST("paravirt-net-vifname", 3);
+ DO_TEST("paravirt-vcpu", 2);
DO_TEST("fullvirt-old-cdrom", 1);
DO_TEST("fullvirt-new-cdrom", 2);
DO_TEST("fullvirt-utc", 2);
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
new file mode 100644
index 0000000..e886545
--- /dev/null
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
@@ -0,0 +1 @@
+(vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d21-71f4-8fb2-e068-e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w'))))
\ No newline at end of file
diff --git a/tests/xml2sexprtest.c b/tests/xml2sexprtest.c
index 77cf760..9cf8d39 100644
--- a/tests/xml2sexprtest.c
+++ b/tests/xml2sexprtest.c
@@ -118,6 +118,7 @@ mymain(int argc, char **argv)
DO_TEST("pv-vfb-new", "pv-vfb-new", "pvtest", 3);
DO_TEST("pv-vfb-new-auto", "pv-vfb-new-auto", "pvtest", 3);
DO_TEST("pv-bootloader", "pv-bootloader", "pvtest", 1);
+ DO_TEST("pv-vcpus", "pv-vcpus", "pvtest", 1);
DO_TEST("disk-file", "disk-file", "pvtest", 2);
DO_TEST("disk-block", "disk-block", "pvtest", 2);
--
1.7.2.3

View File

@@ -0,0 +1,216 @@
From 290ea33111be7bdf1f1381b90de33eb0e67c1a15 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 6 Oct 2010 17:54:41 -0600
Subject: [PATCH 13/15] vcpu: improve support for getting xen vcpu counts
* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Support
more flags.
* src/xen/xend_internal.h (xenDaemonDomainGetVcpusFlags): New
prototype.
* src/xen/xm_internal.h (xenXMDomainGetVcpusFlags): Likewise.
* src/xen/xend_internal.c (virDomainGetVcpusFlags): New function.
* src/xen/xm_internal.c (xenXMDomainGetVcpusFlags): Likewise.
---
src/xen/xen_driver.c | 31 +++++++++++++++++++--------
src/xen/xend_internal.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
src/xen/xend_internal.h | 2 +
src/xen/xm_internal.c | 47 ++++++++++++++++++++++++++++++++++++++++++
src/xen/xm_internal.h | 1 +
5 files changed, 124 insertions(+), 9 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index d6c9c57..fe2ff86 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1142,20 +1142,33 @@ static int
xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
{
GET_PRIVATE(dom->conn);
- int i, ret;
+ int ret;
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
- xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
- flags);
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+ /* Exactly one of LIVE or CONFIG must be set. */
+ if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
+ xenUnifiedError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
return -1;
}
- for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
- if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
- ret = drivers[i]->domainGetMaxVcpus (dom);
- if (ret != 0) return ret;
- }
+ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
+ ret = xenDaemonDomainGetVcpusFlags(dom, flags);
+ if (ret != -2)
+ return ret;
+ }
+ if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
+ ret = xenXMDomainGetVcpusFlags(dom, flags);
+ if (ret != -2)
+ return ret;
+ }
+ if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM))
+ return xenHypervisorGetVcpuMax(dom);
+ xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
return -1;
}
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index dfc6415..3642296 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -3620,6 +3620,58 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
}
/**
+ * xenDaemonDomainGetVcpusFlags:
+ * @domain: pointer to domain object
+ * @flags: bitwise-ORd from virDomainVcpuFlags
+ *
+ * Extract information about virtual CPUs of domain according to flags.
+ *
+ * Returns the number of vcpus on success, -1 if an error message was
+ * issued, and -2 if the unified driver should keep trying.
+
+ */
+int
+xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
+{
+ struct sexpr *root;
+ int ret;
+ xenUnifiedPrivatePtr priv;
+
+ if (domain == NULL || domain->conn == NULL || domain->name == NULL) {
+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+ /* If xendConfigVersion is 2, then we can only report _LIVE (and
+ * xm_internal reports _CONFIG). If it is 3, then _LIVE and
+ * _CONFIG are always in sync for a running system. */
+ if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
+ return -2;
+ if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) {
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain not active"));
+ return -1;
+ }
+
+ root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+ if (root == NULL)
+ return -1;
+
+ ret = sexpr_int(root, "domain/vcpus");
+ if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM)) {
+ int vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
+ if (vcpus)
+ ret = MIN(vcpus, ret);
+ }
+ if (!ret)
+ ret = -2;
+ sexpr_free(root);
+ return ret;
+}
+
+/**
* virDomainGetVcpus:
* @domain: pointer to domain object, or NULL for Domain0
* @info: pointer to an array of virVcpuInfo structures (OUT)
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
index c757716..923cebd 100644
--- a/src/xen/xend_internal.h
+++ b/src/xen/xend_internal.h
@@ -155,6 +155,8 @@ int xenDaemonDomainPinVcpu (virDomainPtr domain,
unsigned int vcpu,
unsigned char *cpumap,
int maplen);
+int xenDaemonDomainGetVcpusFlags (virDomainPtr domain,
+ unsigned int flags);
int xenDaemonDomainGetVcpus (virDomainPtr domain,
virVcpuInfoPtr info,
int maxinfo,
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index f7121ab..4ea4245 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -1671,6 +1671,53 @@ cleanup:
}
/**
+ * xenXMDomainGetVcpusFlags:
+ * @domain: pointer to domain object
+ * @flags: bitwise-ORd from virDomainVcpuFlags
+ *
+ * Extract information about virtual CPUs of domain according to flags.
+ *
+ * Returns the number of vcpus on success, -1 if an error message was
+ * issued, and -2 if the unified driver should keep trying.
+ */
+int
+xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
+{
+ xenUnifiedPrivatePtr priv;
+ const char *filename;
+ xenXMConfCachePtr entry;
+ int ret = -2;
+
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
+ xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+
+ if (domain->id != -1)
+ return -2;
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
+ xenXMError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
+ return -1;
+ }
+
+ priv = domain->conn->privateData;
+ xenUnifiedLock(priv);
+
+ if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
+ goto cleanup;
+
+ if (!(entry = virHashLookup(priv->configCache, filename)))
+ goto cleanup;
+
+ ret = ((flags & VIR_DOMAIN_VCPU_MAXIMUM) ? entry->def->maxvcpus
+ : entry->def->vcpus);
+
+cleanup:
+ xenUnifiedUnlock(priv);
+ return ret;
+}
+
+/**
* xenXMDomainPinVcpu:
* @domain: pointer to domain object
* @vcpu: virtual CPU number (reserved)
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
index 3ad3456..3295fbd 100644
--- a/src/xen/xm_internal.h
+++ b/src/xen/xm_internal.h
@@ -45,6 +45,7 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
+int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
unsigned char *cpumap, int maplen);
virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname);
--
1.7.2.3

View File

@@ -0,0 +1,342 @@
From e443a003129a172a7332f3cb6e40b3c39363ed5e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 14 Oct 2010 16:17:18 -0600
Subject: [PATCH 14/15] vcpu: improve support for setting xen vcpu counts
Tested with RHEL 5.6 (xendConfigVersion 2, where xend_internal
controls live domains and xm_internal controls inactive domains).
Hopefully this works with xendConfigVersion 3 (where xend_internal
controls everything).
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpusFlags): Support
more flags.
(xenUnifiedGetMaxVcpus): Export.
* src/xen/xm_internal.h (xenXMDomainSetVcpusFlags): New prototype.
* src/xen/xend_internal.h (xenDaemonDomainSetVcpusFlags): Likewise.
* src/xen/xen_driver.h (xenUnifiedGetMaxVcpus): Likewise.
* src/xen/xm_internal.c (xenXMDomainSetVcpusFlags): New function.
* src/xen/xend_internal.c (xenDaemonDomainSetVcpusFlags): Likewise.
---
src/xen/xen_driver.c | 60 ++++++++++++++++++++++++---------
src/xen/xen_driver.h | 1 +
src/xen/xend_internal.c | 76 +++++++++++++++++++++++++++++++++++++++++++
src/xen/xend_internal.h | 3 ++
src/xen/xm_internal.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
src/xen/xm_internal.h | 2 +
6 files changed, 208 insertions(+), 17 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index fe2ff86..66e8518 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -508,7 +508,7 @@ xenUnifiedIsSecure(virConnectPtr conn)
return ret;
}
-static int
+int
xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
{
GET_PRIVATE(conn);
@@ -1073,36 +1073,62 @@ xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
unsigned int flags)
{
GET_PRIVATE(dom->conn);
- int i;
+ int ret;
+
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
+ VIR_DOMAIN_VCPU_CONFIG |
+ VIR_DOMAIN_VCPU_MAXIMUM, -1);
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
- xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
- flags);
+ /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
+ * mixed with LIVE. */
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
+ (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
+ (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
+ xenUnifiedError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+ if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
+ xenUnifiedError(VIR_ERR_INVALID_ARG,
+ _("argument out of range: %d"), nvcpus);
return -1;
}
/* Try non-hypervisor methods first, then hypervisor direct method
* as a last resort.
*/
- for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
- if (i != XEN_UNIFIED_HYPERVISOR_OFFSET &&
- priv->opened[i] &&
- drivers[i]->domainSetVcpus &&
- drivers[i]->domainSetVcpus (dom, nvcpus) == 0)
- return 0;
-
- if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] &&
- drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus &&
- drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus (dom, nvcpus) == 0)
- return 0;
+ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
+ ret = xenDaemonDomainSetVcpusFlags(dom, nvcpus, flags);
+ if (ret != -2)
+ return ret;
+ }
+ if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
+ ret = xenXMDomainSetVcpusFlags(dom, nvcpus, flags);
+ if (ret != -2)
+ return ret;
+ }
+ if (flags == VIR_DOMAIN_VCPU_LIVE)
+ return xenHypervisorSetVcpus(dom, nvcpus);
+ xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
return -1;
}
static int
xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
{
- return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
+ unsigned int flags = VIR_DOMAIN_VCPU_LIVE;
+ xenUnifiedPrivatePtr priv;
+
+ /* Per the documented API, it is hypervisor-dependent whether this
+ * affects just _LIVE or _LIVE|_CONFIG; in xen's case, that
+ * depends on xendConfigVersion. */
+ if (dom) {
+ priv = dom->conn->privateData;
+ if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4)
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags);
}
static int
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
index 3e7c1d0..115a26a 100644
--- a/src/xen/xen_driver.h
+++ b/src/xen/xen_driver.h
@@ -220,6 +220,7 @@ int xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr info,
void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
virDomainEventPtr event);
unsigned long xenUnifiedVersion(void);
+int xenUnifiedGetMaxVcpus(virConnectPtr conn, const char *type);
# ifndef PROXY
void xenUnifiedLock(xenUnifiedPrivatePtr priv);
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 3642296..55c2cc4 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -3535,6 +3535,82 @@ xenDaemonLookupByID(virConnectPtr conn, int id) {
}
/**
+ * xenDaemonDomainSetVcpusFlags:
+ * @domain: pointer to domain object
+ * @nvcpus: the new number of virtual CPUs for this domain
+ * @flags: bitwise-ORd from virDomainVcpuFlags
+ *
+ * Change virtual CPUs allocation of domain according to flags.
+ *
+ * Returns 0 on success, -1 if an error message was issued, and -2 if
+ * the unified driver should keep trying.
+ */
+int
+xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
+ unsigned int flags)
+{
+ char buf[VIR_UUID_BUFLEN];
+ xenUnifiedPrivatePtr priv;
+ int max;
+
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
+ || (vcpus < 1)) {
+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (-1);
+ }
+
+ priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+ if ((domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) ||
+ (flags & VIR_DOMAIN_VCPU_MAXIMUM))
+ return -2;
+
+ /* With xendConfigVersion 2, only _LIVE is supported. With
+ * xendConfigVersion 3, only _LIVE|_CONFIG is supported for
+ * running domains, or _CONFIG for inactive domains. */
+ if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) {
+ if (flags & VIR_DOMAIN_VCPU_CONFIG) {
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Xend version does not support modifying "
+ "persistent config"));
+ return -1;
+ }
+ } else if (domain->id < 0) {
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain not running"));
+ return -1;
+ }
+ } else {
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) !=
+ (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) {
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Xend only supports modifying both live and "
+ "persistent config"));
+ }
+ }
+
+ /* Unfortunately, xend_op does not validate whether this exceeds
+ * the maximum. */
+ flags |= VIR_DOMAIN_VCPU_MAXIMUM;
+ if ((max = xenDaemonDomainGetVcpusFlags(domain, flags)) < 0) {
+ virXendError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("could not determin max vcpus for the domain"));
+ return -1;
+ }
+ if (vcpus > max) {
+ virXendError(VIR_ERR_INVALID_ARG,
+ _("requested vcpus is greater than max allowable"
+ " vcpus for the domain: %d > %d"), vcpus, max);
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", vcpus);
+ return xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
+ buf, NULL);
+}
+
+/**
* xenDaemonDomainSetVcpus:
* @domain: pointer to domain object
* @nvcpus: the new number of virtual CPUs for this domain
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
index 923cebd..53f5d2c 100644
--- a/src/xen/xend_internal.h
+++ b/src/xen/xend_internal.h
@@ -151,6 +151,9 @@ int xenDaemonDomainUndefine(virDomainPtr domain);
int xenDaemonDomainSetVcpus (virDomainPtr domain,
unsigned int vcpus);
+int xenDaemonDomainSetVcpusFlags (virDomainPtr domain,
+ unsigned int vcpus,
+ unsigned int flags);
int xenDaemonDomainPinVcpu (virDomainPtr domain,
unsigned int vcpu,
unsigned char *cpumap,
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 4ea4245..2b8e51e 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -1670,6 +1670,89 @@ cleanup:
return ret;
}
+/*
+ * xenXMDomainSetVcpusFlags:
+ * @domain: pointer to domain object
+ * @nvcpus: number of vcpus
+ * @flags: bitwise-ORd from virDomainVcpuFlags
+ *
+ * Change virtual CPUs allocation of domain according to flags.
+ *
+ * Returns 0 on success, -1 if an error message was issued, and -2 if
+ * the unified driver should keep trying.
+ */
+int
+xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
+ unsigned int flags)
+{
+ xenUnifiedPrivatePtr priv;
+ const char *filename;
+ xenXMConfCachePtr entry;
+ int ret = -1;
+ int max;
+
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
+ xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ xenXMError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ return -1;
+ }
+ if (domain->id != -1)
+ return -2;
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
+ xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is not running"));
+ return -1;
+ }
+
+ priv = domain->conn->privateData;
+ xenUnifiedLock(priv);
+
+ if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
+ goto cleanup;
+
+ if (!(entry = virHashLookup(priv->configCache, filename)))
+ goto cleanup;
+
+ /* Hypervisor maximum. */
+ if ((max = xenUnifiedGetMaxVcpus(domain->conn, NULL)) < 0) {
+ xenXMError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not determin max vcpus for the domain"));
+ goto cleanup;
+ }
+ /* Can't specify a current larger than stored maximum; but
+ * reducing maximum can silently reduce current. */
+ if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM))
+ max = entry->def->maxvcpus;
+ if (vcpus > max) {
+ xenXMError(VIR_ERR_INVALID_ARG,
+ _("requested vcpus is greater than max allowable"
+ " vcpus for the domain: %d > %d"), vcpus, max);
+ goto cleanup;
+ }
+
+ if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
+ entry->def->maxvcpus = vcpus;
+ if (entry->def->vcpus > vcpus)
+ entry->def->vcpus = vcpus;
+ } else {
+ entry->def->vcpus = vcpus;
+ }
+
+ /* If this fails, should we try to undo our changes to the
+ * in-memory representation of the config file. I say not!
+ */
+ if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ xenUnifiedUnlock(priv);
+ return ret;
+}
+
/**
* xenXMDomainGetVcpusFlags:
* @domain: pointer to domain object
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
index 3295fbd..a46e1a2 100644
--- a/src/xen/xm_internal.h
+++ b/src/xen/xm_internal.h
@@ -45,6 +45,8 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
+int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
+ unsigned int flags);
int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
unsigned char *cpumap, int maplen);
--
1.7.2.3

View File

@@ -0,0 +1,228 @@
From b013788742183afec9aa5068d3cfd185a3b5c62e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 7 Oct 2010 08:59:27 -0600
Subject: [PATCH 15/15] vcpu: remove dead xen code
* src/xen/xen_driver.h (xenUnifiedDriver): Remove now-unused
domainGetMaxVcpus, domainSetVcpus.
* src/xen/proxy_internal.c (xenProxyDriver): Likewise.
* src/xen/xen_hypervisor.c (xenHypervisorDriver): Likewise.
* src/xen/xen_inotify.c (xenInotifyDriver): Likewise.
* src/xen/xend_internal.c (xenDaemonDriver)
(xenDaemonDomainSetVcpus): Likewise.
* src/xen/xm_internal.c (xenXMDriver, xenXMDomainSetVcpus):
Likewise.
* src/xen/xs_internal.c (xenStoreDriver): Likewise.
---
src/xen/proxy_internal.c | 2 --
src/xen/xen_driver.h | 4 +---
src/xen/xen_hypervisor.c | 2 --
src/xen/xen_inotify.c | 2 --
src/xen/xend_internal.c | 33 ---------------------------------
src/xen/xm_internal.c | 43 -------------------------------------------
src/xen/xs_internal.c | 2 --
7 files changed, 1 insertions(+), 87 deletions(-)
diff --git a/src/xen/proxy_internal.c b/src/xen/proxy_internal.c
index 335dfc4..4033727 100644
--- a/src/xen/proxy_internal.c
+++ b/src/xen/proxy_internal.c
@@ -67,10 +67,8 @@ struct xenUnifiedDriver xenProxyDriver = {
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
- NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
- NULL, /* domainGetMaxVcpus */
NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
index 115a26a..53f97d4 100644
--- a/src/xen/xen_driver.h
+++ b/src/xen/xen_driver.h
@@ -1,7 +1,7 @@
/*
* xen_unified.c: Unified Xen driver.
*
- * Copyright (C) 2007 Red Hat, Inc.
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
*
* See COPYING.LIB for the License of this software
*
@@ -84,10 +84,8 @@ struct xenUnifiedDriver {
virDrvDomainSave domainSave;
virDrvDomainRestore domainRestore;
virDrvDomainCoreDump domainCoreDump;
- virDrvDomainSetVcpus domainSetVcpus;
virDrvDomainPinVcpu domainPinVcpu;
virDrvDomainGetVcpus domainGetVcpus;
- virDrvDomainGetMaxVcpus domainGetMaxVcpus;
virDrvListDefinedDomains listDefinedDomains;
virDrvNumOfDefinedDomains numOfDefinedDomains;
virDrvDomainCreate domainCreate;
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index 6246513..3797865 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -784,10 +784,8 @@ struct xenUnifiedDriver xenHypervisorDriver = {
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
- xenHypervisorSetVcpus, /* domainSetVcpus */
xenHypervisorPinVcpu, /* domainPinVcpu */
xenHypervisorGetVcpus, /* domainGetVcpus */
- xenHypervisorGetVcpuMax, /* domainGetMaxVcpus */
NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
index d24b20f..9507061 100644
--- a/src/xen/xen_inotify.c
+++ b/src/xen/xen_inotify.c
@@ -71,10 +71,8 @@ struct xenUnifiedDriver xenInotifyDriver = {
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
- NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
- NULL, /* domainGetMaxVcpus */
NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 55c2cc4..b90c331 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -3611,37 +3611,6 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
}
/**
- * xenDaemonDomainSetVcpus:
- * @domain: pointer to domain object
- * @nvcpus: the new number of virtual CPUs for this domain
- *
- * Dynamically change the number of virtual CPUs used by the domain.
- *
- * Returns 0 for success; -1 (with errno) on error
- */
-int
-xenDaemonDomainSetVcpus(virDomainPtr domain, unsigned int vcpus)
-{
- char buf[VIR_UUID_BUFLEN];
- xenUnifiedPrivatePtr priv;
-
- if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
- || (vcpus < 1)) {
- virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
-
- priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
-
- if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
- return(-1);
-
- snprintf(buf, sizeof(buf), "%d", vcpus);
- return(xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
- buf, NULL));
-}
-
-/**
* xenDaemonDomainPinCpu:
* @domain: pointer to domain object
* @vcpu: virtual CPU number
@@ -5213,10 +5182,8 @@ struct xenUnifiedDriver xenDaemonDriver = {
xenDaemonDomainSave, /* domainSave */
xenDaemonDomainRestore, /* domainRestore */
xenDaemonDomainCoreDump, /* domainCoreDump */
- xenDaemonDomainSetVcpus, /* domainSetVcpus */
xenDaemonDomainPinVcpu, /* domainPinVcpu */
xenDaemonDomainGetVcpus, /* domainGetVcpus */
- NULL, /* domainGetMaxVcpus */
xenDaemonListDefinedDomains, /* listDefinedDomains */
xenDaemonNumOfDefinedDomains,/* numOfDefinedDomains */
xenDaemonDomainCreate, /* domainCreate */
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 2b8e51e..430d40b 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -103,10 +103,8 @@ struct xenUnifiedDriver xenXMDriver = {
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
- xenXMDomainSetVcpus, /* domainSetVcpus */
xenXMDomainPinVcpu, /* domainPinVcpu */
NULL, /* domainGetVcpus */
- NULL, /* domainGetMaxVcpus */
xenXMListDefinedDomains, /* listDefinedDomains */
xenXMNumOfDefinedDomains, /* numOfDefinedDomains */
xenXMDomainCreate, /* domainCreate */
@@ -1630,47 +1628,6 @@ cleanup:
}
/*
- * Set the VCPU count in config
- */
-int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
- xenUnifiedPrivatePtr priv;
- const char *filename;
- xenXMConfCachePtr entry;
- int ret = -1;
-
- if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
- xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- return (-1);
- }
- if (domain->conn->flags & VIR_CONNECT_RO)
- return (-1);
- if (domain->id != -1)
- return (-1);
-
- priv = domain->conn->privateData;
- xenUnifiedLock(priv);
-
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
- goto cleanup;
-
- if (!(entry = virHashLookup(priv->configCache, filename)))
- goto cleanup;
-
- entry->def->maxvcpus = entry->def->vcpus = vcpus;
-
- /* If this fails, should we try to undo our changes to the
- * in-memory representation of the config file. I say not!
- */
- if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
- goto cleanup;
- ret = 0;
-
-cleanup:
- xenUnifiedUnlock(priv);
- return ret;
-}
-
-/*
* xenXMDomainSetVcpusFlags:
* @domain: pointer to domain object
* @nvcpus: number of vcpus
diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c
index 9296f25..a9817b1 100644
--- a/src/xen/xs_internal.c
+++ b/src/xen/xs_internal.c
@@ -67,10 +67,8 @@ struct xenUnifiedDriver xenStoreDriver = {
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
- NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
- NULL, /* domainGetMaxVcpus */
NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */
--
1.7.2.3

View File

@@ -1003,8 +1003,6 @@ class CParser:
# skip hidden macros
if name in hidden_macros:
return token
if name[-2:] == "_H" or name[-8:] == "_H_ALLOW":
return token
strValue = None
if len(lst) == 1 and lst[0][0] == '"' and lst[0][-1] == '"':
@@ -2117,22 +2115,12 @@ class docBuilder:
self.modulename_file(id.header)))
if id.info is not None:
info = id.info
valhex = ""
if info[0] is not None and info[0] != '':
try:
val = eval(info[0])
valhex = hex(val)
except:
val = info[0]
output.write(" value='%s'" % (val))
if valhex != "":
output.write(" value_hex='%s'" % (valhex))
m = re.match("\(?1<<(\d+)\)?", info[0])
if m:
output.write(" value_bitshift='%s'" % (m.group(1)))
if info[2] is not None and info[2] != '':
output.write(" type='%s'" % info[2])
if info[1] is not None and info[1] != '':
@@ -2282,7 +2270,7 @@ class docBuilder:
output.write(" <file name='%s'>\n" % (module))
dict = self.headers[file]
if dict.info is not None:
for data in ('Summary', 'Description'):
for data in ('Summary', 'Description', 'Author'):
try:
output.write(" <%s>%s</%s>\n" % (
data.lower(),

View File

@@ -184,29 +184,15 @@ Default policy will still allow any application to connect to the RO socket.
</p>
<p>
The default policy can be overridden by creating a new policy file in the
<code>/etc/polkit-1/rules.d</code> directory. Information on the options
available can be found by reading the <code>polkit(8)</code> man page. The
two libvirt actions are named <code>org.libvirt.unix.manage</code> for full
management access, and <code>org.libvirt.unix.monitor</code> for read-only
access.
</p>
<p>
As an example, creating <code>/etc/polkit-1/rules.d/80-libvirt-manage.rules</code>
with the following gives the user <code>fred</code> full management access
when accessing from an active local session:
</p>
<pre>polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.unix.manage" &amp;&amp;
subject.local &amp;&amp; subject.active &amp;&amp; subject.user == "fred") {
return polkit.Result.YES;
}
});</pre>
<p>
Older versions of PolicyKit used policy files ending with .pkla in the
local override directory <code>/etc/polkit-1/localauthority/50-local.d/</code>.
Compatibility with this older format is provided by <a
href="https://pagure.io/polkit-pkla-compat">polkit-pkla-compat</a>. As an
example, this gives the user <code>fred</code> full management access:
Policy files should have a unique name ending with .pkla. Using reverse DNS
naming works well. Information on the options available can be found by
reading the pklocalauthority man page. The two libvirt daemon actions
available are named <code>org.libvirt.unix.manage</code> for full management
access, and <code>org.libvirt.unix.monitor</code> for read-only access.
</p>
<p>
As an example, this gives the user <code>fred</code> full management access:
</p>
<pre>[Allow fred libvirt management permissions]
Identity=unix-user:fred
@@ -214,6 +200,10 @@ Action=org.libvirt.unix.manage
ResultAny=yes
ResultInactive=yes
ResultActive=yes</pre>
<p>
Further examples of PolicyKit setup can be found on the
<a href="http://wiki.libvirt.org/page/SSHPolicyKitSetup">wiki page</a>.
</p>
<h2><a id="ACL_server_sasl">SASL pluggable authentication</a></h2>
<p>

View File

@@ -23,13 +23,12 @@
<p>
The QEMU driver is capable of using the <code>cpuset</code>,
<code>cpu</code>, <code>cpuacct</code>, <code>memory</code>,
<code>blkio</code> and <code>devices</code> controllers.
None of them are compulsory. If any controller is not mounted,
the resource management APIs which use it will cease to operate.
It is possible to explicitly turn off use of a controller,
even when mounted, via the <code>/etc/libvirt/qemu.conf</code>
configuration file.
<code>cpu</code>, <code>memory</code>, <code>blkio</code> and
<code>devices</code> controllers. None of them are compulsory.
If any controller is not mounted, the resource management APIs
which use it will cease to operate. It is possible to explicitly
turn off use of a controller, even when mounted, via the
<code>/etc/libvirt/qemu.conf</code> configuration file.
</p>
<p>
@@ -76,13 +75,11 @@
<p>
The systemd convention is for the scope name of virtual machines / containers
to be of the general format <code>machine-$NAME.scope</code>. Libvirt forms the
<code>$NAME</code> part of this by concatenating the driver type with the id
and truncated name of the guest, and then escaping any systemd reserved
characters.
<code>$NAME</code> part of this by concatenating the driver type with the name
of the guest, and then escaping any systemd reserved characters.
So for a guest <code>demo</code> running under the <code>lxc</code> driver,
we get a <code>$NAME</code> of <code>lxc-12345-demo</code> which when escaped
is <code>lxc\x2d12345\x2ddemo</code>. So the complete scope name is
<code>machine-lxc\x2d12345\x2ddemo.scope</code>.
we get a <code>$NAME</code> of <code>lxc-demo</code> which when escaped is
<code>lxc\x2ddemo</code>. So the complete scope name is <code>machine-lxc\x2ddemo.scope</code>.
The scope names map directly to the cgroup directory names.
</p>
@@ -115,19 +112,19 @@ $ROOT
|
+- machine.slice
|
+- machine-qemu\x2d1\x2dvm1.scope
+- machine-qemu\x2dvm1.scope
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- machine-qemu\x2d2\x2dvm2.scope
+- machine-qemu\x2dvm2.scope
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- machine-qemu\x2d3\x2dvm3.scope
+- machine-qemu\x2dvm3.scope
| |
| +- emulator
| +- vcpu0
@@ -137,15 +134,15 @@ $ROOT
| |
| +- machine-engineering-testing.slice
| | |
| | +- machine-lxc\x2d11111\x2dcontainer1.scope
| | +- machine-lxc\x2dcontainer1.scope
| |
| +- machine-engineering-production.slice
| |
| +- machine-lxc\x2d22222\x2dcontainer2.scope
| +- machine-lxc\x2dcontainer2.scope
|
+- machine-marketing.slice
|
+- machine-lxc\x2d33333\x2dcontainer3.scope
+- machine-lxc\x2dcontainer3.scope
</pre>
<h3><a id="currentLayoutGeneric">Non-systemd cgroups layout</a></h3>
@@ -176,19 +173,19 @@ $ROOT
|
+- machine
|
+- qemu-1-vm1.libvirt-qemu
+- vm1.libvirt-qemu
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- qeme-2-vm2.libvirt-qemu
+- vm2.libvirt-qemu
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- qemu-3-vm3.libvirt-qemu
+- vm3.libvirt-qemu
| |
| +- emulator
| +- vcpu0
@@ -198,15 +195,15 @@ $ROOT
| |
| +- testing.partition
| | |
| | +- lxc-11111-container1.libvirt-lxc
| | +- container1.libvirt-lxc
| |
| +- production.partition
| |
| +- lxc-22222-container2.libvirt-lxc
| +- container2.libvirt-lxc
|
+- marketing.partition
|
+- lxc-33333-container3.libvirt-lxc
+- container3.libvirt-lxc
</pre>
<h2><a id="customPartiton">Using custom partitions</a></h2>

View File

@@ -125,7 +125,7 @@ $ make
<pre>
$ su -
# service libvirtd stop (or systemctl stop libvirtd.service)
# /home/to/your/checkout/src/libvirtd
# /home/to/your/checkout/daemon/libvirtd
</pre>
<p>

View File

@@ -72,6 +72,7 @@
<xsl:if test="deprecated">
<p> WARNING: this module is deprecated !</p>
</xsl:if>
<p>Author(s): <xsl:value-of select="author"/></p>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
<pre class="synopsis">

View File

@@ -77,7 +77,6 @@
<a href="formatstorageencryption.html">storage encryption</a>,
<a href="formatcaps.html">capabilities</a>,
<a href="formatdomaincaps.html">domain capabilities</a>,
<a href="formatstoragecaps.html">storage pool capabilities</a>,
<a href="formatnode.html">node devices</a>,
<a href="formatsecret.html">secrets</a>,
<a href="formatsnapshot.html">snapshots</a></dd>

View File

@@ -29,6 +29,7 @@
<li><strong><a href="drvopenvz.html">OpenVZ</a></strong></li>
<li><strong><a href="drvqemu.html">QEMU</a></strong></li>
<li><strong><a href="drvtest.html">Test</a></strong> - Used for testing</li>
<li><strong><a href="drvuml.html">UML</a></strong> - User Mode Linux</li>
<li><strong><a href="drvvbox.html">VirtualBox</a></strong></li>
<li><strong><a href="drvesx.html">VMware ESX</a></strong></li>
<li><strong><a href="drvvmware.html">VMware Workstation/Player</a></strong></li>

View File

@@ -462,32 +462,5 @@ Example:</p>
&lt;/domain&gt;
</pre>
<h3><a id="bhyvecommand">Pass-through of arbitrary bhyve commands</a></h3>
<p><span class="since">Since 5.1.0</span>, it's possible to pass additional command-line
arguments to the bhyve process when starting the domain using the
<code>&lt;bhyve:commandline&gt;</code> element under <code>domain</code>.
To supply an argument, use the element <code>&lt;bhyve:arg&gt;</code> with
the attribute <code>value</code> set to additional argument to be added.
The arg element may be repeated multiple times. To use this XML addition, it is necessary
to issue an XML namespace request (the special <code>xmlns:<i>name</i></code> attribute)
that pulls in <code>http://libvirt.org/schemas/domain/bhyve/1.0</code>;
typically, the namespace is given the name of <code>bhyve</code>.
</p>
<p>Example:</p>
<pre>
&lt;domain type="bhyve" xmlns:bhyve="http://libvirt.org/schemas/domain/bhyve/1.0"&gt;
...
&lt;bhyve:commandline&gt;
&lt;bhyve:arg value='-somebhyvearg'/&gt;
&lt;/bhyve:commandline&gt;
&lt;/domain&gt;
</pre>
<p>Note that these extensions are for testing and development purposes only.
They are <b>unsupported</b>, using them may result in inconsistent state,
and upgrading either bhyve or libvirtd maybe break behavior of a domain that
was relying on a specific commands pass-through.</p>
</body>
</html>

View File

@@ -8,7 +8,7 @@
<p>
The libvirt KVM/QEMU driver can manage any QEMU emulator from
version 1.5.0 or later.
version 0.12.0 or later.
</p>
<h2><a id="project">Project Links</a></h2>
@@ -395,8 +395,9 @@ chmod o+x /path/to/directory
<pre>
/dev/null, /dev/full, /dev/zero,
/dev/random, /dev/urandom,
/dev/ptmx, /dev/kvm,
/dev/rtc, /dev/hpet
/dev/ptmx, /dev/kvm, /dev/kqemu,
/dev/rtc, /dev/hpet, /dev/net/tun,
/dev/sev
</pre>
<p>

93
docs/drvuml.html.in Normal file
View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>User Mode Linux driver</h1>
<p>
The UML driver for libvirt allows use and management of paravirtualized
guests built for User Mode Linux. UML requires no special support in
the host kernel, so can be used by any user of any linux system, provided
they have enough free RAM for their guest's needs, though there are
certain restrictions on network connectivity unless the administrator
has pre-created TAP devices.
</p>
<h2><a id="project">Project Links</a></h2>
<ul>
<li>
The <a href="http://user-mode-linux.sourceforge.net/">User
Mode Linux</a> paravirtualized kernel
</li>
</ul>
<h2>Connections to UML driver</h2>
<p>
The libvirt UML driver follows the QEMU driver in providing two
types of connection. There is one privileged instance per host,
which runs as root. This is called the "system" instance, and allows
full use of all host resources. Then, there is a per-user unprivileged
"session", instance. This has more restricted capabilities, and may
require the host administrator to setup certain resources ahead of
time to allow full integration with the network. Example connection
URIs are
</p>
<pre>
uml:///session (local access to per-user instance)
uml+unix:///session (local access to per-user instance)
uml:///system (local access to system instance)
uml+unix:///system (local access to system instance)
uml://example.com/system (remote access, TLS/x509)
uml+tcp://example.com/system (remote access, SASl/Kerberos)
uml+ssh://root@example.com/system (remote access, SSH tunnelled)
</pre>
<h2>Example XML configuration</h2>
<p>
User mode Linux driver only supports directly kernel boot at
this time. A future driver enhancement may allow a paravirt
bootloader in a similar style to Xen's pygrub. For now though,
the UML kernel must be stored on the host and referenced
explicitly in the "os" element. Since UML is a paravirtualized
technology, the kernel "type" is set to "uml"
</p>
<p>
There is not yet support for networking in the driver, but
disks can be specified in the usual libvirt manner. The main
variation is the target device naming scheme "ubd0", and
bus type of "uml".
</p>
<p>
Once booted the primary console is connected to a PTY, and
thus accessible with "virsh console" or equivalent tools
</p>
<pre>
&lt;domain type='uml'&gt;
&lt;name&gt;demo&lt;/name&gt;
&lt;uuid&gt;b4433fc2-a22e-ffb3-0a3d-9c173b395800&lt;/uuid&gt;
&lt;memory&gt;500000&lt;/memory&gt;
&lt;currentMemory&gt;500000&lt;/currentMemory&gt;
&lt;vcpu&gt;1&lt;/vcpu&gt;
&lt;os&gt;
&lt;type arch='x86_64'&gt;uml&lt;/type&gt;
&lt;kernel&gt;/home/berrange/linux-uml-2.6.26-x86_64&lt;/kernel&gt;
&lt;/os&gt;
&lt;devices&gt;
&lt;disk type='file' device='disk'&gt;
&lt;source file='/home/berrange/FedoraCore6-AMD64-root_fs'/&gt;
&lt;target dev='ubd0' bus='uml'/&gt;
&lt;/disk&gt;
&lt;console type='pty'/&gt;
&lt;/devices&gt;
&lt;/domain&gt;
</pre>
</body>
</html>

View File

@@ -8,7 +8,7 @@
<p>
The libvirt libxl driver provides the ability to manage virtual
machines on any Xen release from 4.6.0 onwards.
machines on any Xen release from 4.4.0 onwards.
</p>
<h2><a id="project">Project Links</a></h2>

View File

@@ -129,44 +129,6 @@ MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24</pre>
</li>
</ul>
<h3><a id="fw-firewalld-and-virtual-network-driver">firewalld and the virtual network driver</a>
</h3>
<p>
If <a href="https://firewalld.org">firewalld</a> is active on
the host, libvirt will attempt to place the bridge interface of
a libvirt virtual network into the firewalld zone named
"libvirt" (thus making all guest->host traffic on that network
subject to the rules of the "libvirt" zone). This is done
because, if firewalld is using its nftables backend (available
since firewalld 0.6.0) the default firewalld zone (which would
be used if libvirt didn't explicitly set the zone) prevents
forwarding traffic from guests through the bridge, as well as
preventing DHCP, DNS, and most other traffic from guests to
host. The zone named "libvirt" is installed into the firewalld
configuration by libvirt (not by firewalld), and allows
forwarded traffic through the bridge as well as DHCP, DNS, TFTP,
and SSH traffic to the host - depending on firewalld's backend
this will be implemented via either iptables or nftables
rules. libvirt's own rules outlined above will *always* be
iptables rules regardless of which backend is in use by
firewalld.
</p>
<p>
NB: It is possible to manually set the firewalld zone for a
network's interface with the "zone" attribute of the network's
"bridge" element.
</p>
<p>
NB: Prior to libvirt 5.1.0, the firewalld "libvirt" zone did not
exist, and prior to firewalld 0.7.0 a feature crucial to making
the "libvirt" zone operate properly (rich rule priority
settings) was not implemented in firewalld. In cases where one
or the other of the two packages is missing the necessary
functionality, it's still possible to have functional guest
networking by setting the firewalld backend to "iptables" (in
firewalld prior to 0.6.0, this was the only backend available).
</p>
<h3><a id="fw-network-filter-driver">The network filter driver</a>
</h3>
<p>This driver provides a fully configurable network filtering capability

View File

@@ -21,7 +21,6 @@
<li><a href="formatstorageencryption.html">Storage encryption</a></li>
<li><a href="formatcaps.html">Capabilities</a></li>
<li><a href="formatdomaincaps.html">Domain capabilities</a></li>
<li><a href="formatstoragecaps.html">Storage Pool capabilities</a></li>
<li><a href="formatnode.html">Node devices</a></li>
<li><a href="formatsecret.html">Secrets</a></li>
<li><a href="formatsnapshot.html">Snapshots</a></li>

View File

@@ -74,44 +74,24 @@
is able to run. Possible values are:
<dl>
<dt><code>xen</code></dt>
<dd>for XEN PV</dd>
<dd>for XEN</dd>
<dt><code>linux</code></dt>
<dd>legacy alias for <code>xen</code></dd>
<dt><code>xenpvh</code></dt>
<dd>for XEN PVH</dd>
<dt><code>hvm</code></dt>
<dd>Unmodified operating system</dd>
<dt><code>exe</code></dt>
<dd>Container based virtualization</dd>
<dt><code>uml</code></dt>
<dd>User Mode Linux</dd>
</dl>
</dd>
<dt><code>arch</code></dt>
<dd>This element brings some information on supported guest
architecture. Possible subelements are:
<dl>
<dt><code>wordsize</code></dt><dd>Size of CPU word in bits, for example 64.</dd>
<dt><code>emulator</code></dt><dd>Emulator (device model) path, for
use in <a href="formatdomain.html#elementEmulator">emulator</a>
element of domain XML.</dd>
<dt><code>loader</code></dt><dd>Loader path, for use in
<a href="formatdomain.html#elementLoader">loader</a> element of domain
XML.</dd>
<dt><code>machine</code></dt><dd>Machine type, for use in
<a href="formatdomain.html#attributeOSTypeMachine">machine</a>
attribute of os/type element in domain XML. For example Xen
supports <code>xenfv</code> for HVM, <code>xenpv</code> for
PV, or <code>xenpvh</code> for PVH.</dd>
<dt><code>domain</code></dt><dd>The <code>type</code> attribute of
this element specifies the type of hypervisor required to run the
domain. Use in <a href="formatdomain.html#attributeDomainType">type</a>
attribute of the domain root element.</dd>
</dl>
</dd>
<dd>This element brings some information on supported guest architecture.</dd>
<dt><code>features</code></dt>
<dd>This optional element encases possible features that can be used

File diff suppressed because it is too large Load Diff

View File

@@ -37,17 +37,6 @@
management application to choose an appropriate mode for a pass-through
host device as well as which adapter to utilize.</p>
<p>Some XML elements may be entirely omitted from the domaincapabilities
XML, depending on what the libvirt driver has filled in. Applications
should only act on what is explicitly reported in the domaincapabilities
XML. For example, if &lt;disk supported='yes'/&gt; is present, you can safely
assume the driver supports &lt;disk&gt; devices. If &lt;disk supported='no'/&gt; is
present, you can safely assume the driver does NOT support &lt;disk&gt;
devices. If the &lt;disk&gt; block is omitted entirely, the driver is not
indicating one way or the other whether it supports &lt;disk&gt; devices, and
applications should not interpret the missing block to mean any thing in
particular.</p>
<h2><a id="elements">Element and attribute overview</a></h2>
<p> A new query interface was added to the virConnect API's to retrieve the
@@ -289,6 +278,7 @@
&lt;value&gt;virtio&lt;/value&gt;
&lt;value&gt;xen&lt;/value&gt;
&lt;value&gt;usb&lt;/value&gt;
&lt;value&gt;uml&lt;/value&gt;
&lt;value&gt;sata&lt;/value&gt;
&lt;value&gt;sd&lt;/value&gt;
&lt;/enum&gt;
@@ -492,7 +482,7 @@
<p>
For more details on SEV feature see:
<a href="https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf">
<a href="https://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf">
SEV API spec</a> and <a href="http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf">
SEV White Paper</a>
</p>

View File

@@ -107,13 +107,13 @@
may also be connected to the LAN. When defining
a new network with a <code>&lt;forward&gt;</code> mode of
"nat", "route", or "open" (or an isolated network with
"nat" or "route" (or an isolated network with
no <code>&lt;forward&gt;</code> element), libvirt will
automatically generate a unique name for the bridge device if
none is given, and this name will be permanently stored in the
network configuration so that that the same name will be used
every time the network is started. For these types of networks
(nat, route, open, and isolated), a bridge name beginning with the
(nat, routed, and isolated), a bridge name beginning with the
prefix "virbr" is recommended (and that is what is
auto-generated), but not enforced.
Attribute <code>stp</code> specifies if Spanning Tree Protocol
@@ -152,23 +152,6 @@
<span class="since">Since 1.2.11, requires kernel 3.17 or
newer</span>
</p>
<p>
The optional <code>zone</code> attribute of
the <code>bridge</code> element is used to specify
the <a href="https://firewalld.org">firewalld</a>
zone for the bridge of a network with <code>forward</code>
mode of "nat", "route", "open", or one with
no <code>forward</code> specified. By default, the bridges
of all virtual networks with these forward modes are placed
in the firewalld zone named "libvirt", which permits
incoming DNS, DHCP, TFTP, and SSH to the host from guests on
the network. This behavior can be changed either by
modifying the libvirt zone (using firewalld management
tools), or by placing the network in a different zone (which
will also be managed using firewalld tools).
<span class="since">Since 5.1.0</span>
</p>
</dd>
<dt><code>mtu</code></dt>

View File

@@ -70,10 +70,6 @@
<dd>Describes a device on the host's PCI bus. Sub-elements
include:
<dl>
<dt><code>class</code></dt>
<dd>Optional element for combined class, subclass and
programming interface codes as 6-digit hexadecimal number.
<span class="since">Since 5.2.0</span></dd>
<dt><code>domain</code></dt>
<dd>Which domain the device belongs to.</dd>
<dt><code>bus</code></dt>
@@ -385,7 +381,6 @@
&lt;name&gt;igb&lt;/name&gt;
&lt;/driver&gt;
&lt;capability type='pci'&gt;
&lt;class&gt;0x020000&lt;/class&gt;
&lt;domain&gt;0&lt;/domain&gt;
&lt;bus&gt;2&lt;/bus&gt;
&lt;slot&gt;0&lt;/slot&gt;

View File

@@ -2265,7 +2265,7 @@ echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
to the incoming and outgoing direction. All this is related to the ftp
data traffic originating from TCP port 20 of the VM. This then leads to
the following solution
<span class="since">(since 0.8.5 (QEMU, KVM))</span>:
<span class="since">(since 0.8.5 (QEMU, KVM, UML))</span>:
</p>
<pre>
&lt;filter name='test-eth0'&gt;

View File

@@ -33,7 +33,7 @@
resume in a consistent state; but if the disks are modified
externally in the meantime, this is likely to lead to data
corruption.</dd>
<dt>full system</dt>
<dt>system checkpoint</dt>
<dd>A combination of disk snapshots for all disks as well as VM
memory state, which can be used to resume the guest from where it
left off with symptoms similar to hibernation (that is, TCP
@@ -55,12 +55,11 @@
as <code>virDomainSaveImageGetXMLDesc()</code> to work with
those files.
</p>
<p>Full system snapshots are created
by <code>virDomainSnapshotCreateXML()</code> with no flags, while
<p>System checkpoints are created
by <code>virDomainSnapshotCreateXML()</code> with no flags, and
disk snapshots are created by the same function with
the <code>VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY</code>
flag. Regardless of the flags provided, restoration of the
snapshot is handled by
the <code>VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY</code> flag; in
both cases, they are restored by
the <code>virDomainRevertToSnapshot()</code> function. For
these types of snapshots, libvirt tracks each snapshot as a
separate <code>virDomainSnapshotPtr</code> object, and maintains
@@ -79,8 +78,7 @@
redefining a snapshot (<span class="since">since 0.9.5</span>),
with the <code>VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE</code> flag
of <code>virDomainSnapshotCreateXML()</code>, all of the XML
described here is relevant on input, even the fields that are
normally described as readonly for output.
described here is relevant.
</p>
<p>
Snapshots are maintained in a hierarchy. A domain can have a
@@ -99,14 +97,16 @@
</p>
<dl>
<dt><code>name</code></dt>
<dd>The optional name for this snapshot. If the name is
omitted, libvirt will create a name based on the time of the
creation.
<dd>The name for this snapshot. If the name is specified when
initially creating the snapshot, then the snapshot will have
that particular name. If the name is omitted when initially
creating the snapshot, then libvirt will make up a name for
the snapshot, based on the time when it was created.
</dd>
<dt><code>description</code></dt>
<dd>An optional human-readable description of the snapshot. If
the description is omitted when initially creating the
snapshot, then this field will be empty.
<dd>A human-readable description of the snapshot. If the
description is omitted when initially creating the snapshot,
then this field will be empty.
</dd>
<dt><code>memory</code></dt>
<dd>On input, this is an optional request for how to handle VM
@@ -128,10 +128,13 @@
what file name is created in an external snapshot. On output,
this is fully populated to show the state of each disk in the
snapshot, including any properties that were generated by the
hypervisor defaults. For full system snapshots, this field is
ignored on input and omitted on output (a full system snapshot
implies that all disks participate in the snapshot process).
This element has a list of <code>disk</code>
hypervisor defaults. For system checkpoints, this field is
ignored on input and omitted on output (a system checkpoint
implies that all disks participate in the snapshot process,
and since the current implementation only does internal system
checkpoints, there are no extra details to add); a future
release may allow the use of <code>disks</code> with a system
checkpoint. This element has a list of <code>disk</code>
sub-elements, describing anywhere from zero to all of the
disks associated with the domain. <span class="since">Since
0.9.5</span>
@@ -198,52 +201,45 @@
</dl>
</dd>
<dt><code>creationTime</code></dt>
<dd>A readonly representation of the time this snapshot was
created. The time is specified in seconds since the Epoch,
UTC (i.e. Unix time).
<dd>The time this snapshot was created. The time is specified
in seconds since the Epoch, UTC (i.e. Unix time). Readonly.
</dd>
<dt><code>state</code></dt>
<dd>A readonly representation of the state of the domain at the
time this snapshot was taken. If a full system snapshot was
created, then this is the state of the domain at that
time. When the domain is reverted to this snapshot, the
domain's state will default to this state, unless overridden
by <code>virDomainRevertToSnapshot()</code> flags to revert to
a running or paused state. Additionally, this field can be the
value "disk-snapshot" (<span class="since">since 0.9.5</span>)
when it represents only a disk snapshot (no VM memory state),
and reverting to this snapshot will default to an inactive
guest.
<dd>The state of the domain at the time this snapshot was taken.
If the snapshot was created as a system checkpoint, then this
is the state of the domain at that time; when the domain is
reverted to this snapshot, the domain's state will default to
whatever is in this field unless additional flags are passed
to <code>virDomainRevertToSnapshot()</code>. Additionally,
this field can be the value "disk-snapshot"
(<span class="since">since 0.9.5</span>) when it represents
only a disk snapshot (no VM memory state), and reverting to this
snapshot will default to an inactive guest. Readonly.
</dd>
<dt><code>parent</code></dt>
<dd>An optional readonly representation of the parent of this
snapshot. If present, this element contains exactly one child
element, <code>name</code>. This specifies the name of the
parent snapshot of this snapshot, and is used to represent
trees of snapshots.
<dd>The parent of this snapshot. If present, this element
contains exactly one child element, name. This specifies the
name of the parent snapshot of this snapshot, and is used to
represent trees of snapshots. Readonly.
</dd>
<dt><code>domain</code></dt>
<dd>A readonly representation of the domain that this snapshot
was taken against. Older versions of libvirt stored only a
single child element, uuid; reverting to a snapshot like this
is risky if the current state of the domain differs from the
state that the domain was created in, and requires the use of
the <code>VIR_DOMAIN_SNAPSHOT_REVERT_FORCE</code> flag
<dd>The domain that this snapshot was taken against. Older
versions of libvirt stored only a single child element, uuid;
reverting to a snapshot like this is risky if the current
state of the domain differs from the state that the domain was
created in, and requires the use of the
<code>VIR_DOMAIN_SNAPSHOT_REVERT_FORCE</code> flag
in <code>virDomainRevertToSnapshot()</code>. Newer versions
of libvirt (<span class="since">since 0.9.5</span>) store the
entire inactive <a href="formatdomain.html">domain
configuration</a> at the time of the snapshot
(<span class="since">since 0.9.5</span>). The domain will have
security-sensitive information omitted
unless the flag <code>VIR_DOMAIN_SNAPSHOT_XML_SECURE</code> is
provided on a read-write connection.
of libvirt (<span class="since">since 0.9.5</span>) store the entire
inactive <a href="formatdomain.html">domain configuration</a>
at the time of the snapshot (<span class="since">since
0.9.5</span>). Readonly.
</dd>
<dt><code>cookie</code></dt>
<dd>An optional readonly representation of a save image cookie
containing additional data libvirt may need to properly
restore a domain from an active snapshot when such data cannot
be stored directly in the <code>domain</code> to maintain
compatibility with older libvirt or hypervisor.
<dd>Save image cookie containing additional data libvirt may need to
properly restore a domain from an active snapshot when such data
cannot be stored directly in the <code>domain</code> to maintain
compatibility with older libvirt or hypervisor. Readonly.
</dd>
</dl>

View File

@@ -19,15 +19,14 @@
a single attribute <code>type</code>, which is one of <code>dir</code>,
<code>fs</code>, <code>netfs</code>, <code>disk</code>,
<code>iscsi</code>, <code>logical</code>, <code>scsi</code>
(all <span class="since">since 0.4.1</span>),
<code>mpath</code> (<span class="since">since 0.7.1</span>),
<code>rbd</code> (<span class="since">since 0.9.13</span>),
<code>sheepdog</code> (<span class="since">since 0.10.0</span>),
<code>gluster</code> (<span class="since">since 1.2.0</span>),
<code>zfs</code> (<span class="since">since 1.2.8</span>),
<code>vstorage</code> (<span class="since">since 3.1.0</span>),
or <code>iscsi-direct</code> (<span class="since">since 4.7.0</span>).
This corresponds to the
(all <span class="since">since 0.4.1</span>), <code>mpath</code>
(<span class="since">since 0.7.1</span>), <code>rbd</code>
(<span class="since">since 0.9.13</span>), <code>sheepdog</code>
(<span class="since">since 0.10.0</span>),
<code>gluster</code> (<span class="since">since
1.2.0</span>), <code>zfs</code> (<span class="since">since
1.2.8</span>) or <code>vstorage</code> (<span class="since">since
3.1.0</span>). This corresponds to the
storage backend drivers listed further along in this document.
</p>
<h3><a id="StoragePoolFirst">General metadata</a></h3>
@@ -122,26 +121,15 @@
&lt;/source&gt;
...</pre>
<pre>
...
&lt;source&gt;
&lt;host name='localhost'/&gt;
&lt;dir path='/var/lib/libvirt/images'/&gt;
&lt;format type='nfs'/&gt;
&lt;protocol ver='3'/&gt;
&lt;/source&gt;
...</pre>
<dl>
<dt><code>device</code></dt>
<dd>Provides the source for pools backed by physical devices
(pool types <code>fs</code>, <code>logical</code>, <code>disk</code>,
<code>iscsi</code>, <code>iscsi-direct</code>, <code>zfs</code>,
<code>vstorage</code>).
<code>iscsi</code>, <code>zfs</code>, <code>vstorage</code>).
May be repeated multiple times depending on backend driver. Contains
a required attribute <code>path</code> which is either the fully
qualified path to the block device node or for <code>iscsi</code>
or <code>iscsi-direct</code> the iSCSI Qualified Name (IQN).
the iSCSI Qualified Name (IQN).
<span class="since">Since 0.4.1</span>
<p>An optional attribute <code>part_separator</code> for each
<code>path</code> may be supplied. Valid values for the attribute
@@ -346,7 +334,6 @@
<dt><code>host</code></dt>
<dd>Provides the source for pools backed by storage from a
remote server (pool types <code>netfs</code>, <code>iscsi</code>,
<code>iscsi-direct</code>,
<code>rbd</code>, <code>sheepdog</code>, <code>gluster</code>). Will be
used in combination with a <code>directory</code>
or <code>device</code> element. Contains an attribute <code>name</code>
@@ -361,19 +348,11 @@
server. See the <a href="storage.html">storage driver page</a> for
any restrictions for specific storage backends.
<span class="since">Since 0.4.1</span></dd>
<dt><code>initiator</code></dt>
<dd>Required by the <code>iscsi-direct</code> pool in order to provide
the iSCSI Qualified Name (IQN) to communicate with the pool's
<code>device</code> target IQN. There is one sub-element
<code>iqn</code> with the <code>name</code> attribute to describe
the IQN for the initiator.
<span class="since">Since 4.7.0</span></dd>
<dt><code>auth</code></dt>
<dd>If present, the <code>auth</code> element provides the
authentication credentials needed to access the source by the
setting of the <code>type</code> attribute (pool
types <code>iscsi</code>, <code>iscsi-direct</code>, <code>rbd</code>).
The <code>type</code>
types <code>iscsi</code>, <code>rbd</code>). The <code>type</code>
must be either "chap" or "ceph". Use "ceph" for
Ceph RBD (Rados Block Device) network sources and use "iscsi" for CHAP
(Challenge-Handshake Authentication Protocol) iSCSI
@@ -407,12 +386,6 @@
LVM metadata type. All drivers are required to have a default
value for this, so it is optional. <span class="since">Since 0.4.1</span></dd>
<dt><code>protocol</code></dt>
<dd>For a <code>netfs</code> Storage Pool provide a mechanism to
define which NFS protocol version number will be used to contact
the server's NFS service. The attribute <code>ver</code> accepts
an unsigned integer as the version number to use.
<span class="since">Since 5.1.0</span></dd>
<dt><code>vendor</code></dt>
<dd>Provides optional information about the vendor of the
storage device. This contains a single
@@ -478,8 +451,8 @@
The <code>owner</code> element contains the numeric user ID.
The <code>group</code> element contains the numeric group ID.
If <code>owner</code> or <code>group</code> aren't specified when
creating a directory, the UID and GID of the libvirtd process are used.
The <code>label</code> element contains the MAC (eg SELinux)
creating a directory, the values are inherited from the parent
directory. The <code>label</code> element contains the MAC (eg SELinux)
label string.
<span class="since">Since 0.4.1</span>
For running directory or filesystem based pools, these fields
@@ -508,145 +481,6 @@
device, measured in bytes. <span class="since">Since 0.4.1</span>
</p>
<h3><a id="StoragePoolRefresh">Refresh overrides</a></h3>
<p>
The optional <code>refresh</code> element can control how the pool and
associated volumes are refreshed (pool type <code>rbd</code>). The
<code>allocation</code> attribute of the <code>volume</code> child element
controls the method used for computing the allocation of a volume. The
valid attribute values are <code>default</code> to compute the actual
usage or <code>capacity</code> to use the logical capacity for cases where
computing the allocation is too expensive. The following XML snippet
shows the syntax:
<pre>
&lt;pool type="rbd"&gt;
&lt;name&gt;myrbdpool&lt;/name&gt;
...
&lt;source/&gt;
...
&lt;refresh&gt;
&lt;volume allocation='capacity'/&gt;
&lt;/refresh&gt;
...
&lt;/pool&gt;
</pre>
<span class="since">Since 5.2.0</span>
</p>
<h3><a id="StoragePoolNamespaces">Storage Pool Namespaces</a></h3>
<p>
Usage of Storage Pool Namespaces provides a mechanism to provide
pool type specific data in a free form or arbitrary manner via
XML syntax targeted solely for the needs of the specific pool type
which is not otherwise supported in standard XML. For the "fs" and
"netfs" pool types this provides a mechanism to provide additional
mount options on the command line. For the "rbd" pool this provides
a mechanism to override default settings for RBD configuration options.
</p>
<p>
Usage of namespaces comes with no support guarantees. It is intended
for developers testing out a concept prior to requesting an explicitly
supported XML option in libvirt, and thus should never be used in
production.
</p>
<dl>
<dt><code>fs:mount_opts</code></dt>
<dd>Provides an XML namespace mechanism to optionally utilize
specifically named options for the mount command via the "-o"
option for the <code>fs</code> or <code>netfs</code> type storage
pools. In order to designate that the Storage Pool will be using
the mechanism, the <code>pool</code> element must be modified to
provide the XML namespace attribute syntax as follows:
<p>
xmlns:fs='http://libvirt.org/schemas/storagepool/fs/1.0'
</p>
<p>
The <code>fs:mount_opts</code> defines the mount options by
specifying multiple <code>fs:option</code> subelements with
the attribute <code>name</code> specifying the mount option to
be added. The value of the named option is not checked since
it's possible options don't exist on all distributions. It is
expected that proper and valid options will be supplied for the
target host.
</p>
The following XML snippet shows the syntax required in order to
utilize for a netfs pool:
<pre>
&lt;pool type="netfs" xmlns:fs='http://libvirt.org/schemas/storagepool/fs/1.0'&gt;
&lt;name&gt;nfsimages&lt;/name&gt;
...
&lt;source&gt;
...
&lt;/source&gt;
...
&lt;target&gt;
...
&lt;/target&gt;
&lt;fs:mount_opts&gt;
&lt;fs:option name='sync'/&gt;
&lt;fs:option name='lazytime'/&gt;
&lt;/fs:mount_opts&gt;
&lt;/pool&gt;
...</pre>
<span class="since">Since 5.1.0.</span></dd>
<dt><code>rbd:config_opts</code></dt>
<dd>Provides an XML namespace mechanism to optionally utilize
specifically named options for the RBD configuration options
via the rados_conf_set API for the <code>rbd</code> type
storage pools. In order to designate that the Storage Pool
will be using the mechanism, the <code>pool</code> element
must be modified to provide the XML namespace attribute
syntax as follows:
<p>
xmlns:rbd='http://libvirt.org/schemas/storagepool/rbd/1.0'
</p>
<p>
The <code>rbd:config_opts</code> defines the configuration options
by specifying multiple <code>rbd:option</code> subelements with
the attribute <code>name</code> specifying the configuration option
to be added and <code>value</code> specifying the configuration
option value. The name and value for each option is only checked
to be not empty. The name and value provided are not checked since
it's possible options don't exist on all distributions. It is
expected that proper and valid options will be supplied for the
target host.
</p>
The following XML snippet shows the syntax required in order to
utilize
<pre>
&lt;pool type="rbd" xmlns:rbd='http://libvirt.org/schemas/storagepool/rbd/1.0'&gt;
&lt;name&gt;myrbdpool&lt;/name&gt;
...
&lt;source&gt;
...
&lt;/source&gt;
...
&lt;target&gt;
...
&lt;/target&gt;
...
&lt;rbd:config_opts&gt;
&lt;rbd:option name='client_mount_timeout' value='45'/&gt;
&lt;rbd:option name='rados_mon_op_timeout' value='20'/&gt;
&lt;rbd:option name='rados_osd_op_timeout' value='10'/&gt;
&lt;/rbd:config_opts&gt;
&lt;/pool&gt;
</pre>
<span class="since">Since 5.1.0.</span></dd>
</dl>
<h2><a id="StorageVol">Storage volume XML</a></h2>
<p>
A storage volume will generally be either a file or a device
@@ -802,8 +636,8 @@
The <code>owner</code> element contains the numeric user ID.
The <code>group</code> element contains the numeric group ID.
If <code>owner</code> or <code>group</code> aren't specified when
creating a supported volume, the UID and GID of the libvirtd process
are used. The <code>label</code> element contains the MAC (eg SELinux)
creating a supported volume, the values are inherited from the parent
directory. The <code>label</code> element contains the MAC (eg SELinux)
label string.
For existing directory or filesystem based volumes, these fields
will be filled with the values used by the existing file.

View File

@@ -1,101 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Storage Pool Capabilities XML format</h1>
<ul id="toc"></ul>
<h2><a id="Overview">Overview</a></h2>
<p>The Storage Pool Capabilities XML will provide the information
to determine what types of Storage Pools exist, whether the pool is
supported, and if relevant the source format types, the required
source elements, and the target volume format types. </p>
<p>The Storage Pool Capabilities XML provides more information than the
<a href="/html/libvirt-libvirt-host.html#virConnectGetCapabilities">
<code>virConnectGetCapabilities</code>
</a>
which only provides an enumerated list of supported pool types.</p>
<h2><a id="elements">Element and attribute overview</a></h2>
<p>A query interface was added to the virConnect API's to retrieve the
XML listing of the set of Storage Pool Capabilities
(<span class="since">Since 5.2.0</span>):</p>
<pre>
<a href="/html/libvirt-libvirt-domain.html#virConnectGetStoragePoolCapabilities">virConnectGetStoragePoolCapabilities</a>
</pre>
<p>The root element that emulator capability XML document starts with is
named <code>storagepoolCapabilities</code>. There will be any number of
<code>pool</code> child elements with two attributes <code>type</code>
and <code>supported</code>. Each <code>pool</code> element may have
a <code>poolOptions</code> or <code>volOptions</code> subelements to
describe the available features. Sample XML output is:</p>
<pre>
&lt;storagepoolCapabilities&gt;
&lt;pool type='dir' supported='yes'&gt;
&lt;volOptions&gt;
&lt;defaultFormat type='raw'&lt;/&gt;
&lt;enum name='targetFormatType'&gt;
&lt;value&gt;none&lt;/value&gt;
&lt;value&gt;raw&lt;/value&gt;
...
&lt;/enum&gt;
&lt;/volOptions&gt;
&lt;/pool&gt;
&lt;pool type='fs' supported='yes'&gt;
&lt;poolOptions&gt;
&lt;defaultFormat type='auto'&lt;/&gt;
&lt;enum name='sourceFormatType'&gt;
&lt;value&gt;auto&lt;/value&gt;
&lt;value&gt;ext2&lt;/value&gt;
...
&lt;/enum&gt;
&lt;/poolOptions&gt;
&lt;volOptions&gt;
&lt;defaultFormat type='raw'&lt;/&gt;
&lt;enum name='targetFormatType'&gt;
&lt;value&gt;none&lt;/value&gt;
&lt;value&gt;raw&lt;/value&gt;
...
&lt;/enum&gt;
&lt;/volOptions&gt;
&lt;/pool&gt;
...
&lt;/storagepoolCapabilities&gt;
</pre>
<p>The following section decribes subelements of the
<code>poolOptions</code> and <code>volOptions</code> subelements </p>:
<dl>
<dt><code>defaultFormat</code></dt>
<dd>For the <code>poolOptions</code>, the <code>type</code> attribute
describes the default format name used for the pool source. For the
<code>volOptions</code>, the <code>type</code> attribute describes
the default volume name used for each volume.
</dd>
<dl>
<dt><code>enum</code></dt>
<dd>Each enum uses a name from the list below with any number of
<code>value</code> value subelements describing the valid values.
<dl>
<dt><code>sourceFormatType</code></dt>
<dd>Lists all the possible <code>poolOptions</code> source
pool format types.
</dd>
<dt><code>targetFormatType</code></dt>
<dd>Lists all the possible <code>volOptions</code> target volume
format types.
</dd>
</dl>
</dd>
</dl>
</dl>
</body>
</html>

View File

@@ -155,7 +155,7 @@
also implicitly stating that they have the legal right to make the
contribution, if doing so on behalf of a broader organization /
company. Most of the project's code is distributed under the GNU
Lesser General Public License, version 2.1 or later. Details of the
Lesser General Public License, version 2 or later. Details of the
exact license under which contributions will be presumed to be
covered are found in the source repositories, or website in question.
</p>

View File

@@ -1121,22 +1121,22 @@
<p>
Do not use the strncpy function. According to the man page, it
does <b>not</b> guarantee a NULL-terminated buffer, which makes
it extremely dangerous to use. Instead, use one of the replacement
functions provided by libvirt:
it extremely dangerous to use. Instead, use one of the
functionally equivalent functions:
</p>
<pre>
virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
</pre>
<p>
The first two arguments have the same meaning as for strncpy,
namely the destination and source of the copy operation. Unlike
strncpy, the function will always copy exactly the number of bytes
requested and make sure the destination is NULL-terminated, as the
source is required to be; sanity checks are performed to ensure the
size of the destination, as specified by the last argument, is
sufficient for the operation to succeed. On success, 0 is returned;
on failure, a value &lt;0 is returned instead.
The first three arguments have the same meaning as for strncpy;
namely the destination, source, and number of bytes to copy,
respectively. The last argument is the number of bytes
available in the destination string; if a copy of the source
string (including a \0) will not fit into the destination, no
bytes are copied and the routine returns NULL. Otherwise, n
bytes from the source are copied into the destination and a
trailing \0 is appended.
</p>
<pre>
@@ -1144,8 +1144,10 @@
</pre>
<p>
Use this variant if you know you want to copy the entire src
string into dest.
</p>
string into dest. Note that this is a macro, so arguments could
be evaluated more than once. This is equivalent to
virStrncpy(dest, src, strlen(src), destbytes)
</p>
<pre>
virStrcpyStatic(char *dest, const char *src)
@@ -1155,7 +1157,8 @@
string into dest <b>and</b> you know that your destination string is
a static string (i.e. that sizeof(dest) returns something
meaningful). Note that this is a macro, so arguments could be
evaluated more than once.
evaluated more than once. This is equivalent to
virStrncpy(dest, src, strlen(src), sizeof(dest)).
</p>
<pre>
@@ -1412,34 +1415,5 @@ int foo()
in the same way, but still make sure they get reviewed if non-trivial.
</li>
</ul>
<h2><a id="coverage">Code coverage reports</a></h2>
<p>
Code coverage HTML reports can be generated with:
</p>
<pre>
make coverage
</pre>
<p>
Reports will be generated in the <code>cov/</code> directory. Point a
web browser at <code>cov/index.html</code> for the full report.
</p>
<p>
The <code>make coverage</code> target is provided by <code>gnulib</code>.
It is a convenience helper for calling the following 3 targets in order.
It may be useful to occasionally call these directly.
<ul>
<li><code>make init-coverage</code>: run <code>make clean</code> and
remove all code coverage counter files (*.gcno, etc.)</li>
<li><code>make build-coverage</code>: run <code>make</code> and
<code>make check</code> with <code>CFLAGS</code> filled in with
necessary coverage flags</li>
<li><code>make gen-coverage</code>: generate the HTML report</li>
</ul>
</p>
</body>
</html>

View File

@@ -66,7 +66,6 @@
<a href="formatstorageencryption.html">storage encryption</a>,
<a href="formatcaps.html">capabilities</a>,
<a href="formatdomaincaps.html">domain capabilities</a>,
<a href="formatstoragecaps.html">storage pool capabilities</a>,
<a href="formatnode.html">node devices</a>,
<a href="formatsecret.html">secrets</a>,
<a href="formatsnapshot.html">snapshots</a></dd>

View File

@@ -426,7 +426,7 @@ dprintf(logfd, "%s: ", timestamp);
VIR_FREE(timestamp);
virCommandWriteArgLog(cmd, logfd);
string = virCommandToString(cmd, false);
string = virCommandToString(cmd);
if (string)
VIR_DEBUG("about to run %s", string);
VIR_FREE(string);

View File

@@ -100,15 +100,14 @@
margin-right: auto;
padding: 0px;
padding-bottom: 1em;
max-width: 95%;
width: 70em;
max-width: 60em;
}
body.index #content,
body.docs #content,
body.hvsupport #content
{
width: inherit;
max-width: inherit;
}
pre {
@@ -394,7 +393,6 @@ table.acl {
table.acl tr, table.acl td {
padding: 0.3em;
border: 1px solid #ccc;
}
table.acl thead {
@@ -538,7 +536,3 @@ dl.mail dt a:hover {
color: rgb(255, 230, 0);
text-decoration: none;
}
td.enumvalue {
white-space: nowrap;
}

View File

@@ -288,24 +288,6 @@
</xsl:choose>
</xsl:template>
<xsl:template name="enumvalue">
<xsl:param name="value" select="@value"/>
<xsl:param name="valuehex" select="@value_hex"/>
<xsl:param name="valuebitshift" select="@value_bitshift"/>
<xsl:value-of select="@value"/>
<xsl:if test="$valuehex != '' or $valuebitshift != ''">
<xsl:text> (</xsl:text>
<xsl:if test="$valuehex != ''">
<xsl:value-of select="@value_hex"/>
</xsl:if>
<xsl:if test="$valuebitshift != ''">
<xsl:text>; 1 &lt;&lt; </xsl:text>
<xsl:value-of select="@value_bitshift"/>
</xsl:if>
<xsl:text>)</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="typedef[@type = 'enum']">
<xsl:variable name="name" select="string(@name)"/>
<h3><a name="{$name}"><code><xsl:value-of select="$name"/></code></a></h3>
@@ -324,7 +306,7 @@
<td><xsl:text> = </xsl:text></td>
<xsl:choose>
<xsl:when test="@info != ''">
<td class="enumvalue"><xsl:call-template name="enumvalue"/></td>
<td><xsl:value-of select="@value"/></td>
<td>
<div class="comment">
<xsl:call-template name="dumptext">
@@ -334,7 +316,7 @@
</td>
</xsl:when>
<xsl:otherwise>
<td colspan="2" class="enumvalue"><xsl:call-template name="enumvalue"/></td>
<td colspan="2"><xsl:value-of select="@value"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>

View File

@@ -33,929 +33,6 @@
-->
<libvirt>
<release version="v5.2.0" date="unreleased">
<section title="New features">
<change>
<summary>
Add Storage Pool Capabilities output
</summary>
<description>
Add support to list an enumerated list of supported Storage
Pools via the virConnectGetCapabilities API when connected
via a Storage Driver. Add support to get a more detailed
list XML output Storage Pool Capabilities vis the
virConnectGetStoragePoolCapabilites API.
</description>
</change>
<change>
<summary>
qemu: Support virtio-{non-}transitional device models
</summary>
<description>
<code>virtio-transitional</code> and
<code>virtio-non-transitional</code> <code>model</code> values
were added to the QEMU driver for the following devices:
<code>disk</code>, <code>interface</code>, <code>filesystem</code>,
<code>rng</code>, <code>vsock</code>, <code>memballoon</code>,
<code>controller</code> type <code>scsi</code>,
<code>controller</code> type <code>virtio-serial</code>,
<code>input</code> bus <code>virtio</code>
type <code>passthrough</code>,
<code>hostdev</code> type <code>scsi_host</code>. These new
models can be used to give fine grained control over what
virtio device version is presented to the guest.
</description>
</change>
<change>
<summary>
qemu: Enable firmware autoselection
</summary>
<description>
Libvirt allows users to provide loader path for some time now.
However, this puts some burden on users because they need to
know what firmware meets their requirements. Now that QEMU
ships firmware description files this burden can be moved onto
libvirt. It is as easy as setting the <code>firmware</code>
attribute in the <code>os</code> element (accepted values are
<code>bios</code> and <code>efi</code>). Moreover, libvirt
automatically enables domain features needed for firmware it
chooses.
</description>
</change>
<change>
<summary>
snapshots: Add support for topological listings
</summary>
<description>
A new flag VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL is available
for the various snapshot listing APIs such as
virDomainListAllSnapshots(). For drivers that support the
flag, the listed snapshots are guaranteed to be sorted such
that parents occur before children.
</description>
</change>
<change>
<summary>
Xen: Add support for max grant frames setting
</summary>
<description>
Add support for Xen's max_grant_frames setting by adding a
new xenbus controller type with a maxGrantFrames attribute.
E.g. <code>&lt;controller type='xenbus' maxGrantFrames='64'/&gt;</code>
</description>
</change>
<change>
<summary>
qemu: Add support for parallel migration
</summary>
<description>
With QEMU 4.0.0 libvirt can enable parallel migration which causes
the memory pages to be processed in parallel by several threads and
sent to the destination host using several connections at the same
time. This may increase migration speed in case a single thread is
unable to saturate the network link.
</description>
</change>
</section>
<section title="Removed features">
<change>
<summary>
Drop support for Upstart and "Red Hat" init scripts
</summary>
<description>
Not a single one of the platforms we target still uses Upstart,
and the Upstart project itself has been abandoned for several years
now; the same is true for the "Red Hat" (really System V) init
scripts, since RHEL 7 and later releases use systemd.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
Report class information for PCI node device capability.
</summary>
</change>
<change>
<summary>
Split setup of IPv4 and IPv6 top level chain
</summary>
<description>
The requirement resulting from private chains improvement done
in <code>v5.1.0</code> was refined so that only tables from
corresponding IP version are required. This means that if a
network doesn't have <code>IPv6</code> enabled then those
tables are not required.
</description>
</change>
</section>
<section title="Bug fixes">
</section>
</release>
<release version="v5.1.0" date="2019-03-04">
<section title="New features">
<change>
<summary>
bhyve: Add support for additional command-line arguments
</summary>
<description>
The bhyve driver now supports passing additional command-line
arguments to the bhyve process using the new
<code>&lt;bhyve:commandline&gt;</code> element in domain
configuration.
</description>
</change>
<change>
<summary>
network: Support setting a firewalld "zone" for virtual network bridges
</summary>
<description>
All libvirt virtual networks with bridges managed by libvirt
(i.e. those with forward mode of "nat", "route", "open", or
no forward mode) will now be placed in a special firewalld
zone called "libvirt" by default. The zone of any network
bridge can be changed using the <code>zone</code> attribute
of the network's <code>bridge</code> element.
</description>
</change>
<change>
<summary>
bhyve: Support for ignoring unknown MSRs reads and writes
</summary>
<description>
A new &lt;features&gt; element &lt;msrs unknown='ignore'/&gt; was
introduced and the bhyve driver supports it to control unknown
Model Specific Registers (MSRs) reads and writes.
</description>
</change>
<change>
<summary>
qemu: Add support for encrypted VNC TLS keys
</summary>
<description>
Use the password stored in the secret driver under the uuid
specified by the <code>vnc_tls_x509_secret_uuid</code> option
in qemu.conf.
</description>
</change>
<change>
<summary>
Add storage pool namespace options
</summary>
<description>
Allow for adjustment of RBD configuration options via Storage
Pool XML Namespace adjustments.
</description>
</change>
<change>
<summary>
qemu: Add support for setting post-copy migration bandwidth
</summary>
<description>
Users can now limit the bandwidth of post-copy migration, e.g.
via <code>virsh migrate --postcopy-bandwidth</code>.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
Create private chains for virtual network firewall rules
</summary>
<description>
Historically firewall rules for virtual networks were added
straight into the base chains. This works but has a number of
bugs and design limitations. To address them, libvirt now puts
firewall rules into its own chains. Note that with this change the
<code>filter</code>, <code>nat</code> and <code>mangle</code> tables
are required for both <code>IPv4</code> and <code>IPv6</code>.
</description>
</change>
<change>
<summary>
Detect CEPH and GPFS as shared FS
</summary>
<description>
When starting a migration libvirt performs some sanity checks
to make sure domain will be able to run on the destination.
One of the requirements is that the disk has to either be
migrated too or be accessible from a network filesystem. CEPH
and GPFS weren't detected as a network filesystem.
</description>
</change>
<change>
<summary>
Advertise network MTU via DHCP when specified
</summary>
<description>
If network MTU is set and the network has DHCP enabled,
advertise the MTU in DHCP transaction too so that clients can
adjust their link accordingly.
</description>
</change>
<change>
<summary>
qemu: Allocate memory at the configured NUMA nodes from start
</summary>
<description>
Libvirt used to just start QEMU, let it allocate memory for
the guest, and then use CGroups to move the memory to
configured NUMA nodes. This is suboptimal as huge chunks of
memory have to be moved. Moreover, this relies on ability to
move memory later which is not always true. A change was made
to set process affinity correctly from the start so that memory
is allocated on the configured nodes from the beginning.
</description>
</change>
<change>
<summary>
Support for newer Wireshark
</summary>
<description>
Adapt libvirt to use the more recent release requiring a
source build configuration of libvirt
<code>--with-wireshark</code> to upgrade to the more recent
version.
</description>
</change>
<change>
<summary>
Batch mode virsh and virt-admin parsing improvements
</summary>
<description>
When parsing a single-argument command_string in batch mode,
virsh and virt-admin now permit newlines in addition to
semicolons for splitting commands, and backslash-newline for
splitting long lines, to be more like shell parsing.
</description>
</change>
</section>
<section title="Bug fixes">
<change>
<summary>
qemu: Use CAP_DAC_OVERRIDE during QEMU capabilities probing
</summary>
<description>
By default, libvirt runs the QEMU process as <code>qemu:qemu</code>
which could cause issues during probing as some features like AMD SEV
might be inaccessible to QEMU because of file system permissions.
Therefore, <code>CAP_DAC_OVERRIDE</code> is granted to overcome these
for the purposes of probing.
</description>
</change>
<change>
<summary>
storage: Add default mount options for fs/netfs storage pools
</summary>
<description>
Altered the command line generation for fs/netfs storage pools to
add some default options. For Linux based systems, the options
added are "nodev, nosuid, noexec". For FreeBSD based systems,
the options added are "nosuid, noexec".
</description>
</change>
<change>
<summary>
qemu: Allow use of PCI for RISC-V guests
</summary>
<description>
This works with QEMU 4.0.0+ only and is opt-in at the moment, since
it requires users to manually assign PCI addresses, but is otherwise
fully functional.
</description>
</change>
<change>
<summary>
network: Fix virtual networks on systems using firewalld+nftables
</summary>
<description>
Because of the transitional state of firewalld's new support
for nftables, not all iptables features required by libvirt
are yet available, so libvirt must continue to use iptables
for its own packet filtering rules even when the firewalld
backend is set to use nftables. However, due to the way
iptables support is implemented in kernels using nftables
(iptables rules are converted to nftables rules and
processed in a separate hook from the native nftables
rules), guest networking was broken on hosts with firewalld
configured to use nftables as the backend. This has been
fixed by putting libvirt-managed bridges in their own
firewalld zone, so that guest traffic can be forwarded
beyond the host and host services can be exposed to guests
on the virtual network without opening up those same
services to the rest of the physical network. This means
that host access from virtual machines is no longer
controlled by the firewalld default zone (usually "public"),
but rather by the new firewalld zone called "libvirt"
(unless configured otherwise using the new zone
attribute of the network bridge element).
</description>
</change>
<change>
<summary>
qemu: Fix i6300esb watchdog hotplug on Q35
</summary>
<description>
Ensure that libvirt allocates a PCI address for the device so
that QEMU did not default to an address that would not allow
for device hotplug.
</description>
</change>
<change>
<summary>
lxc: Don't reboot host on virDomainReboot
</summary>
<description>
If the container is really a simple one (init is just bash and
the whole root is passed through) then virDomainReboot and
virDomainShutdown would reboot or shutdown the host. The
solution is to use different method to reboot or shutdown the
container in that case (e.g. signal).
</description>
</change>
<change>
<summary>
rpc: Various stream fixes
</summary>
<description>
One particular race was fixed, one locking problem and error
reporting from streams was made better.
</description>
</change>
<change>
<summary>
qemu: Fix guestfwd hotplug/hotunplug
</summary>
<description>
Fixed the generation of the guestfwd hotplug/unplug command
sent to QEMU to match the syntax used when creating the
initial command line.
</description>
</change>
<change>
<summary>
qemu: Forbid CDROMs on virtio bus
</summary>
<description>
Attempting to create an empty virtio-blk drive or attempting
to eject it results into an error. Forbid configurations
where users would attempt to use CDROMs in virtio bus.
</description>
</change>
<change>
<summary>
qemu: Use 'raw' for 'volume' disks without format
</summary>
<description>
Storage pools might want to specify format of the image when
translating the volume thus libvirt can't add any default
format when parsing the XML. Add an explicit format when
starting the VM and format is not present neither by user
specifying it nor by the storage pool translation function.
</description>
</change>
<change>
<summary>
qemu: Assume 'raw' default storage format also for network storage
</summary>
<description>
Post parse callback adds the 'raw' type only for local files.
Remote files can also have backing store (even local) so we
should do this also for network backed storage.
</description>
</change>
<change>
<summary>
qemu: Fix block job progress reporting and advocate for READY event
</summary>
<description>
In some cases QEMU can get to 100% and still not reach the
synchronised phase. Initiating a pivot in that case will fail.
Therefore it is strongly advised to wait for
<code>VIR_DOMAIN_BLOCK_JOB_READY</code> event which does not
suffer from this problem.
</description>
</change>
<change>
<summary>
qemu: Don't format image properties for empty drive
</summary>
<description>
If a <code>-drive</code> has no image, then formatting
attributes such as cache, readonly, etc. would cause errors to
be reported from QEMU. This was fixed by not supplying the
attributes for devices without an image.
</description>
</change>
<change>
<summary>
External snapshot metadata redefinition is fixed
</summary>
<description>
Attempting to use VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE to
reinstate the metadata describing an external snapshot
created earlier for an offline domain no longer fails.
</description>
</change>
</section>
</release>
<release version="v5.0.0" date="2019-01-15">
<section title="New features">
<change>
<summary>
Xen: Add support for openvswitch
</summary>
<description>
The libxl driver now supports virtual interfaces that connect to
an openvswitch bridge, including interfaces with VLAN tagging and
trunking configuration.
</description>
</change>
<change>
<summary>
qemu: Report whether KVM nesting is available
</summary>
<description>
Running nested KVM guests requires specific configuration steps to
be performed on the host; libvirt will now report in the host
capabilities whether KVM nesting support is available.
</description>
</change>
</section>
<section title="Removed features">
<change>
<summary>
Drop UML driver
</summary>
<description>
The UML driver was unmaintained and not tested for
quite some time now. Worse, there is a bug that causes
it to deadlock on some very basic operations (e.g.
dumping domain XML). These facts make us believe no one
uses it.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
qemu: Add support for ARMv6l guests
</summary>
</change>
<change>
<summary>
Support more NVDIMM configuration options
</summary>
<description>
Introduce more configuration options. For the source element, add
the 'alignsize' and 'pmem' subelements. For the target element, add
the 'readonly' subelement.
</description>
</change>
<change>
<summary>
cpu: Add support for "stibp" x86_64 feature
</summary>
<description>
Add cpu flag stibp (Single Thread Indirect Branch Predictors) to
prevent indirect branch predictions from being controlled by the
sibling Hyperthread.
</description>
</change>
<change>
<summary>
libxl: Handle external domain destroy
</summary>
<description>
Historically, if a domain was destroyed using <code>xl</code>
rather than through libvirt APIs, libvirt would not be aware of
the fact and keep considering it as running. This is no longer the
case.
</description>
</change>
<change>
<summary>
Start selecting the first available DRI device for OpenGL operations
</summary>
<description>
If OpenGL support is needed (either with SPICE gl enabled or with
egl-headless), libvirt is now able to pick the first available DRI
device for the job. At the same time, this improvement is also a
bugfix as it prevents permission-related issues with regards to our
mount namespaces and the default DRI render node's permissions which
would normally prevent QEMU from accessing such a device.
</description>
</change>
<change>
<summary>
qemu: Add support for postcopy-requests migration statistics
</summary>
<description>
The <code>virDomainJobInfo</code> can get number page requests
received from the destination host during post-copy migration.
</description>
</change>
</section>
<section title="Bug fixes">
<change>
<summary>
lxc: Don't forbid interfaces with type=direct
</summary>
<description>
Such interfaces are supported by lxc and should be allowed.
</description>
</change>
<change>
<summary>
qemu: Fully clean up RNG devices on detach
</summary>
<description>
Some RNG device types, such as those using EGD, might need extra
clean up on the host in addition to removing the guest-side device.
</description>
</change>
</section>
</release>
<release version="v4.10.0" date="2018-12-03">
<section title="New features">
<change>
<summary>
qemu: Add Hyper-V PV IPI and Enlightened VMCS support
</summary>
<description>
The QEMU driver now has support for Hyper-V PV IPI and Enlightened VMCS
for Windows and Hyper-V guests.
</description>
</change>
<change>
<summary>
qemu: Added support for PCI devices on S390
</summary>
<description>
PCI addresses can now include the new zpci element which contains
uid (user-defined identifier) and fid (PCI function identifier)
attributes and makes the corresponding devices usable by S390
guests.
</description>
</change>
<change>
<summary>
Support changing IOThread polling parameters for a live guest
</summary>
<description>
Introduced virDomainSetIOThreadParams which allows dynamically
setting the IOThread polling parameters used by QEMU to manage
the thread polling interval and the algorithm for growth or
shrink of the polling time. The values only affect a running
guest with IOThreads. The guest's IOThread polling values can
be viewed via the domain statistics.
</description>
</change>
<change>
<summary>
Xen: Add support for PVH
</summary>
<description>
The libxl driver now supports Xen's PVH virtual machine type.
PVH machines are enabled with the new "xenpvh" OS type, e.g.
<code>&lt;os&gt;&lt;type&gt;xenpvh&lt;/type&gt;&lt;/os&gt;</code>
</description>
</change>
<change>
<summary>
qemu: Added support for CMT (Cache Monitoring Technology)
</summary>
<description>
Introduced cache monitoring using the <code>monitor</code>
element in <code>cachetune</code> for vCPU threads. Added
interfaces to get and display the cache utilization statistics
through the command 'virsh domstats' via the
virConnectGetAllDomainStats API.
</description>
</change>
<change>
<summary>
qemu: Add support for nested HV for pSeries guests
</summary>
<description>
Nested HV support makes it possible to run nested (L2) guests
with minimal performance penalty when compared to regular (L1)
guests on ppc64 hardware.
</description>
</change>
</section>
<section title="Improvements">
</section>
<section title="Bug fixes">
<change>
<summary>
Xen: Handle soft reset shutdown event
</summary>
<description>
The pvops Linux kernel uses soft reset to handle the crash
machine operation. The libxl driver now supports the soft
reset shutdown event, allowing proper crash handling of
pvops-based HVM domains.
</description>
</change>
</section>
</release>
<release version="v4.9.0" date="2018-11-04">
<section title="New features">
<change>
<summary>
util: Add cgroup v2 support
</summary>
<description>
cgroup v2 support has been implemented in libvirt, with both
"unified" (v2 only) and "hybrid" (v2 + v1) setups being usable;
existing "legacy" (v1 only) setups will keep working.
</description>
</change>
<change>
<summary>
qemu: Add vfio AP support
</summary>
<description>
The QEMU driver now has support to passthrough adjunct processors
into QEMU guests on S390.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
rpc: Make 'genprotocol' output reproducible
</summary>
<description>
This is another step towards making libvirt builds fully
reproducible.
</description>
</change>
</section>
<section title="Bug fixes">
<change>
<summary>
security: Fix permissions for UNIX sockets
</summary>
<description>
Since 4.5.0, libvirt is using FD passing to hand sockets over to
QEMU, which in theory removes the need for them to be accessible by
the user under which the QEMU process is running; however, other
processes such as vdsm need to access the sockets as well, which
means adjusting permissions is still necessary.
</description>
</change>
<change>
<summary>
cpu_map: Add Icelake model definitions
</summary>
<description>
These CPU models will be available in the upcoming 3.1.0 QEMU
release.
</description>
</change>
<change>
<summary>
util: Properly parse URIs with missing trailing slash
</summary>
<description>
Some storage URIs were not parsed correctly, in which case libvirt
ended up emitting XML that it would then refuse to parse back.
</description>
</change>
</section>
</release>
<release version="v4.8.0" date="2018-10-01">
<section title="New features">
<change>
<summary>
Xen: Support PM Suspend and Wakeup
</summary>
<description>
The libxl driver now supports the virDomainPMSuspendForDuration
and virDomainPMWakeup APIs.
</description>
</change>
</section>
<section title="Removed features">
<change>
<summary>
Xen: Drop support for Xen 4.4 and 4.5
</summary>
<description>
Xen 4.4 and 4.5 are no longer supported by the Xen community.
Drop support for these older versions and require Xen >= 4.6.
</description>
</change>
<change>
<summary>
nwfilter: Disallow binding creation in session mode
</summary>
<description>
Ensure that a filter binding creation is not attempted in session
mode and generates a proper error message.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
qemu: Retrieve guest hostname through QEMU Guest Agent command
</summary>
<description>
QEMU is now able to retrieve the guest hostname using a new QEMU-GA
command called 'guest-get-host-name'. Virsh users can execute
'domhostname' for QEMU driver for domains configured to use the
Guest Agent.
</description>
</change>
<change>
<summary>
virsh: Implement vsh-table in virsh and virsh-admin
</summary>
<description>
The new API fixes problems with table-alignment, making the tables
more readable and deals with unicode.
</description>
</change>
</section>
<section title="Bug fixes">
<change>
<summary>
storage: Allow inputvol to be encrypted
</summary>
<description>
When creating a storage volume based on another volume, the base
input volume is allowed to be encrypted.
</description>
</change>
<change>
<summary>
virsh: Require explicit --domain for domxml-to-native
</summary>
<description>
The --domain option for domxml-to-native virsh command has always
been documented as required, but commit v4.3.0-127-gd86531daf2
accidentally made it optional.
</description>
</change>
<change>
<summary>
lxc_monitor: Avoid AB / BA lock race
</summary>
<description>
A deadlock situation could occur when autostarting a LXC domain
'guest' due to two threads attempting to take opposing locks while
holding opposing locks (AB BA problem).
</description>
</change>
</section>
</release>
<release version="v4.7.0" date="2018-09-03">
<section title="New features">
<change>
<summary>
storage: add storage pool iscsi-direct
</summary>
<description>
Introduce a new storage pool backend that uses libiscsi instead of
iscsiadm. It support basic pool operations: checkPool and refreshPool.
</description>
</change>
<change>
<summary>
Add support for MBA (Memory Bandwidth Allocation technology)
</summary>
<description>
Domain vCPU threads can now have allocated some parts of host memory
bandwidth by using the <code>memorytune</code> element in <code>cputune</code>.
</description>
</change>
<change>
<summary>
qemu: Add support for RISC-V guests
</summary>
<description>
riscv32 and riscv64 guest architectures are now supported.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
qemu: Add ccw support for vhost-vsock
</summary>
<description>
Support the vhost-vsock-ccw device on S390.
</description>
</change>
<change>
<summary>
qemu: Make default machine type independent of QEMU
</summary>
<description>
We can't control whether or not QEMU will change its default
machine type in the future, or whether downstream distributions
will decide to compile out some machine types, so our only option
to provide a predictable behavior is taking care of the default
ourselves; management applications and users are encouraged to
explicitly pick a machine type when creating new guests.
</description>
</change>
<change>
<summary>
apparmor: Various improvements
</summary>
<description>
Rules have been added to deal with a number of scenarios that
didn't work correctly.
</description>
</change>
</section>
<section title="Bug fixes">
<change>
<summary>
esx: Truncate CPU model name
</summary>
<description>
Some CPU model names are too long to be stored into the
corresponding property, and should be explicitly truncated
to avoid unexpected behavior in users of the
<code>virNodeGetInfo()</code> API such as
<code>virsh nodeinfo</code>.
</description>
</change>
<change>
<summary>
utils: Remove arbitrary limit on socket_id/core_id
</summary>
<description>
Both values were assumed to be smaller than 4096, but in fact
they are entirely hardware-dependent and there have been reports
of machines presenting much bigger values, preventing libvirt from
working correctly; all such limits have now been removed.
</description>
</change>
</section>
</release>
<release version="v4.6.0" date="2018-08-06">
<section title="New features">
<change>
<summary>
qemu: Implement the HTM pSeries feature
</summary>
<description>
Users can now decide whether HTM (Hardware Transactional Memory)
support should be available to the guest.
</description>
</change>
<change>
<summary>
qemu: Enable VNC console for mediated devices
</summary>
<description>
Host devices now support a new atribute 'display' which can be used
to turn on frame buffer rendering on a vgpu mediated device instead of
on an emulated GPU, like QXL.
</description>
</change>
</section>
<section title="Improvements">
<change>
<summary>
qemu: Introduce a new video model of type 'none'
</summary>
<description>
Introduce a new video model type that disables the automatic addition
of a video device to domains with 'graphics' specified in their XML.
This can be useful with GPU mediated devices which can serve as the
only rendering devices within the guest.
</description>
</change>
<change>
<summary>
virsh: Add --alias to attach-disk and attach-interface commands
</summary>
<description>
Add option --alias to set customized device alias name when
using attach-disk or attach-interface commands.
</description>
</change>
<change>
<summary>
virsh: Support usb and sata address to attach-disk
</summary>
<description>
Usb or sata address could be used when attach-disk with --address.
For example, use usb address as usb:&lt;bus&gt;.&lt;port&gt;, use
sata address as &lt;controller&gt;.&lt;bus&gt;.&lt;unit&gt;.
</description>
</change>
</section>
<section title="Bug fixes">
</section>
</release>
<release version="v4.5.0" date="2018-07-02">
<section title="New features">
<change>

View File

@@ -175,6 +175,7 @@
<h3>Community</h3>
<ul>
<li><a href="https://twitter.com/hashtag/libvirt">twitter</a></li>
<li><a href="https://plus.google.com/communities/109522598353007505282">google+</a></li>
<li><a href="http://stackoverflow.com/questions/tagged/libvirt">stackoverflow</a></li>
<li><a href="http://serverfault.com/questions/tagged/libvirt">serverfault</a></li>
</ul>

View File

@@ -39,7 +39,7 @@
<ul>
<li><a href="https://repology.org/metapackage/libvirt/versions">libvirt</a></li>
<li><a href="https://repology.org/metapackage/qemu/versions">qemu</a></li>
<li><a href="https://repology.org/metapackage/qemu-kvm/versions">qemu-kvm</a></li>
<li><a href="https://repology.org/metapackage/qemu/versions">qemu-kvm</a></li>
</ul>

View File

@@ -17,6 +17,9 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
# Authors:
# Andrea Bolognani <abologna@redhat.com>
from __future__ import print_function

View File

@@ -65,17 +65,6 @@
</data>
</choice>
</define>
<define name="uint32">
<choice>
<data type="string">
<param name="pattern">(0x)?[0-9a-fA-F]{1,8}</param>
</data>
<data type="unsignedInt">
<param name="minInclusive">0</param>
<param name="maxInclusive">4294967295</param>
</data>
</choice>
</define>
<define name="UUID">
<choice>
@@ -122,22 +111,6 @@
</attribute>
</optional>
</define>
<define name="zpciaddress">
<optional>
<element name="zpci">
<optional>
<attribute name="uid">
<ref name="uint16"/>
</attribute>
</optional>
<optional>
<attribute name="fid">
<ref name="uint32"/>
</attribute>
</optional>
</element>
</optional>
</define>
<!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
<!-- The lowest bit of the 1st byte is the "multicast" bit. a -->
@@ -279,12 +252,6 @@
</data>
</define>
<define name="zoneName">
<data type="string">
<param name="pattern">[a-zA-Z0-9_\-]+</param>
</data>
</define>
<define name="filePath">
<data type="string">
<param name="pattern">.+</param>
@@ -412,7 +379,6 @@
<choice>
<value>aarch64</value>
<value>alpha</value>
<value>armv6l</value>
<value>armv7l</value>
<value>cris</value>
<value>i686</value>
@@ -432,8 +398,6 @@
<value>ppc64</value>
<value>ppc64le</value>
<value>ppcemb</value>
<value>riscv32</value>
<value>riscv64</value>
<value>s390</value>
<value>s390x</value>
<value>sh4</value>

View File

@@ -51,9 +51,6 @@
<optional>
<ref name='cache'/>
</optional>
<optional>
<ref name='memory_bandwidth'/>
</optional>
<zeroOrMore>
<ref name='secmodel'/>
</zeroOrMore>
@@ -316,9 +313,6 @@
</zeroOrMore>
</element>
</oneOrMore>
<optional>
<ref name='cpuMonitor'/>
</optional>
</element>
</define>
@@ -332,68 +326,6 @@
</attribute>
</define>
<define name='memory_bandwidth'>
<element name='memory_bandwidth'>
<oneOrMore>
<element name='node'>
<attribute name='id'>
<ref name='unsignedInt'/>
</attribute>
<attribute name='cpus'>
<ref name='cpuset'/>
</attribute>
<zeroOrMore>
<element name='control'>
<attribute name='granularity'>
<ref name='unsignedInt'/>
</attribute>
<optional>
<attribute name='min'>
<ref name='unsignedInt'/>
</attribute>
</optional>
<attribute name='maxAllocs'>
<ref name='unsignedInt'/>
</attribute>
</element>
</zeroOrMore>
</element>
</oneOrMore>
<optional>
<ref name='cpuMonitor'/>
</optional>
</element>
</define>
<define name='cpuMonitor'>
<element name='monitor'>
<optional>
<attribute name='level'>
<ref name='unsignedInt'/>
</attribute>
<attribute name='reuseThreshold'>
<ref name='unsignedInt'/>
</attribute>
</optional>
<attribute name='maxMonitors'>
<ref name='unsignedInt'/>
</attribute>
<oneOrMore>
<element name='feature'>
<attribute name='name'>
<ref name='monitorFeature'/>
</attribute>
</element>
</oneOrMore>
</element>
</define>
<define name='monitorFeature'>
<data type='string'>
<param name='pattern'>(llc_|mbm_)[a-zA-Z0-9\-_]+</param>
</data>
</define>
<define name='guestcaps'>
<element name='guest'>
<ref name='ostype'/>
@@ -412,7 +344,7 @@
but is also used by phyp driver -->
<value>hvm</value> <!-- unmodified OS -->
<value>exe</value> <!-- For container based virt -->
<value>uml</value> <!-- user mode linux; NOT USED ANYMORE -->
<value>uml</value> <!-- user mode linux -->
</choice>
</element>
</define>
@@ -484,7 +416,7 @@
<value>kqemu</value>
<value>kvm</value>
<value>xen</value>
<value>uml</value> <!-- NOT USED ANYMORE -->
<value>uml</value>
<value>lxc</value>
<value>openvz</value>
<value>test</value>

View File

@@ -142,18 +142,12 @@
<define name='devices'>
<element name='devices'>
<optional>
<interleave>
<ref name='disk'/>
</optional>
<optional>
<ref name='graphics'/>
</optional>
<optional>
<ref name='video'/>
</optional>
<optional>
<ref name='hostdev'/>
</optional>
</interleave>
</element>
</define>
@@ -187,18 +181,12 @@
<define name='features'>
<element name='features'>
<optional>
<interleave>
<ref name='gic'/>
</optional>
<optional>
<ref name='vmcoreinfo'/>
</optional>
<optional>
<ref name='vmgenid'/>
</optional>
<optional>
<ref name='sev'/>
</optional>
</interleave>
</element>
</define>

View File

@@ -81,9 +81,6 @@
<optional>
<ref name='launchSecurity'/>
</optional>
<optional>
<ref name='bhyvecmdline'/>
</optional>
</interleave>
</element>
</define>
@@ -207,7 +204,7 @@
<value>kvm</value>
<value>xen</value>
<value>lxc</value>
<value>uml</value> <!-- NOT USED ANYMORE -->
<value>uml</value>
<value>openvz</value>
<value>test</value>
<value>vmware</value>
@@ -256,14 +253,6 @@
</optional>
<element name="os">
<interleave>
<optional>
<attribute name="firmware">
<choice>
<value>bios</value>
<value>efi</value>
</choice>
</attribute>
</optional>
<ref name="ostypehvm"/>
<optional>
<element name="loader">
@@ -291,9 +280,7 @@
</choice>
</attribute>
</optional>
<optional>
<ref name="absFilePath"/>
</optional>
<ref name="absFilePath"/>
</element>
</optional>
<optional>
@@ -353,15 +340,13 @@
<attribute name="machine">
<choice>
<value>xenpv</value>
<value>xenfv</value>
<value>xenpvh</value>
<value>xenner</value>
</choice>
</attribute>
</optional>
<choice>
<value>xen</value>
<value>linux</value>
<value>xenpvh</value>
</choice>
</element>
</define>
@@ -670,7 +655,6 @@
<choice>
<value>file</value>
<value>anonymous</value>
<value>memfd</value>
</choice>
</attribute>
</element>
@@ -972,7 +956,7 @@
<attribute name="vcpus">
<ref name='cpuset'/>
</attribute>
<zeroOrMore>
<oneOrMore>
<element name="cache">
<attribute name="id">
<ref name='unsignedInt'/>
@@ -996,33 +980,6 @@
</attribute>
</optional>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="monitor">
<attribute name="level">
<ref name='unsignedInt'/>
</attribute>
<attribute name="vcpus">
<ref name='cpuset'/>
</attribute>
</element>
</zeroOrMore>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="memorytune">
<attribute name="vcpus">
<ref name='cpuset'/>
</attribute>
<oneOrMore>
<element name="node">
<attribute name="id">
<ref name='unsignedInt'/>
</attribute>
<attribute name="bandwidth">
<ref name='unsignedInt'/>
</attribute>
</element>
</oneOrMore>
</element>
</zeroOrMore>
@@ -1519,15 +1476,6 @@
</interleave>
</group>
</choice>
<optional>
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
</attribute>
</optional>
<optional>
<ref name="snapshot"/>
</optional>
@@ -1580,14 +1528,6 @@
</optional>
</define>
<define name="diskSourceCommon">
<optional>
<attribute name="index">
<ref name="positiveInteger"/>
</attribute>
</optional>
</define>
<define name="diskSource">
<choice>
<ref name="diskSourceFile"/>
@@ -1611,7 +1551,6 @@
<ref name="absFilePath"/>
</attribute>
</optional>
<ref name="diskSourceCommon"/>
<optional>
<ref name="storageStartupPolicy"/>
</optional>
@@ -1636,7 +1575,6 @@
<ref name="absFilePath"/>
</attribute>
</optional>
<ref name="diskSourceCommon"/>
<optional>
<ref name="storageStartupPolicy"/>
</optional>
@@ -1662,7 +1600,6 @@
<attribute name="dir">
<ref name="absFilePath"/>
</attribute>
<ref name="diskSourceCommon"/>
<optional>
<ref name="storageStartupPolicy"/>
</optional>
@@ -1716,7 +1653,6 @@
<attribute name="protocol">
<value>rbd</value>
</attribute>
<ref name="diskSourceCommon"/>
<optional>
<attribute name="name"/>
</optional>
@@ -1756,7 +1692,6 @@
<value>iscsi</value>
</attribute>
<attribute name="name"/>
<ref name="diskSourceCommon"/>
<ref name="diskSourceNetworkHost"/>
<optional>
<ref name="diskAuth"/>
@@ -1764,9 +1699,6 @@
<optional>
<ref name="encryption"/>
</optional>
<optional>
<ref name="initiatorinfo"/>
</optional>
</element>
</define>
@@ -1779,7 +1711,6 @@
</choice>
</attribute>
<attribute name="name"/>
<ref name="diskSourceCommon"/>
<ref name="diskSourceNetworkHost"/>
<optional>
<ref name="encryption"/>
@@ -1798,7 +1729,6 @@
</choice>
</attribute>
<attribute name="name"/>
<ref name="diskSourceCommon"/>
<ref name="diskSourceNetworkHost"/>
<optional>
<ref name="encryption"/>
@@ -1819,7 +1749,6 @@
<ref name="virYesNo"/>
</attribute>
</optional>
<ref name="diskSourceCommon"/>
<ref name="diskSourceNetworkHost"/>
<optional>
<ref name="encryption"/>
@@ -1833,7 +1762,6 @@
<value>gluster</value>
</attribute>
<attribute name="name"/>
<ref name="diskSourceCommon"/>
<oneOrMore>
<ref name="diskSourceNetworkHost"/>
</oneOrMore>
@@ -1851,7 +1779,6 @@
</choice>
</attribute>
<attribute name="name"/>
<ref name="diskSourceCommon"/>
<optional>
<attribute name="tls">
<ref name="virYesNo"/>
@@ -1896,7 +1823,6 @@
</choice>
</attribute>
</optional>
<ref name="diskSourceCommon"/>
<optional>
<ref name="storageStartupPolicy"/>
</optional>
@@ -1929,7 +1855,7 @@
<value>virtio</value>
<value>xen</value>
<value>usb</value>
<value>uml</value> <!-- NOT USED ANYMORE -->
<value>uml</value>
<value>sata</value>
<value>sd</value>
</choice>
@@ -2166,8 +2092,6 @@
<value>ibmvscsi</value>
<value>virtio-scsi</value>
<value>lsisas1078</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
</attribute>
</optional>
@@ -2325,15 +2249,6 @@
<attribute name="type">
<value>virtio-serial</value>
</attribute>
<optional>
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="ports">
<ref name="unsignedInt"/>
@@ -2345,17 +2260,6 @@
</attribute>
</optional>
</group>
<!-- xenbus has an optional attribute "maxGrantFrames" -->
<group>
<attribute name="type">
<value>xenbus</value>
</attribute>
<optional>
<attribute name="maxGrantFrames">
<ref name="unsignedInt"/>
</attribute>
</optional>
</group>
</choice>
<optional>
<element name="driver">
@@ -2534,15 +2438,6 @@
</element>
</optional>
</interleave>
<optional>
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
</attribute>
</optional>
</element>
</define>
<define name="fsDriver">
@@ -2818,7 +2713,7 @@
<ref name="usbAddr"/>
</attribute>
<attribute name="device">
<ref name="usbAddr"/>
<ref name="usbPort"/>
</attribute>
</group>
</choice>
@@ -3471,20 +3366,6 @@
</attribute>
</optional>
</group>
<group>
<attribute name="type">
<value>egl-headless</value>
</attribute>
<optional>
<element name="gl">
<optional>
<attribute name="rendernode">
<ref name="absFilePath"/>
</attribute>
</optional>
</element>
</optional>
</group>
</choice>
</element>
</define>
@@ -3570,7 +3451,6 @@
<value>vbox</value>
<value>virtio</value>
<value>gop</value>
<value>none</value>
</choice>
</attribute>
<group>
@@ -3778,7 +3658,7 @@
<choice>
<value>xen</value>
<value>serial</value>
<value>uml</value> <!-- NOT USED ANYMORE -->
<value>uml</value>
<value>virtio</value>
<value>lxc</value>
<value>openvz</value>
@@ -3810,7 +3690,6 @@
<value>pci-serial</value>
<value>spapr-vty</value>
<value>pl011</value>
<value>16550a</value>
<value>sclpconsole</value>
<value>sclplmconsole</value>
</choice>
@@ -4125,8 +4004,6 @@
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
<value>xen</value>
<value>none</value>
</choice>
@@ -4336,11 +4213,7 @@
<element name="vsock">
<optional>
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
<value>virtio</value>
</attribute>
</optional>
<interleave>
@@ -4361,9 +4234,6 @@
<optional>
<ref name="address"/>
</optional>
<optional>
<ref name="alias"/>
</optional>
</interleave>
</element>
</define>
@@ -4441,15 +4311,6 @@
</element>
</group>
</choice>
<optional>
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
</attribute>
</optional>
<optional>
<ref name="alias"/>
</optional>
@@ -4686,15 +4547,6 @@
<attribute name="type">
<value>scsi_host</value>
</attribute>
<optional>
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
</attribute>
</optional>
<element name="source">
<choice>
<group>
@@ -4719,14 +4571,8 @@
<choice>
<value>vfio-pci</value>
<value>vfio-ccw</value>
<value>vfio-ap</value>
</choice>
</attribute>
<optional>
<attribute name="display">
<ref name="virOnOff"/>
</attribute>
</optional>
<element name="source">
<ref name="mdevaddress"/>
</element>
@@ -4786,7 +4632,7 @@
<ref name="usbAddr"/>
</attribute>
<attribute name="device">
<ref name="usbAddr"/>
<ref name="usbPort"/>
</attribute>
</element>
</define>
@@ -5061,19 +4907,6 @@
<optional>
<ref name="vmcoreinfo"/>
</optional>
<optional>
<element name="htm">
<ref name="featurestate"/>
</element>
</optional>
<optional>
<element name="nested-hv">
<ref name="featurestate"/>
</element>
</optional>
<optional>
<ref name="msrs"/>
</optional>
</interleave>
</element>
</optional>
@@ -5322,17 +5155,6 @@
</element>
</define>
<define name="msrs">
<element name="msrs">
<attribute name="unknown">
<choice>
<value>ignore</value>
<value>fault</value>
</choice>
</attribute>
</element>
</define>
<define name="address">
<element name="address">
<choice>
@@ -5341,7 +5163,6 @@
<value>pci</value>
</attribute>
<ref name="pciaddress"/>
<ref name="zpciaddress"/>
</group>
<group>
<attribute name="type">
@@ -5475,21 +5296,9 @@
</interleave>
</group>
<group>
<interleave>
<element name="path">
<ref name="absFilePath"/>
</element>
<optional>
<element name="alignsize">
<ref name="scaledInteger"/>
</element>
</optional>
<optional>
<element name="pmem">
<empty/>
</element>
</optional>
</interleave>
<element name="path">
<ref name="absFilePath"/>
</element>
</group>
</choice>
</element>
@@ -5513,11 +5322,6 @@
</element>
</element>
</optional>
<optional>
<element name="readonly">
<empty/>
</element>
</optional>
</interleave>
</element>
</define>
@@ -5525,11 +5329,7 @@
<define name="rng">
<element name="rng">
<attribute name="model">
<choice>
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
</choice>
<value>virtio</value>
</attribute>
<interleave>
<ref name="rng-backend"/>
@@ -5593,8 +5393,6 @@
<attribute name="iommu">
<ref name="virOnOff"/>
</attribute>
</optional>
<optional>
<attribute name="ats">
<ref name="virOnOff"/>
</attribute>
@@ -5898,31 +5696,6 @@
</optional>
</element>
</optional>
<optional>
<element name="frequencies">
<ref name="featurestate"/>
</element>
</optional>
<optional>
<element name="reenlightenment">
<ref name="featurestate"/>
</element>
</optional>
<optional>
<element name="tlbflush">
<ref name="featurestate"/>
</element>
</optional>
<optional>
<element name="ipi">
<ref name="featurestate"/>
</element>
</optional>
<optional>
<element name="evmcs">
<ref name="featurestate"/>
</element>
</optional>
</interleave>
</element>
</define>
@@ -6222,20 +5995,6 @@
</element>
</define>
<!--
Optional hypervisor extensions in their own namespace:
Bhyve
-->
<define name="bhyvecmdline">
<element name="commandline" ns="http://libvirt.org/schemas/domain/bhyve/1.0">
<zeroOrMore>
<element name="arg">
<attribute name='value'/>
</element>
</zeroOrMore>
</element>
</define>
<!--
Type library
-->

View File

@@ -58,12 +58,6 @@
</attribute>
</optional>
<optional>
<attribute name="zone">
<ref name="zoneName"/>
</attribute>
</optional>
<optional>
<attribute name="stp">
<ref name="virOnOff"/>

View File

@@ -133,13 +133,6 @@
<value>pci</value>
</attribute>
<optional>
<element name='class'>
<data type="string">
<param name="pattern">0x[0-9a-fA-F]{6}</param>
</data>
</element>
</optional>
<element name='domain'>
<ref name='unsignedLong'/>
</element>

View File

@@ -24,7 +24,9 @@
</choice>
</attribute>
<interleave>
<ref name='secret'/>
<zeroOrMore>
<ref name='secret'/>
</zeroOrMore>
<optional>
<element name='cipher'>
<ref name='keycipher'/>
@@ -37,17 +39,6 @@
</element>
</define>
<define name='initiatorinfo'>
<element name='initiator'>
<element name='iqn'>
<attribute name='name'>
<text/>
</attribute>
<empty/>
</element>
</element>
</define>
<define name="reconnect">
<element name="reconnect">
<attribute name="enabled">
@@ -236,11 +227,4 @@
</optional>
</define>
<define name='refreshVolumeAllocation'>
<choice>
<value>default</value>
<value>capacity</value>
</choice>
</define>
</grammar>

View File

@@ -18,7 +18,6 @@
<ref name='poollogical'/>
<ref name='pooldisk'/>
<ref name='pooliscsi'/>
<ref name='pooliscsidirect'/>
<ref name='poolscsi'/>
<ref name='poolmpath'/>
<ref name='poolrbd'/>
@@ -52,9 +51,6 @@
<ref name='sourcefs'/>
<ref name='target'/>
</interleave>
<optional>
<ref name='fs_mount_opts'/>
</optional>
</define>
<define name='poolnetfs'>
@@ -67,9 +63,6 @@
<ref name='sourcenetfs'/>
<ref name='target'/>
</interleave>
<optional>
<ref name='fs_mount_opts'/>
</optional>
</define>
<define name='poollogical'>
@@ -108,19 +101,6 @@
</interleave>
</define>
<define name='pooliscsidirect'>
<attribute name='type'>
<value>iscsi-direct</value>
</attribute>
<interleave>
<ref name='commonmetadata'/>
<optional>
<ref name='sizing'/>
</optional>
<ref name='sourceiscsidirect'/>
</interleave>
</define>
<define name='poolscsi'>
<attribute name='type'>
<value>scsi</value>
@@ -155,11 +135,7 @@
<ref name='commonMetadataNameOptional'/>
<ref name='sizing'/>
<ref name='sourcerbd'/>
<ref name='refresh'/>
</interleave>
<optional>
<ref name='rbd_config_opts'/>
</optional>
</define>
<define name='poolsheepdog'>
@@ -338,11 +314,14 @@
</element>
</define>
<define name='sourceinfodeviscsidirect'>
<element name='device'>
<attribute name='path'>
<ref name='IscsiQualifiedName'/>
</attribute>
<define name='initiatorinfo'>
<element name='initiator'>
<element name='iqn'>
<attribute name='name'>
<text/>
</attribute>
<empty/>
</element>
</element>
</define>
@@ -541,13 +520,6 @@
<ref name='sourceinfohost'/>
<ref name='sourceinfodir'/>
<ref name='sourcefmtnetfs'/>
<optional>
<element name='protocol'>
<attribute name='ver'>
<ref name='unsignedInt'/>
</attribute>
</element>
</optional>
<optional>
<ref name='sourceinfovendor'/>
</optional>
@@ -623,19 +595,6 @@
</element>
</define>
<define name='sourceiscsidirect'>
<element name='source'>
<interleave>
<ref name='sourceinfohost'/>
<ref name='sourceinfodeviscsidirect'/>
<ref name='initiatorinfo'/>
<optional>
<ref name='sourceinfoauth'/>
</optional>
</interleave>
</element>
</define>
<define name='sourcescsi'>
<element name='source'>
<interleave>
@@ -692,63 +651,4 @@
</data>
</define>
<define name='refresh'>
<optional>
<element name='refresh'>
<interleave>
<ref name='refreshVolume'/>
</interleave>
</element>
</optional>
</define>
<define name='refreshVolume'>
<optional>
<element name='volume'>
<optional>
<attribute name='allocation'>
<ref name="refreshVolumeAllocation"/>
</attribute>
</optional>
</element>
</optional>
</define>
<!--
Optional storage pool extensions in their own namespace:
"fs" or "netfs"
-->
<define name="fs_mount_opts">
<element name="mount_opts" ns="http://libvirt.org/schemas/storagepool/fs/1.0">
<zeroOrMore>
<element name="option">
<attribute name='name'>
<text/>
</attribute>
</element>
</zeroOrMore>
</element>
</define>
<!--
Optional storage pool extensions in their own namespace:
RBD
-->
<define name="rbd_config_opts">
<element name="config_opts" ns="http://libvirt.org/schemas/storagepool/rbd/1.0">
<zeroOrMore>
<element name="option">
<attribute name='name'>
<text/>
</attribute>
<attribute name='value'>
<text/>
</attribute>
</element>
</zeroOrMore>
</element>
</define>
</grammar>

View File

@@ -1,88 +0,0 @@
<?xml version="1.0"?>
<!-- A Relax NG schema for the libvirt storage pool capabilities XML format -->
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<include href='basictypes.rng'/>
<start>
<ref name='storagepoolCapabilities'/>
</start>
<define name='storagepoolCapabilities'>
<element name='storagepoolCapabilities'>
<zeroOrMore>
<ref name='poolCapsType'/>
</zeroOrMore>
</element>
</define>
<define name='poolCapsType'>
<element name='pool'>
<ref name='poolCapsTypes'/>
<ref name='poolCapsSupported'/>
<optional>
<ref name='poolCapsPoolOptions'/>
</optional>
<optional>
<ref name='poolCapsVolOptions'/>
</optional>
</element>
</define>
<define name='poolCapsTypes'>
<attribute name='type'>
<text/>
</attribute>
</define>
<define name='poolCapsSupported'>
<attribute name='supported'>
<ref name="virYesNo"/>
</attribute>
</define>
<define name='poolCapsPoolOptions'>
<element name='poolOptions'>
<optional>
<ref name='poolDefaultFormat'/>
</optional>
<optional>
<ref name='poolCapsEnum'/>
</optional>
</element>
</define>
<define name='poolCapsVolOptions'>
<element name='volOptions'>
<ref name='poolDefaultFormat'/>
<ref name='poolCapsEnum'/>
</element>
</define>
<define name='poolDefaultFormat'>
<element name='defaultFormat'>
<attribute name='type'>
<text/>
</attribute>
</element>
</define>
<define name='poolCapsEnum'>
<zeroOrMore>
<element name='enum'>
<attribute name='name'>
<text/>
</attribute>
<ref name='value'/>
</element>
</zeroOrMore>
</define>
<define name='value'>
<zeroOrMore>
<element name='value'>
<text/>
</element>
</zeroOrMore>
</define>
</grammar>

View File

@@ -139,7 +139,6 @@
</element>
<ref name='format'/>
<ref name='permissions'/>
<ref name='timestamps'/>
</interleave>
</element>
</define>

View File

@@ -310,7 +310,7 @@
on the size and placement of volumes. The 'free extents'
information will detail the regions which are available for creating
new volumes. A volume cannot span across 2 different free extents.
It will default to using <code>dos</code> as the pool source format.
It will default to using <code>msdos</code> as the pool source format.
</p>
<h3>Example pool input</h3>
@@ -357,10 +357,8 @@
</li>
</ul>
<p>
The formats <code>dos</code> ("msdos" in parted terminology,
good for BIOS systems) or <code>gpt</code> (good for UEFI
systems) are recommended for best portability - the latter is
needed for disks larger than 2TB.
The <code>dos</code> or <code>gpt</code> formats are recommended for
best portability - the latter is needed for disks larger than 2TB.
</p>
<h3>Valid volume format types</h3>
@@ -435,36 +433,6 @@
The iSCSI volume pool does not use the volume format type element.
</p>
<h2><a id="StorageBackendISCSIDirect">iSCSI direct pool</a></h2>
<p>
This is a variant of the iSCSI pool. Instead of using iscsiadm, it uses
libiscsi.
It requires a host, a path which is the target IQN, and an initiator IQN.
</p>
<h3>Example pool input</h3>
<pre>
&lt;pool type="iscsi-direct"&gt;
&lt;name&gt;virtimages&lt;/name&gt;
&lt;source&gt;
&lt;host name="iscsi.example.com"/&gt;
&lt;device path="iqn.2013-06.com.example:iscsi-pool"/&gt;
&lt;initiator&gt;
&lt;iqn name="iqn.2013-06.com.example:iscsi-initiator"/&gt;
&lt;/initiator&gt;
&lt;/source&gt;
&lt;/pool&gt;</pre>
<h3>Valid pool format types</h3>
<p>
The iSCSI direct volume pool does not use the pool format type element.
</p>
<h3>Valid volume format types</h3>
<p>
The iSCSI direct volume pool does not use the volume format type element.
</p>
<h2><a id="StorageBackendSCSI">SCSI pool</a></h2>
<p>
This provides a pool based on a SCSI HBA. Volumes are preexisting SCSI
@@ -782,7 +750,7 @@
The ZFS volume pool does not use the pool format type element.
</p>
<h3>Valid volume format types</h3>
<h3>Valid pool format types</h3>
<p>
The ZFS volume pool does not use the volume format type element.
</p>
@@ -810,12 +778,6 @@
&lt;path&gt;/mnt/clustername&lt;/path&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
<h3>Valid pool format types</h3>
<p>
The Vstorage volume pool does not use the pool format type element.
</p>
<h3>Valid volume format types</h3>
<p>The valid volume types are the same as for the directory pool.</p>
</body>

View File

@@ -19,6 +19,12 @@
FILTERS = $(wildcard $(srcdir)/xml/nwfilter/*.xml)
EXTRA_DIST = \
apparmor/TEMPLATE.qemu \
apparmor/TEMPLATE.lxc \
apparmor/libvirt-qemu \
apparmor/libvirt-lxc \
apparmor/usr.lib.libvirt.virt-aa-helper \
apparmor/usr.sbin.libvirtd \
lxcconvert/virt-lxc-convert \
polkit/libvirt-acl.rules \
$(wildcard $(srcdir)/systemtap/*.stp) \
@@ -27,10 +33,10 @@ EXTRA_DIST = \
$(wildcard $(srcdir)/xml/test/*.xml)
AM_CPPFLAGS = \
-I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)
LDADD = $(STATIC_BINARIES) $(WARN_CFLAGS) \
$(top_builddir)/src/libvirt.la \
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir) \
-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib
LDADD = $(STATIC_BINARIES) $(WARN_CFLAGS) $(COVERAGE_LDFLAGS) \
$(top_builddir)/src/libvirt.la $(top_builddir)/gnulib/lib/libgnu.la \
$(top_builddir)/src/libvirt-admin.la
noinst_PROGRAMS=dominfo/info1 dommigrate/dommigrate domsuspend/suspend \
@@ -64,6 +70,36 @@ admin_logging_SOURCES = admin/logging.c
INSTALL_DATA_LOCAL =
UNINSTALL_LOCAL =
if WITH_APPARMOR_PROFILES
apparmordir = $(sysconfdir)/apparmor.d/
apparmor_DATA = \
apparmor/usr.lib.libvirt.virt-aa-helper \
apparmor/usr.sbin.libvirtd \
$(NULL)
abstractionsdir = $(apparmordir)/abstractions
abstractions_DATA = \
apparmor/libvirt-qemu \
apparmor/libvirt-lxc \
$(NULL)
templatesdir = $(apparmordir)/libvirt
templates_DATA = \
apparmor/TEMPLATE.qemu \
apparmor/TEMPLATE.lxc \
$(NULL)
APPARMOR_LOCAL_DIR = "$(DESTDIR)$(apparmordir)/local"
install-apparmor-local:
$(MKDIR_P) "$(APPARMOR_LOCAL_DIR)"
echo "# Site-specific additions and overrides for \
'usr.lib.libvirt.virt-aa-helper'" \
>$(APPARMOR_LOCAL_DIR)/usr.lib.libvirt.virt-aa-helper
INSTALL_DATA_LOCAL += install-apparmor-local
UNINSTALL_LOCAL += uninstall-apparmor-local
endif WITH_APPARMOR_PROFILES
if WITH_NWFILTER
NWFILTER_DIR = "$(DESTDIR)$(sysconfdir)/libvirt/nwfilter"

View File

@@ -1,7 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <libvirt/libvirt.h>
#include <libvirt/libvirt-admin.h>
#include<stdio.h>
#include<stdlib.h>
#include<libvirt/libvirt.h>
#include<libvirt/libvirt-admin.h>
int main(void)
{

View File

@@ -1,9 +1,9 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <libvirt/libvirt-admin.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<libvirt/libvirt-admin.h>
static const char *
exampleTransportToString(int transport)
@@ -30,13 +30,9 @@ exampleGetTimeStr(time_t then)
{
char *ret = NULL;
struct tm timeinfo;
struct tm *timeinfop;
/* localtime_r() is smarter, but since mingw lacks it and this
* example is single-threaded, we can get away with localtime */
if (!(timeinfop = localtime(&then)))
if (!localtime_r(&then, &timeinfo))
return NULL;
timeinfo = *timeinfop;
if (!(ret = calloc(64, sizeof(char))))
return NULL;

View File

@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <libvirt/libvirt-admin.h>
#include<stdio.h>
#include<stdlib.h>
#include<libvirt/libvirt-admin.h>
int main(int argc, char **argv)
{

View File

@@ -1,7 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <libvirt/libvirt-admin.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<libvirt/libvirt-admin.h>
static const char *
exampleTransportToString(int transport)
@@ -28,13 +28,9 @@ exampleGetTimeStr(time_t then)
{
char *ret = NULL;
struct tm timeinfo;
struct tm *timeinfop;
/* localtime_r() is smarter, but since mingw lacks it and this
* example is single-threaded, we can get away with localtime */
if (!(timeinfop = localtime(&then)))
if (!localtime_r(&then, &timeinfo))
return NULL;
timeinfo = *timeinfop;
if (!(ret = calloc(64, sizeof(char))))
return NULL;

View File

@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <libvirt/libvirt-admin.h>
#include<stdio.h>
#include<stdlib.h>
#include<libvirt/libvirt-admin.h>
int main(void)
{

View File

@@ -1,10 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include <unistd.h>
#include <libvirt/libvirt-admin.h>
#include <libvirt/virterror.h>
#include "config.h"
#include<unistd.h>
#include<libvirt/libvirt-admin.h>
#include<libvirt/virterror.h>
static void printHelp(const char *argv0)
{

View File

@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <libvirt/libvirt-admin.h>
#include<stdio.h>
#include<stdlib.h>
#include<libvirt/libvirt-admin.h>
int main(int argc, char **argv)
{

View File

@@ -16,15 +16,14 @@
network inet stream,
network inet6 stream,
ptrace (readby, tracedby) peer=libvirtd,
ptrace (readby, tracedby) peer=/usr/sbin/libvirtd,
signal (receive) peer=libvirtd,
signal (receive) peer=/usr/sbin/libvirtd,
/dev/net/tun rw,
/dev/kvm rw,
/dev/ptmx rw,
/dev/kqemu rw,
@{PROC}/*/status r,
# When qemu is signaled to terminate, it will read cmdline of signaling
# process for reporting purposes. Allowing read access to a process
@@ -181,19 +180,6 @@
# for rbd
/etc/ceph/ceph.conf r,
# Various functions will need to enumerate /tmp (e.g. ceph), allow the base
# dir and a few known functions like samba support.
# We want to avoid to give blanket rw permission to everything under /tmp,
# users are expected to add site specific addons for more uncommon cases.
# Qemu processes usually all run as the same users, so the "owner"
# restriction prevents access to other services files, but not across
# different instances.
# This is a tradeoff between usability and security - if paths would be more
# predictable that would be preferred - at least for write rules we would
# want more unique paths per rule.
/{,var/}tmp/ r,
owner /{,var/}tmp/**/ r,
# for file-posix getting limits since 9103f1ce
/sys/devices/**/block/*/queue/max_segments r,
@@ -202,9 +188,6 @@
@{PROC}/device-tree/** r,
/sys/firmware/devicetree/** r,
# allow connect with openGraphicsFD to work
unix (send, receive) type=stream addr=none peer=(label=/usr/sbin/libvirtd),
# for gathering information about available host resources
/sys/devices/system/cpu/ r,
/sys/devices/system/node/ r,

View File

@@ -19,9 +19,6 @@ profile virt-aa-helper /usr/{lib,lib64}/libvirt/virt-aa-helper {
/etc/libnl-3/classid r,
# for gl enabled graphics
/dev/dri/{,*} r,
# for hostdev
/sys/devices/ r,
/sys/devices/** r,
@@ -53,7 +50,7 @@ profile virt-aa-helper /usr/{lib,lib64}/libvirt/virt-aa-helper {
@{HOME}/** r,
/var/lib/libvirt/images/ r,
/var/lib/libvirt/images/** r,
/var/lib/nova/instances/_base/* r,
/var/lib/nova/instances/_base/* r
/{media,mnt,opt,srv}/** r,
# For virt-sandbox
/{,var/}run/libvirt/**/[sv]d[a-z] r,

View File

@@ -2,7 +2,7 @@
#include <tunables/global>
@{LIBVIRT}="libvirt"
profile libvirtd /usr/sbin/libvirtd flags=(attach_disconnected) {
/usr/sbin/libvirtd flags=(attach_disconnected) {
#include <abstractions/base>
#include <abstractions/dbus>
@@ -33,11 +33,17 @@ profile libvirtd /usr/sbin/libvirtd flags=(attach_disconnected) {
mount options=(rw,rslave) -> /,
mount options=(rw, nosuid) -> /{var/,}run/libvirt/qemu/*.dev/,
# libvirt provides any mounts under /dev to qemu namespaces
mount options=(rw, move) /dev/ -> /{,var/}run/libvirt/qemu/*.dev/,
mount options=(rw, move) /dev/** -> /{,var/}run/libvirt/qemu/*{,/},
mount options=(rw, move) /{,var/}run/libvirt/qemu/*.dev/ -> /dev/,
mount options=(rw, move) /{,var/}run/libvirt/qemu/*{,/} -> /dev/**,
mount options=(rw, move) /dev/ -> /{var/,}run/libvirt/qemu/*.dev/,
mount options=(rw, move) /dev/hugepages/ -> /{var/,}run/libvirt/qemu/*.hugepages/,
mount options=(rw, move) /dev/mqueue/ -> /{var/,}run/libvirt/qemu/*.mqueue/,
mount options=(rw, move) /dev/pts/ -> /{var/,}run/libvirt/qemu/*.pts/,
mount options=(rw, move) /dev/shm/ -> /{var/,}run/libvirt/qemu/*.shm/,
mount options=(rw, move) /{var/,}run/libvirt/qemu/*.dev/ -> /dev/,
mount options=(rw, move) /{var/,}run/libvirt/qemu/*.hugepages/ -> /dev/hugepages/,
mount options=(rw, move) /{var/,}run/libvirt/qemu/*.mqueue/ -> /dev/mqueue/,
mount options=(rw, move) /{var/,}run/libvirt/qemu/*.pts/ -> /dev/pts/,
mount options=(rw, move) /{var/,}run/libvirt/qemu/*.shm/ -> /dev/shm/,
network inet stream,
network inet dgram,
@@ -50,13 +56,11 @@ profile libvirtd /usr/sbin/libvirtd flags=(attach_disconnected) {
# for --p2p migrations
unix (send, receive) type=stream addr=none peer=(label=unconfined addr=none),
ptrace (read,trace) peer=unconfined,
ptrace (read,trace) peer=@{profile_name},
ptrace (read,trace) peer=dnsmasq,
ptrace (read,trace) peer=/usr/sbin/dnsmasq,
ptrace (read,trace) peer=libvirt-*,
ptrace (trace) peer=unconfined,
ptrace (trace) peer=/usr/sbin/libvirtd,
ptrace (trace) peer=/usr/sbin/dnsmasq,
ptrace (trace) peer=libvirt-*,
signal (send) peer=dnsmasq,
signal (send) peer=/usr/sbin/dnsmasq,
signal (read, send) peer=libvirt-*,
signal (send) set=("kill", "term") peer=unconfined,
@@ -65,14 +69,6 @@ profile libvirtd /usr/sbin/libvirtd flags=(attach_disconnected) {
unix (send, receive) type=stream addr=none peer=(label=/usr/sbin/libvirtd//qemu_bridge_helper),
signal (send) set=("term") peer=/usr/sbin/libvirtd//qemu_bridge_helper,
# allow connect with openGraphicsFD, direction reversed in newer versions
unix (send, receive) type=stream addr=none peer=(label=libvirt-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*),
# unconfined also required if guests run without security module
unix (send, receive) type=stream addr=none peer=(label=unconfined),
# required if guests run unconfined seclabel type='none' but libvirtd is confined
signal (read, send) peer=unconfined,
# Very lenient profile for libvirtd since we want to first focus on confining
# the guests. Guests will have a very restricted profile.
/ r,
@@ -123,7 +119,6 @@ profile libvirtd /usr/sbin/libvirtd flags=(attach_disconnected) {
# For communication/control from libvirtd
unix (send, receive) type=stream addr=none peer=(label=/usr/sbin/libvirtd),
signal (receive) set=("term") peer=/usr/sbin/libvirtd,
signal (receive) set=("term") peer=libvirtd,
/dev/net/tun rw,
/etc/qemu/** r,

View File

@@ -5,6 +5,7 @@
* hypervisor and extract domain information.
* usage: info1
* test: info1
* author: Daniel Veillard
* copy: see Copyright for the status of this software.
*/

View File

@@ -18,6 +18,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Sahid Orentino Ferdjaoui <sahid.ferdjaoui@cloudwatt.com>
*/
#include <stdio.h>
@@ -79,7 +81,8 @@ main(int argc, char *argv[])
cleanup:
if (dom != NULL)
virDomainFree(dom);
virConnectClose(conn);
if (conn != NULL)
virConnectClose(conn);
out:
return ret;

View File

@@ -17,8 +17,12 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Author: Michal Privoznik <mprivozn@redhat.com>
*/
#include <config.h>
#include <errno.h>
#include <getopt.h>
#include <libvirt/libvirt.h>

View File

@@ -16,8 +16,12 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Author: Michal Privoznik <mprivozn@redhat.com>
*/
#include <config.h>
#include <errno.h>
#include <getopt.h>
#include <libvirt/libvirt.h>
@@ -241,8 +245,7 @@ print_cpu_usage(const char *dom_name,
if (delim)
printf("\t");
/* mingw lacks %zu */
printf("CPU%u: %.2lf", (unsigned)(cpu + i), usage);
printf("CPU%zu: %.2lf", cpu + i, usage);
delim = true;
}
@@ -266,6 +269,10 @@ do_top(virConnectPtr conn,
int max_id = 0;
int nparams = 0, then_nparams = 0, now_nparams = 0;
virTypedParameterPtr then_params = NULL, now_params = NULL;
struct sigaction action_stop;
memset(&action_stop, 0, sizeof(action_stop));
action_stop.sa_handler = stop;
/* Lookup the domain */
if (!(dom = virDomainLookupByName(conn, dom_name))) {
@@ -291,10 +298,8 @@ do_top(virConnectPtr conn,
goto cleanup;
}
/* The ideal program would use sigaction to set this handler, but
* this way is portable to mingw. */
signal(SIGTERM, stop);
signal(SIGINT, stop);
sigaction(SIGTERM, &action_stop, NULL);
sigaction(SIGINT, &action_stop, NULL);
run_top = true;
while (run_top) {

View File

@@ -2,6 +2,8 @@
* hypervisor and gather a few bits of information about domains.
* Similar API's exist for storage pools, networks, and interfaces. */
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <libvirt/libvirt.h>

View File

@@ -17,6 +17,7 @@
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
# Author: Cedric Bosdonnat <cbosdonnat@suse.com>
handler_cleanup()
{

View File

@@ -1,9 +1,13 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <inttypes.h>
#include <verify.h>
#define VIR_ENUM_SENTINELS
#include <libvirt/libvirt.h>
@@ -13,14 +17,6 @@
#define STREQ(a, b) (strcmp(a, b) == 0)
#define NULLSTR(s) ((s) ? (s) : "<null>")
#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
&& (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \
&& !defined __cplusplus)
# define verify(cond) _Static_assert(cond, "verify (" #cond ")")
#else
# define verify(cond)
#endif
#ifndef ATTRIBUTE_UNUSED
# define ATTRIBUTE_UNUSED __attribute__((__unused__))
#endif
@@ -948,11 +944,10 @@ myDomainEventBlockThresholdCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
unsigned long long excess,
void *opaque ATTRIBUTE_UNUSED)
{
/* Casts to uint64_t to work around mingw not knowing %lld */
printf("%s EVENT: Domain %s(%d) block threshold callback dev '%s'(%s), "
"threshold: '%" PRIu64 "', excess: '%" PRIu64 "'",
"threshold: '%llu', excess: '%llu'",
__func__, virDomainGetName(dom), virDomainGetID(dom),
dev, NULLSTR(path), (uint64_t)threshold, (uint64_t)excess);
dev, NULLSTR(path), threshold, excess);
return 0;
}
@@ -1147,8 +1142,13 @@ main(int argc, char **argv)
virConnectPtr dconn = NULL;
int callback1ret = -1;
int callback16ret = -1;
struct sigaction action_stop;
size_t i;
memset(&action_stop, 0, sizeof(action_stop));
action_stop.sa_handler = stop;
if (argc > 1 && STREQ(argv[1], "--help")) {
printf("%s uri\n", argv[0]);
goto cleanup;
@@ -1179,10 +1179,8 @@ main(int argc, char **argv)
goto cleanup;
}
/* The ideal program would use sigaction to set this handler, but
* this way is portable to mingw. */
signal(SIGTERM, stop);
signal(SIGINT, stop);
sigaction(SIGTERM, &action_stop, NULL);
sigaction(SIGINT, &action_stop, NULL);
printf("Registering event callbacks\n");

View File

@@ -1,6 +1,8 @@
/* This is a copy of the hellolibvirt example demonstaring how to use
* virConnectOpenAuth with a custom auth callback */
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -16,6 +16,7 @@
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
# Author: Daniel P. Berrange <berrange@redhat.com>
#
# This script will monitor all operation of the libvirt event loop
# in both client and server. Example output is:

View File

@@ -11,11 +11,12 @@
# Document usage with uninstalled daemon and libs. Assuming CWD is toplevel
# source git directory, it should be only slight modification to the following:
#
# ./run stap --ldd -c src/libvirtd -d src/libvirtd
# ./run stap --ldd -c daemon/libvirtd -d daemon/libvirtd
# examples/systemtap/lock-debug.stp src/.libs/libvirt.so
#
# Debug RWLock mechanisms as well.
#
# Author: Martin Kletzander <mkletzan@redhat.com>
global mx_tolock

Some files were not shown because too many files have changed in this diff Show More