1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-10-01 21:46:35 +03:00

Compare commits

..

15 Commits

Author SHA1 Message Date
Ján Tomko
be5d96d547 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 10:26:35 +02:00
Ján Tomko
980109c41c 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 10:26:35 +02:00
Pavel Hrdina
84d35ef500 maint: fix syntax-check sc_prohibit_int_ijk exclude rule
Fix the regex for excluding files for this syntax-rule.  The rule "include/"
will not work, because we are matching the whole line like this
"^(...|include/|...)$ so we need to use "include/libvirt/libvirt.+".  The second
issue is that we are using only one '$' but there should be two of those at the
end.  The last small adjustment is to escape dots '.' so it match only dot.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit a94efa50e2)
2016-10-03 18:11:26 +02:00
Eric Blake
b25ca8143a build: accomodate selinux 2.5 header API change
Yet again, selinux has been adding const-correctness; this change
is ABI-compatible, but breaks API, which affects us when we try to
override things in our testsuite:

../../tests/securityselinuxhelper.c:307:24: error: conflicting types for 'selabel_open'
 struct selabel_handle *selabel_open(unsigned int backend,
                        ^~~~~~~~~~~~
In file included from ../../tests/securityselinuxhelper.c:32:0:
/usr/include/selinux/label.h:73:24: note: previous declaration of 'selabel_open' was here

The problem is a new 'const' prior to the second parameter.

Fix it the same way we did in commit 292d3f2d: check for the new
const at configure time.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 5ea3a690a2)
2016-10-03 18:10:17 +02:00
Pavel Hrdina
ec7040c000 build: add GCC 6.0 -Wlogical-op workaround
fdstream.c: In function 'virFDStreamWrite':
fdstream.c:390:29: error: logical 'or' of equal expressions [-Werror=logical-op]
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
                            ^~

Fedora rawhide now uses gcc 6.0 and there is a bug with -Wlogical-op
producing false warnings.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69602

Use GCC pragma push/pop and ignore -Wlogical-op for GCC that supports
push/pop pragma and also has this bug.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit d713a6b120)
2016-10-03 18:10:15 +02:00
Michal Privoznik
6a293aa29e Initialize couple of variables.
While trying to build with -Os couple of compile errors showed
up.

conf/domain_conf.c: In function 'virDomainChrRemove':
conf/domain_conf.c:13666:24: error: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     virDomainChrDefPtr ret, **arrPtr = NULL;
                        ^
Compiler fails to see that @ret is used only if set in the loop,
but whatever, there's no harm in initializing the variable.

In vboxAttachDrivesNew and _vboxAttachDrivesOld compiler thinks
that @rc may be used uninitialized. Well, not directly, but maybe
after some optimization. Yet again, no harm in initializing a
variable.

In file included from ./util/virthread.h:26:0,
                 from ./datatypes.h:28,
                 from vbox/vbox_tmpl.c:43,
                 from vbox/vbox_V3_1.c:37:
vbox/vbox_tmpl.c: In function '_vboxAttachDrivesOld':
./util/virerror.h:181:5: error: 'rc' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,              \
     ^
In file included from vbox/vbox_V3_1.c:37:0:
vbox/vbox_tmpl.c:1041:14: note: 'rc' was declared here
     nsresult rc;
              ^
Yet again, one uninitialized variable:

qemu/qemu_driver.c: In function 'qemuDomainBlockCommit':
qemu/qemu_driver.c:17194:9: error: 'baseSource' may be used uninitialized in this function [-Werror=maybe-uninitialized]
         qemuDomainPrepareDiskChainElement(driver, vm, baseSource,
         ^

And another one:

storage/storage_backend_logical.c: In function 'virStorageBackendLogicalMatchPoolSource.isra.2':
storage/storage_backend_logical.c:618:33: error: 'thisSource' may be used uninitialized in this function [-Werror=maybe-uninitialized]
                       thisSource->devices[j].path))
                                 ^

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit bde6e002b5)
2016-10-03 18:10:13 +02:00
Marc Hartmayer
598845b4f6 util: bitmap: clarify virBitmapLastSetBit() behavior for empty bitmaps
Before the variable 'bits' was initialized with 0 (commit
3470cd860d), the following bug was
possible.

A function call with an empty bitmap leads to undefined
behavior. Because if 'bitmap->map_len == 0' 'unusedBits' will be <= 0
and 'sz == 1'. So the non global and non static variable 'bits' would
have never been set. Consequently the check 'bits == 0' results in
undefined behavior.

This patch clarifies the current version of the function by handling the
empty bitmap explicitly. Also, for an empty bitmap there is obviously no
bit set so we can just return -1 (indicating no bit set) right away. The
explicit check for 'bits == 0' after the loop is unnecessary because we
only get to this point if no set bit was found.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com>
Reviewed-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.vnet.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
(cherry picked from commit 7cd01a248b)
2016-10-03 18:10:10 +02:00
Martin Kletzander
5f71b6ed14 Fix building with -Og
When building using -Og, gcc sees that some variables can be used
uninitialized  It can be debatable whether it is possible with our
codeflow, but functions should be self-contained and initializations are
always good.  The return instead of goto is due to actualType being used
in the cleanup.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 3470cd860d)
2016-10-03 18:10:09 +02:00
Martin Kletzander
7ed7246b4c qemu: Only use memory-backend-file with NUMA if needed
If this reminds you of a commit message from around a year ago, it's
41c2aa729f and yes, we're dealing with
"the same thing" again.  Or f309db1f4d and
it's similar.

There is a logic in place that if there is no real need for
memory-backend-file, qemuBuildMemoryBackendStr() returns 0.  However
that wasn't the case with hugepage backing.  The reason for that was
that we abused the 'pagesize' variable for storing that information, but
we should rather have a separate one that specifies whether we really
need the new object for hugepage backing.  And that variable should be
set only if this particular NUMA cell needs special treatment WRT
hugepages.

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

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 4372a7845acbc6974f6027ef68e7dd3eeb47f425)
2016-10-03 18:10:05 +02:00
Jiri Denemark
2d5370eba6 qemu: Let empty default VNC password work as documented
CVE-2016-5008

Setting an empty graphics password is documented as a way to disable
VNC/SPICE access, but QEMU does not always behaves like that. VNC would
happily accept the empty password. Let's enforce the behavior by setting
password expiration to "now".

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

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bb848feec0)
2016-06-30 12:08:49 +01:00
Martin Kletzander
73c3997f0f qemu: Don't crash when create fails early
Since commit 7140807917 we are generating
socket path later than before -- when starting a domain.  That makes one
particular inconsistent state of a chardev, which was not possible
before, currently valid.  However, SELinux security driver forgot to
guard the main restoring function by a check for NULL-paths.  So make it
no-op for NULL paths, as in the DAC driver.

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

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 1794a0103a)
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2016-02-03 11:11:43 +01:00
Michal Privoznik
f464e07f21 include: Handle case when builddir == srcdir
In my previous commit a70f3b1c77 I've tried to fix case
when building from VPATH and a file wasn't being installed.
However, my fix broke non-VPATH build.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 0d0e41a719)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-02-02 09:59:57 +01:00
Michal Privoznik
d8cc67931c includes: Install libvirt-common.h
The libvirt-common.h is build time generated file from .in.
Obviously, it's generated into builddir and not srcdir. Problem
is, the list of header files to install, virinc_HEADERS contains
only $(srcdir)/*.h and this misses libvirt-common.h. This problem
is pretty obvious when doing a VPATH build.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit a70f3b1c77)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-02-01 11:35:47 +01:00
Michal Privoznik
bce46d6a89 virLogManagerDomainReadLogFile: Don't do dummy allocs
Since we pass dummy variables @fdout and @fdoutlen into
virNetClientProgramCall() we make it alloc @fdout array (even
though it's an array of 0 elements since vitlogd can hardly pass
us some FDs at this stage). Nevertheless, it's an allocation not
followed by free():

==29385== 0 bytes in 60 blocks are definitely lost in loss record 2 of 1,009
==29385==    at 0x4C2C070: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==29385==    by 0x54B99EF: virAllocN (viralloc.c:191)
==29385==    by 0x56821B1: virNetClientProgramCall (virnetclientprogram.c:359)
==29385==    by 0x563B304: virLogManagerDomainReadLogFile (log_manager.c:272)
==29385==    by 0x217CD613: qemuDomainLogContextRead (qemu_domain.c:2485)
==29385==    by 0x217EDC76: qemuProcessReadLog (qemu_process.c:1660)
==29385==    by 0x217EDE1D: qemuProcessReportLogError (qemu_process.c:1696)
==29385==    by 0x217EE8C1: qemuProcessWaitForMonitor (qemu_process.c:1957)
==29385==    by 0x217F6636: qemuProcessLaunch (qemu_process.c:4955)
==29385==    by 0x217F71A4: qemuProcessStart (qemu_process.c:5152)
==29385==    by 0x21846582: qemuDomainObjStart (qemu_driver.c:7396)
==29385==    by 0x218467DE: qemuDomainCreateWithFlags (qemu_driver.c:7450)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit c03fbecc7c)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-01-18 17:24:26 +01:00
Michal Privoznik
58832fe437 qemuProcessReadLog: Fix memmove arguments
So I can observe this crasher that with freshly started daemon
(and virtlogd enabled) I am trying to startup a domain that
immediately dies (because it's said to use huge pages but I
haven't allocated a single one in the pool). Hardly reproducible
with -O0 or under valgrind. But I just got lucky:

==20469== Invalid write of size 8
==20469==    at 0x4C2E99B: memcpy@GLIBC_2.2.5 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20469==    by 0x217EDD07: qemuProcessReadLog (qemu_process.c:1670)
==20469==    by 0x217EDE1D: qemuProcessReportLogError (qemu_process.c:1696)
==20469==    by 0x217EE8C1: qemuProcessWaitForMonitor (qemu_process.c:1957)
==20469==    by 0x217F6636: qemuProcessLaunch (qemu_process.c:4955)
==20469==    by 0x217F71A4: qemuProcessStart (qemu_process.c:5152)
==20469==    by 0x21846582: qemuDomainObjStart (qemu_driver.c:7396)
==20469==    by 0x218467DE: qemuDomainCreateWithFlags (qemu_driver.c:7450)
==20469==    by 0x21846845: qemuDomainCreate (qemu_driver.c:7468)
==20469==    by 0x5611CD0: virDomainCreate (libvirt-domain.c:6753)
==20469==    by 0x125D9A: remoteDispatchDomainCreate (remote_dispatch.h:3613)
==20469==    by 0x125CB7: remoteDispatchDomainCreateHelper (remote_dispatch.h:3589)
==20469==  Address 0x27a52ad0 is 0 bytes after a block of size 5,584 alloc'd
==20469==    at 0x4C29F80: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20469==    by 0x9B8D1DB: xdr_string (in /lib64/libc-2.21.so)
==20469==    by 0x563B39C: xdr_virLogManagerProtocolNonNullString (log_protocol.c:24)
==20469==    by 0x563B6B7: xdr_virLogManagerProtocolDomainReadLogFileRet (log_protocol.c:123)
==20469==    by 0x164B34: virNetMessageDecodePayload (virnetmessage.c:407)
==20469==    by 0x5682360: virNetClientProgramCall (virnetclientprogram.c:379)
==20469==    by 0x563B30E: virLogManagerDomainReadLogFile (log_manager.c:272)
==20469==    by 0x217CD613: qemuDomainLogContextRead (qemu_domain.c:2485)
==20469==    by 0x217EDC76: qemuProcessReadLog (qemu_process.c:1660)
==20469==    by 0x217EDE1D: qemuProcessReportLogError (qemu_process.c:1696)
==20469==    by 0x217EE8C1: qemuProcessWaitForMonitor (qemu_process.c:1957)
==20469==    by 0x217F6636: qemuProcessLaunch (qemu_process.c:4955)

This points to memmove() in qemuProcessReadLog(). Imagine we just
read the following string from qemu:

"abc\n2016-01-18T09:40:44.022744Z qemu-system-x86_64: Error\n"

After the first pass of the while() loop in the
qemuProcessReadLog() (in which we have taken the false branch in
the if) @buf still points to the beginning of the string,
@filter_next points to the beginning of the second line.  So we
start second iteration because there is yet another newline
character at the end. In this iteration @eol points to it
actually. Now, the control gets inside true branch of if(). Just
to remind you:

got = 58
filter_next = buf + 5,
eol = buf + 58.

Therefore skip = 54 which is correct. The message we want to skip
is 54 bytes long. However:

memmove(filter_next, eol + 1, (got - skip) +1);

which is

memmove(filter_next, eol + 1, 5)

is obviously wrong as there is only one byte we can access, not 5!

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 105b51f42e)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2016-01-18 17:24:16 +01:00
7192 changed files with 1131631 additions and 3030009 deletions

44
.gitignore vendored
View File

@@ -1,7 +1,5 @@
*#*#
*.#*#
*.[187]
*.[187].in
*.a
*.cov
*.exe
@@ -11,7 +9,6 @@
*.gcov
*.html
*.i
*.init
*.la
*.lo
*.loT
@@ -21,8 +18,6 @@
*.pyc
*.rej
*.s
*.service
*.socket
*.swp
*~
.#*
@@ -43,7 +38,8 @@
/NEWS
/aclocal.m4
/autom4te.cache
/build-aux/*
/build-aux
/build-aux/
/build/
/confdefs.h
/config.cache
@@ -61,7 +57,13 @@
/daemon/libvirt_qemud
/daemon/libvirtd
/daemon/libvirtd*.logrotate
/daemon/libvirtd.8
/daemon/libvirtd.8.in
/daemon/libvirtd.init
/daemon/libvirtd.pod
/daemon/libvirtd.policy
/daemon/libvirtd.service
/daemon/libvirtd.socket
/daemon/test_libvirtd.aug
/docs/aclperms.htmlinc
/docs/apibuild.py.stamp
@@ -72,16 +74,8 @@
/docs/libvirt-lxc-*.xml
/docs/libvirt-qemu-*.xml
/docs/libvirt-refs.xml
/docs/news.html.in
/docs/search.php
/docs/todo.html.in
/examples/admin/client_close
/examples/admin/client_info
/examples/admin/client_limits
/examples/admin/list_clients
/examples/admin/list_servers
/examples/admin/logging
/examples/admin/threadpool_params
/examples/object-events/event-test
/examples/dominfo/info1
/examples/domsuspend/suspend
@@ -95,7 +89,7 @@
/gnulib/tests/*
/include/libvirt/libvirt-common.h
/libtool
/libvirt-*.tar.xz
/libvirt-*.tar.gz
/libvirt-[0-9]*
/libvirt*.pc
/libvirt.spec
@@ -159,27 +153,32 @@
/src/test_libvirt*.aug
/src/test_virtlockd.aug
/src/test_virtlogd.aug
/src/util/virkeycodetable*.h
/src/util/virkeynametable*.h
/src/util/virkeymaps.h
/src/virt-aa-helper
/src/virtlockd
/src/virtlockd.8
/src/virtlockd.8.in
/src/virtlockd.init
/src/virtlogd
/src/virtlogd.8
/src/virtlogd.8.in
/src/virtlogd.init
/tests/*.log
/tests/*.pid
/tests/*.trs
/tests/*test
/tests/commandhelper
/tests/qemucapsprobe
!/tests/virsh-self-test
/tests/*test
!/tests/*schematest
!/tests/virt-aa-helper-test
!/tests/virt-admin-self-test
/tests/objectlocking
/tests/objectlocking-files.txt
/tests/objectlocking.cm[ix]
/tests/reconnect
/tests/ssh
/tests/test_file_access.txt
/tests/test_conf
/tools/*.[18]
/tools/libvirt-guests.init
/tools/libvirt-guests.service
/tools/libvirt-guests.sh
/tools/virt-login-shell
/tools/virsh
@@ -206,7 +205,6 @@ stamp-h
stamp-h.in
stamp-h1
tags
!/build-aux/*.pl
!/gnulib/lib/Makefile.am
!/gnulib/tests/Makefile.am
!/m4/virt-*.m4

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "gnulib"]
path = .gnulib
url = git://git.sv.gnu.org/gnulib.git
[submodule "keycodemapdb"]
path = src/keycodemapdb
url = https://gitlab.com/keycodemap/keycodemapdb.git

Submodule .gnulib updated: 94386a1366...6cc32c63e8

View File

@@ -1,85 +0,0 @@
sudo: false
language: c
dist: precise
compiler:
- gcc
cache: ccache
addons:
apt:
packages:
- xsltproc
- autopoint
- libxml2-dev
- libncurses5-dev
- libreadline-dev
- zlib1g-dev
- libgnutls-dev
- libgcrypt11-dev
- libavahi-client-dev
- libsasl2-dev
- libxen-dev
- lvm2
- libgcrypt11-dev
- libparted0-dev
- libdevmapper-dev
- uuid-dev
- libudev-dev
- libpciaccess-dev
- libcap-ng-dev
- libnl-3-dev
- libnl-route-3-dev
- libyajl-dev
- libpcap0.8-dev
- libnuma-dev
- libnetcf-dev
- libaudit-dev
# - dwarves
- libxml2-utils
- libapparmor-dev
- dnsmasq-base
- librbd-dev
- w3c-dtd-xhtml
notifications:
irc:
# The channel name "irc.oftc.net#virt" is encrypted against libvirt/libvirt
# to prevent IRC notifications from github forks. This was created using:
# $ travis encrypt -r "libvirt/libvirt" "irc.oftc.net#virt"
channels:
- secure: "hUPdkLxX7nh75+clpnk4U0XLExLfV9DFKSvQSAUtf5JtDNMslj7AeOCf2wcbkNsEhkiF557odTAnov1s5m1w/yaa56zbjFAh5agzqRKya3QjqsrvlBKw/WuN+l82iMNLLeebTgCPAXrbAbGWH8YmYssp/7+eMsnKaVh84EQQNbMCHlLg6ovE26Fs18mZ6J5RC3OPa1vbv+xkdCHvGg/Oyp4K8bpU7RYyimA56jdxI/OfdTH9HxntHYSzykR7hDbyzZhdIlAUyRKReQVjcV5+R8fdDL/1imyGA/88KTztMeKXpZ5Rf+Ss3vYLZb6qsLLegCZ4AU/q0vvbWxjpZGJZoeyrVpfBTZdYGIzmLTMl9GYXXa/gDwFlbvRDiPDG4TIy6GlMUROinj7KRKEHu1fWRYu012ife5OjidxcwrTnz21vYaCv3AKWPpMPxwIzQPkY1hex9uLLX6z+TrAxxDLF+7UzRT9w2RLFBkLYlj2aDVrLAVb/ynRsxDz5CGzC61FSQVft2e308SkGjdn8YxvguCuXv+N70Fu1cvFyh5XYeHb4fbBRo0Ctzaec78leHlQvRGWKJxXDXRkE2lvvBc7YbBNSAYh7Fs8Y+zY7l7rMxvXdrt3nuaNQhe74V3yhxPDAld66qmAn9TYMmaZW2f5/KKKILLbCa0t2MxiAc6L2OI8="
on_success: change
on_failure: always
email:
# The list name 'libvirt-ci@redhat.com" is encrypted against libvirt/libvirt
# to prevent IRC notifications from github forks. This was created using:
# $ travis encrypt -r "libvirt/libvirt" "libvirt-ci@redhat.com"
recipients:
- secure: "QcU9eP96P0RlDNzVRZl/4sxyydPStGzECrpgJhr2IPB/7pHk23yaBrmUsq9S830tB+jwLGma1IscNB8uf7Sf7WY+cYIpfR8v030OffWnaipo/Gcs0dpnlfURWHjOFQI3RJzGEihsqvbwUFOwsM+3IDyO3qdWaiT6cN2Tj9ROlwYCySSX5YWzLyX7arBZ4lp8ESs7ohQaEwp2cegnMP2oGPJJe4SebvlCDjHZbjkU5aEradwUWnRQDJZWTKknpNLArVFxN2/ixp6f/MGY4DmkHoDweio6mHIPN5zTs5Jt32aiX6wDBa+bBa4v8TCRqzhYkQ63ZZhNV8bY5Uf9ufTdyvt96yIANyakd85b1QpMdAX76IyJi1l0/Uub6DTQZAcq3vK7iPjGeTVSpyoXrqTfGy4JxMjqDoocpWvv8ALX1wrYI/HfN2R2Aepw9jModTimOsebYhJ1yMhSt8qnh5AQNftGKL2JBKoA1LWdU2YJ5fO1bGjKNiVEkGFQTPYFWrYCUY5JcT+s5WCzNeMNm8s9na8liYhGl3WtS3rPr5M8bof+BMsBhG2hQ0loduc94x2GkvyhQZUgRbqrwNR+y4hn+rWFC3hBzzyiAULs43vY/PJ+eBdKEf3VAc0MkhQ8GgXGSA61fR6aXYonroI/WnBVItwDmUnnMfSziZXxk09GLl4="
git:
submodules: true
before_install:
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update && brew install gnutls libgcrypt yajl gettext rpcgen ; fi
# the custom PATH is just to pick up OS-X homebrew & its harmless on Linux
before_script:
- PATH="/usr/local/opt/gettext/bin:/usr/local/opt/rpcgen/bin:$PATH" ./autogen.sh
script:
- VIR_TEST_DEBUG=1 make -j3 && make -j3 syntax-check && make -j3 check
# Environments here are run in addition to the main environment defined above
matrix:
include:
- compiler: clang
dist: precise
- compiler: clang
dist: trusty
- compiler: gcc
dist: trusty
- compiler: clang
os: osx
script:
# many unit tests fail & so does syntax-check, so skip for now
# one day we must fix it though....
- make -j3

View File

@@ -15,6 +15,7 @@ Claudio Bley <claudio.bley@gmail.com>
Cole Robinson <crobinso@redhat.com>
Daniel Berrange <berrange@redhat.com>
Daniel Veillard <veillard@redhat.com>
Dmitry Guryanov <dguryanov@parallels.com>
Doug Goldstein <cardoe@gentoo.org>
Eric Blake <eblake@redhat.com>
Erik Skultety <eskultet@redhat.com>
@@ -28,7 +29,6 @@ Laine Stump <laine@redhat.com>
Mark McLoughlin <markmc@redhat.com>
Martin Kletzander <mkletzan@redhat.com>
Matthias Bolte <matthias.bolte@googlemail.com>
Maxim Nestratov <mnestratov@virtuozzo.com>
Michal Prívozník <mprivozn@redhat.com>
Pavel Hrdina <phrdina@redhat.com>
Peter Krempa <pkrempa@redhat.com>
@@ -45,7 +45,6 @@ Chris Lalancette <clalance@redhat.com>
Dan Smith <danms@us.ibm.com>
Dave Allan <dallan@redhat.com>
Dave Leskovec <dlesko@linux.vnet.ibm.com>
Dmitry Guryanov <dguryanov@parallels.com>
Guannan Ren <gren@redhat.com>
Jim Meyering <meyering@redhat.com>
John Levon <john.levon@sun.com>

125
HACKING
View File

@@ -23,11 +23,19 @@ libvirt-python) online <http://libvirt.org/git/>.
join the appropriate language team. The libvirt release process automatically
pulls the latest version of each translation file from zanata.
(4) Post patches using "git send-email", with git rename detection enabled. You
(4) Post patches in unified diff format, with git rename detection enabled. You
need a one-time setup of:
git config diff.renames true
After that, a command similar to this should work:
diff -urp libvirt.orig/ libvirt.modified/ > libvirt-myfeature.patch
or:
git diff > libvirt-myfeature.patch
Also, for code motion patches, you may find that "git diff --patience"
provides an easier-to-read patch. However, the usual workflow of libvirt
developer is:
@@ -65,6 +73,8 @@ Moreover, such patch needs to be prefixed correctly with
"--subject-prefix=PATCHv2" appended to "git send-email" (substitute "v2" with
the correct version if needed though).
(5) In your commit message, make the summary line reasonably short (60 characters
is typical), followed by a blank line, followed by any longer description of
why your patch makes sense. If the patch fixes a regression, and you know what
@@ -75,6 +85,8 @@ You can use 'git shortlog -30' to get an idea of typical summary lines.
Libvirt does not currently attach any meaning to Signed-off-by: lines, so it
is up to you if you want to include or omit them in the commit message.
(6) Split large changes into a series of smaller patches, self-contained if
possible, with an explanation of each patch and an explanation of how the
sequence of patches fits together. Moreover, please keep in mind that it's
@@ -84,6 +96,8 @@ of a series, but intermediate patches must compile and not cause test-suite
failures (this is to preserve the usefulness of "git bisect", among other
things).
(7) Make sure your patches apply against libvirt GIT. Developers only follow GIT
and don't care much about released versions.
@@ -138,16 +152,7 @@ There is also a "./run" script at the top level, to make it easier to run
programs that have not yet been installed, as well as to wrap invocations of
various tests under gdb or Valgrind.
When running our test suite it may happen that the test result is
nondeterministic because of the test suite relying on a particular file in the
system being accessible or having some specific value. To catch this kind of
errors, the test suite has a module for that prints any path touched that
fulfils constraints described above into a file. To enable it just set
"VIR_TEST_FILE_ACCESS" environment variable. Then
"VIR_TEST_FILE_ACCESS_OUTPUT" environment variable can alter location where
the file is stored.
VIR_TEST_FILE_ACCESS=1 VIR_TEST_FILE_ACCESS_OUTPUT="/tmp/file_access.txt" ./qemuxml2argvtest
(9) The Valgrind test should produce similar output to "make check". If the output
has traces within libvirt API's, then investigation is required in order to
@@ -223,102 +228,18 @@ to "tests/.valgrind.supp" in order to suppress the warning:
obj:*/lib*/ld-2.*so*
}
(10) Update tests and/or documentation, particularly if you are adding a new
feature or changing the output of a program.
(11) Don't forget to update the release notes <news.html> by changing
"docs/news.xml" if your changes are significant. All user-visible changes,
such as adding new XML elements or fixing all but the most obscure bugs, must
be (briefly) described in a release notes entry; changes that are only
relevant to other libvirt developers, such as code refactoring, don't belong
in the release notes. Note that "docs/news.xml" should be updated in its own
commit not to get in the way of backports.
There is more on this subject, including lots of links to background reading
on the subject, on Richard Jones' guide to working with open source projects
<http://people.redhat.com/rjones/how-to-supply-code-to-open-source-projects/>.
Naming conventions
==================
When reading libvirt code, a number of different naming conventions will be
evident due to various changes in thinking over the course of the project's
lifetime. The conventions documented below should be followed when creating
any entirely new files in libvirt. When working on existing files, while it is
desirable to apply these conventions, keeping a consistent style with existing
code in that particular file is generally more important. The overall guiding
principal is that every file, enum, struct, function, macro and typedef name
must have a 'vir' or 'VIR' prefix. All local scope variable names are exempt,
and global variables are exempt, unless exported in a header file.
*File names*
File naming varies depending on the subdirectory. The preferred style is to
have a 'vir' prefix, followed by a name which matches the name of the
functions / objects inside the file. For example, a file containing an object
'virHashtable' is stored in files 'virhashtable.c' and 'virhashtable.h'.
Sometimes, methods which would otherwise be declared 'static' need to be
exported for use by a test suite. For this purpose a second header file should
be added with a suffix of 'priv', e.g. 'virhashtablepriv.h'. Use of
underscores in file names is discouraged when using the 'vir' prefix style.
The 'vir' prefix naming applies to src/util, src/rpc and tests/ directories.
Most other directories do not follow this convention.
*Enum type & field names*
All enums should have a 'vir' prefix in their typedef name, and each following
word should have its first letter in uppercase. The enum name should match the
typedef name with a leading underscore. The enum member names should be in all
uppercase, and use an underscore to separate each word. The enum member name
prefix should match the enum typedef name.
typedef enum _virSocketType virSocketType;
enum _virSocketType {
VIR_SOCKET_TYPE_IPV4,
VIR_SOCKET_TYPE_IPV6,
};
*Struct type names*
All structs should have a 'vir' prefix in their typedef name, and each
following word should have its first letter in uppercase. The struct name
should be the same as the typedef name with a leading underscore. A second
typedef should be given for a pointer to the struct with a 'Ptr' suffix.
typedef struct _virHashTable virHashTable;
typedef virHashTable *virHashTablePtr;
struct _virHashTable {
...
};
*Function names*
All functions should have a 'vir' prefix in their name, followed by one or
more words with first letter of each word capitalized. Underscores should not
be used in function names. If the function is operating on an object, then the
function name prefix should match the object typedef name, otherwise it should
match the filename. Following this comes the verb / action name, and finally
an optional subject name. For example, given an object 'virHashTable', all
functions should have a name 'virHashTable$VERB' or
'virHashTable$VERB$SUBJECT", e.g. 'virHashTableLookup' or
'virHashTableGetValue'.
*Macro names*
All macros should have a "VIR" prefix in their name, followed by one or more
uppercase words separated by underscores. The macro argument names should be
in lowercase. Aside from having a "VIR" prefix there are no common practices
for the rest of the macro name.
Code indentation
================
Libvirt's C source code generally adheres to some basic code-formatting
@@ -651,6 +572,8 @@ true) ...". Rather, write "if (seen)...".
Of course, take all of the above with a grain of salt. If you're about to use
some system interface that requires a type like "size_t", "pid_t" or "off_t",
use matching types for any corresponding variables.
@@ -762,6 +685,8 @@ size:
File handling
=============
Usage of the "fdopen()", "close()", "fclose()" APIs is deprecated in libvirt
@@ -805,6 +730,8 @@ APIs, use the macros from virfile.h
String comparisons
==================
Do not use the strcmp, strncmp, etc functions directly. Instead use one of the
@@ -852,6 +779,8 @@ following semantically named macros
String copying
==============
Do not use the strncpy function. According to the man page, it does *not*
@@ -1020,6 +949,8 @@ by further potentially failing calls. You should almost certainly be using a
conditional and a block instead of a goto. Perhaps some of your function's
logic would be better pulled out into a helper function.
Although libvirt does not encourage the Linux kernel wind/unwind style of
multiple labels, there's a good general discussion of the issue archived at
KernelTrap <http://kerneltrap.org/node/553/2131>

View File

@@ -19,12 +19,9 @@
LCOV = lcov
GENHTML = genhtml
SUBDIRS = . gnulib/lib include/libvirt src daemon tools docs gnulib/tests \
SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
tests po examples
XZ_OPT ?= -v -T0
export XZ_OPT
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = \
@@ -36,6 +33,7 @@ EXTRA_DIST = \
libvirt-qemu.pc.in \
libvirt-lxc.pc.in \
libvirt-admin.pc.in \
autobuild.sh \
Makefile.nonreentrant \
autogen.sh \
cfg.mk \
@@ -43,27 +41,15 @@ EXTRA_DIST = \
AUTHORS.in
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc libvirt-admin.pc
pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc
NEWS: \
$(srcdir)/docs/news.xml \
$(srcdir)/docs/news-ascii.xsl \
$(srcdir)/docs/reformat-news.py
$(AM_V_GEN) \
if [ -x $(XSLTPROC) ]; then \
$(XSLTPROC) --nonet \
$(srcdir)/docs/news-ascii.xsl \
$(srcdir)/docs/news.xml \
>$@-tmp \
|| { rm -f $@-tmp; exit 1; }; \
$(srcdir)/docs/reformat-news.py $@-tmp >$@ \
|| { rm -f $@-tmp; exit 1; }; \
rm -f $@-tmp; \
fi
EXTRA_DIST += \
$(srcdir)/docs/news.xml \
$(srcdir)/docs/news-ascii.xsl \
$(srcdir)/docs/reformat-news.py
NEWS: $(top_srcdir)/docs/news.xsl $(top_srcdir)/docs/news.html.in
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
$(XSLTPROC) --nonet $(top_srcdir)/docs/news.xsl \
$(top_srcdir)/docs/news.html.in \
| perl -0777 -pe 's/\n\n+$$/\n/' \
| perl -pe 's/[ \t]+$$//' \
> $@-t && mv $@-t $@ ; fi
$(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl \
$(top_srcdir)/docs/hacking2.xsl \
@@ -77,15 +63,12 @@ $(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl \
> $@-t && mv $@-t $@ ; fi;
rpm: clean
@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.xz)
@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz)
check-local: all tests
check-access:
@($(MAKE) $(AM_MAKEFLAGS) -C tests check-access)
cov: clean-cov
$(MKDIR_P) $(top_builddir)/coverage
mkdir $(top_builddir)/coverage
$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp \
-d $(top_builddir)/src -d $(top_builddir)/daemon \
-d $(top_builddir)/tests
@@ -100,6 +83,9 @@ clean-cov:
MAINTAINERCLEANFILES = .git-module-status
# disable this check
distuninstallcheck:
dist-hook: gen-ChangeLog gen-AUTHORS
# Generate the ChangeLog file (with all entries since the switch to git)

View File

@@ -113,11 +113,3 @@ NON_REENTRANT += inet_nsap_ntoa
NON_REENTRANT += inet_ntoa
NON_REENTRANT += inet_ntop
NON_REENTRANT += inet_pton
# Separate two nothings by space to get one space in a variable
space =
space +=
# The space needs to be in a variable otherwise it would be ignored.
# And there must be no spaces around the commas because they would
# not be ignored, logically.
NON_REENTRANT_RE=$(subst $(space),|,$(NON_REENTRANT))

122
autobuild.sh Executable file
View File

@@ -0,0 +1,122 @@
#!/bin/sh
set -e
set -v
# Make things clean.
test -n "$1" && RESULTS=$1 || RESULTS=results.log
: ${AUTOBUILD_INSTALL_ROOT=$HOME/builder}
# If run under the autobuilder, we must use --nodeps with rpmbuild;
# but this can lead to odd error diagnosis for normal development.
nodeps=
if test "${AUTOBUILD_COUNTER+set}"; then
nodeps=--nodeps
fi
test -f Makefile && make -k distclean || :
rm -rf coverage
rm -rf build
mkdir build
cd build
# Run with options not normally exercised by the rpm build, for
# more complete code coverage.
../autogen.sh --prefix="$AUTOBUILD_INSTALL_ROOT" \
--enable-expensive-tests \
--enable-test-coverage \
--disable-nls \
--enable-werror \
--enable-static
# If the MAKEFLAGS envvar does not yet include a -j option,
# add -jN where N depends on the number of processors.
case $MAKEFLAGS in
*-j*) ;;
*) n=$(getconf _NPROCESSORS_ONLN 2> /dev/null)
test "$n" -gt 0 || n=1
n=$(expr $n + 1)
MAKEFLAGS="$MAKEFLAGS -j$n"
export MAKEFLAGS
;;
esac
make
make install
# set -o pipefail is a bashism; this use of exec is the POSIX alternative
exec 3>&1
st=$(
exec 4>&1 >&3
{ make check syntax-check 2>&1 3>&- 4>&-; echo $? >&4; } | tee "$RESULTS"
)
exec 3>&-
test "$st" = 0
test -x /usr/bin/lcov && make cov
rm -f *.tar.gz
make dist
if test -n "$AUTOBUILD_COUNTER" ; then
EXTRA_RELEASE=".auto$AUTOBUILD_COUNTER"
else
NOW=`date +"%s"`
EXTRA_RELEASE=".$USER$NOW"
fi
if test -f /usr/bin/rpmbuild ; then
rpmbuild $nodeps \
--define "extra_release $EXTRA_RELEASE" \
--define "_sourcedir `pwd`" \
-ba --clean libvirt.spec
fi
# Test mingw32 cross-compile
if test -x /usr/bin/i686-w64-mingw32-gcc ; then
make distclean
PKG_CONFIG_LIBDIR="/usr/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig:/usr/i686-w64-mingw32/sys-root/mingw/share/pkgconfig" \
PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig" \
CC="i686-w64-mingw32-gcc" \
../configure \
--build=$(uname -m)-w64-linux \
--host=i686-w64-mingw32 \
--prefix="$AUTOBUILD_INSTALL_ROOT/i686-w64-mingw32/sys-root/mingw" \
--enable-expensive-tests \
--enable-werror
make
make install
fi
# Test mingw64 cross-compile
if test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
make distclean
PKG_CONFIG_LIBDIR="/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig:/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig" \
PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig" \
CC="x86_64-w64-mingw32-gcc" \
../configure \
--build=$(uname -m)-w64-linux \
--host=x86_64-w64-mingw32 \
--prefix="$AUTOBUILD_INSTALL_ROOT/x86_64-w64-mingw32/sys-root/mingw" \
--enable-expensive-tests \
--enable-werror
make
make install
fi
if test -x /usr/bin/i686-w64-mingw32-gcc && test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
if test -f /usr/bin/rpmbuild ; then
rpmbuild $nodeps \
--define "extra_release $EXTRA_RELEASE" \
--define "_sourcedir `pwd`" \
-ba --clean mingw-libvirt.spec
fi
fi

View File

@@ -1,196 +1,117 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
die()
{
echo "error: $1" >&2
set -e
srcdir=`dirname "$0"`
test -z "$srcdir" && srcdir=.
THEDIR=`pwd`
cd "$srcdir"
test -f src/libvirt.c || {
echo "You must run this script in the top-level libvirt directory"
exit 1
}
starting_point=$(pwd)
srcdir=$(dirname "$0")
test "$srcdir" || srcdir=.
cd "$srcdir" || {
die "Failed to cd into $srcdir"
}
test -f src/libvirt.c || {
die "$0 must live in the top-level libvirt directory"
}
dry_run=
EXTRA_ARGS=
no_git=
gnulib_srcdir=
extra_args=
while test "$#" -gt 0; do
case "$1" in
--dry-run)
# This variable will serve both as an indicator of the fact that
# a dry run has been requested, and to store the result of the
# dry run. It will be ultimately used as return code for the
# script: 0 means no action is necessary, 2 means that autogen.sh
# needs to be executed, and 1 is reserved for failures
dry_run=0
shift
;;
--no-git)
no_git=" $1"
shift
;;
--gnulib-srcdir=*)
gnulib_srcdir=" $1"
shift
;;
--gnulib-srcdir)
gnulib_srcdir=" $1=$2"
shift
shift
;;
--system)
prefix=/usr
sysconfdir=/etc
localstatedir=/var
if test -d $prefix/lib64; then
libdir=$prefix/lib64
else
libdir=$prefix/lib
fi
extra_args="--prefix=$prefix --localstatedir=$localstatedir"
extra_args="$extra_args --sysconfdir=$sysconfdir --libdir=$libdir"
shift
;;
*)
# All remaining arguments will be passed to configure verbatim
break
;;
esac
done
no_git="$no_git$gnulib_srcdir"
if test "x$1" = "x--no-git"; then
no_git=" $1"
shift
case "$1 $2" in
--gnulib-srcdir=*) no_git="$no_git $1"; shift ;;
--gnulib-srcdir\ *) no_git="$no_git $1=$2"; shift; shift;;
esac
fi
if test -z "$NOCONFIGURE" ; then
if test "x$1" = "x--system"; then
shift
prefix=/usr
libdir=$prefix/lib
sysconfdir=/etc
localstatedir=/var
if [ -d /usr/lib64 ]; then
libdir=$prefix/lib64
fi
EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir"
echo "Running ./configure with $EXTRA_ARGS $@"
else
if test -z "$*" && test ! -f "$THEDIR/config.status"; then
echo "I am going to run ./configure with no arguments - if you wish"
echo "to pass any to it, please specify them on the $0 command line."
fi
fi
fi
gnulib_hash()
# Compute the hash we'll use to determine whether rerunning bootstrap
# is required. The first is just the SHA1 that selects a gnulib snapshot.
# The second ensures that whenever we change the set of gnulib modules used
# by this package, we rerun bootstrap to pull in the matching set of files.
# The third ensures that whenever we change the set of local gnulib diffs,
# we rerun bootstrap to pull in those diffs.
bootstrap_hash()
{
local no_git=$1
if test "$no_git"; then
echo "no-git"
echo no-git
return
fi
# Compute the hash we'll use to determine whether rerunning bootstrap
# is required. The first is just the SHA1 that selects a gnulib snapshot.
# The second ensures that whenever we change the set of gnulib modules used
# by this package, we rerun bootstrap to pull in the matching set of files.
# The third ensures that whenever we change the set of local gnulib diffs,
# we rerun bootstrap to pull in those diffs.
git submodule status .gnulib | awk '{ print $1 }'
git submodule status | sed 's/^[ +-]//;s/ .*//'
git hash-object bootstrap.conf
git ls-tree -d HEAD gnulib/local | awk '{ print $3 }'
git ls-tree -d HEAD gnulib/local | awk '{print $3}'
}
# Only look into git submodules if we're in a git checkout
# Ensure that whenever we pull in a gnulib update or otherwise change to a
# different version (i.e., when switching branches), we also rerun ./bootstrap.
# Also, running 'make rpm' tends to litter the po/ directory, and some people
# like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates
# the required file po/Makevars.
# Only run bootstrap from a git checkout, never from a tarball.
if test -d .git || test -f .git; then
# Check for dirty submodules
if test -z "$CLEAN_SUBMODULE"; then
for path in $(git submodule status | awk '{ print $2 }'); do
case "$(git diff "$path")" in
*-dirty*)
echo "error: $path is dirty, please investigate" >&2
echo "set CLEAN_SUBMODULE to discard submodule changes" >&2
exit 1
;;
esac
done
curr_status=.git-module-status t=
if test "$no_git"; then
t=no-git
elif test -d .gnulib; then
t=$(bootstrap_hash; git diff .gnulib)
fi
if test "$CLEAN_SUBMODULE" && test -z "$no_git"; then
if test -z "$dry_run"; then
echo "Cleaning up submodules..."
git submodule foreach 'git clean -dfqx && git reset --hard' || {
die "Cleaning up submodules failed"
}
fi
fi
# Update all submodules. If any of the submodules has not been
# initialized yet, it will be initialized now; moreover, any submodule
# with uncommitted changes will be returned to the expected state
echo "Updating submodules..."
git submodule update --init || {
die "Updating submodules failed"
}
# The expected hash, eg. the one computed after the last
# successful bootstrap run, is stored on disk
state_file=.git-module-status
expected_hash=$(cat "$state_file" 2>/dev/null)
actual_hash=$(gnulib_hash "$no_git")
if test "$actual_hash" = "$expected_hash" && \
test -f po/Makevars && test -f AUTHORS; then
# The gnulib hash matches our expectations, and all the files
# that can only be generated through bootstrap are present:
# we just need to run autoreconf. Unless we're performing a
# dry run, of course...
if test -z "$dry_run"; then
echo "Running autoreconf..."
autoreconf -if || {
die "autoreconf failed"
}
fi
case $t:${CLEAN_SUBMODULE+set} in
*:set) ;;
*-dirty*)
echo "error: gnulib submodule is dirty, please investigate" 2>&1
echo "set env-var CLEAN_SUBMODULE to discard gnulib changes" 2>&1
exit 1 ;;
esac
# Keep this test in sync with cfg.mk:_update_required
if test "$t" = "$(cat $curr_status 2>/dev/null)" \
&& test -f "po/Makevars" && test -f AUTHORS; then
# good, it's up to date, all we need is autoreconf
autoreconf -if
else
# Whenever the gnulib submodule or any of the related bits
# has been changed in some way (see gnulib_hash) we need to
# run bootstrap again. If we're performing a dry run, we
# change the return code instead to signal our caller
if test "$dry_run"; then
dry_run=2
else
echo "Running bootstrap..."
./bootstrap$no_git --bootstrap-sync || {
die "bootstrap failed"
}
gnulib_hash >"$state_file"
if test -z "$no_git" && test ${CLEAN_SUBMODULE+set}; then
echo cleaning up submodules...
git submodule foreach 'git clean -dfqx && git reset --hard'
fi
echo running bootstrap$no_git...
./bootstrap$no_git --bootstrap-sync && bootstrap_hash > $curr_status \
|| { echo "Failed to bootstrap, please investigate."; exit 1; }
fi
fi
# When performing a dry run, we can stop here
test "$dry_run" && exit "$dry_run"
test -n "$NOCONFIGURE" && exit 0
# If asked not to run configure, we can stop here
test "$NOCONFIGURE" && exit 0
cd "$THEDIR"
cd "$starting_point" || {
die "Failed to cd into $starting_point"
}
if test "$OBJ_DIR"; then
mkdir -p "$OBJ_DIR" || {
die "Failed to create $OBJ_DIR"
}
cd "$OBJ_DIR" || {
die "Failed to cd into $OBJ_DIR"
}
if test "x$OBJ_DIR" != x; then
mkdir -p "$OBJ_DIR"
cd "$OBJ_DIR"
fi
if test -z "$*" && test -z "$extra_args" && test -f config.status; then
echo "Running config.status..."
./config.status --recheck || {
die "config.status failed"
}
if test -z "$*" && test -z "$EXTRA_ARGS" && test -f config.status; then
./config.status --recheck
else
if test -z "$*" && test -z "$extra_args"; then
echo "I am going to run configure with no arguments - if you wish"
echo "to pass any to it, please specify them on the $0 command line."
else
echo "Running configure with $extra_args $@"
fi
"$srcdir/configure" $extra_args "$@" || {
die "configure failed"
}
fi
echo
echo "Now type 'make' to compile libvirt."
$srcdir/configure $EXTRA_ARGS "$@"
fi && {
echo
echo "Now type 'make' to compile libvirt."
}

View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Print a version string.
scriptversion=2017-01-09.19; # UTC
scriptversion=2014-12-08.12; # UTC
# Bootstrap this package from checked-out sources.
# Copyright (C) 2003-2017 Free Software Foundation, Inc.
# Copyright (C) 2003-2016 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
@@ -42,7 +42,7 @@ export LC_ALL
local_gl_dir=gl
# Honor $PERL, but work even if there is none.
# Honour $PERL, but work even if there is none
PERL="${PERL-perl}"
me=$0
@@ -418,30 +418,28 @@ sort_ver() { # sort -V is not generally available
done
}
get_version_sed='
# Move version to start of line.
s/.*[v ]\([0-9]\)/\1/
# Skip lines that do not start with version.
/^[0-9]/!d
# Remove characters after the version.
s/[^.a-z0-9-].*//
# The first component must be digits only.
s/^\([0-9]*\)[a-z-].*/\1/
#the following essentially does s/5.005/5.5/
s/\.0*\([1-9]\)/.\1/g
p
q'
get_version() {
app=$1
$app --version >/dev/null 2>&1 || { $app --version; return 1; }
$app --version 2>&1 | sed -n "$get_version_sed"
$app --version 2>&1 |
sed -n '# Move version to start of line.
s/.*[v ]\([0-9]\)/\1/
# Skip lines that do not start with version.
/^[0-9]/!d
# Remove characters after the version.
s/[^.a-z0-9-].*//
# The first component must be digits only.
s/^\([0-9]*\)[a-z-].*/\1/
#the following essentially does s/5.005/5.5/
s/\.0*\([1-9]\)/.\1/g
p
q'
}
check_versions() {
@@ -790,7 +788,7 @@ symlink_to_dir()
# Leave any existing symlink alone, if it already points to the source,
# so that broken build tools that care about symlink times
# aren't confused into doing unnecessary builds. Conversely, if the
# existing symlink's timestamp is older than the source, make it afresh,
# existing symlink's time stamp is older than the source, make it afresh,
# so that broken tools aren't confused into skipping needed builds. See
# <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00326.html>.
test -h "$dst" &&
@@ -1023,6 +1021,6 @@ echo "$0: done. Now you can run './configure'."
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -54,7 +54,6 @@ func
getaddrinfo
getcwd-lgpl
gethostname
getopt-posix
getpass
getpeername
getsockname
@@ -121,7 +120,6 @@ time_r
timegm
ttyname_r
uname
unsetenv
useless-if-before-free
usleep
vasprintf
@@ -209,6 +207,7 @@ gzip -
libtool -
patch -
perl 5.5
perl::XML::XPath -
pkg-config -
rpcgen -
tar -

View File

@@ -1,6 +1,6 @@
#!/usr/bin/perl
#
# check-spacing.pl: Report any usage of 'function (..args..)'
# bracket-spacing.pl: Report any usage of 'function (..args..)'
# Also check for other syntax issues, such as correct use of ';'
#
# This library is free software; you can redistribute it and/or
@@ -43,7 +43,7 @@ foreach my $file (@ARGV) {
$data =~ s/'[";,=]'/'X'/g;
# Kill any quoted strings
$data =~ s,"(?:[^\\\"]|\\.)*","XXX",g;
$data =~ s,"([^\\\"]|\\.)*","XXX",g;
# Kill any C++ style comments
$data =~ s,//.*$,//,;
@@ -91,8 +91,8 @@ foreach my $file (@ARGV) {
my $kw = $1;
# Allow space after keywords only
if ($kw =~ /^(?:if|for|while|switch|return)$/) {
$tmpdata =~ s/(?:$kw\s\()/XXX(/;
if ($kw =~ /^(if|for|while|switch|return)$/) {
$tmpdata =~ s/($kw\s\()/XXX(/;
} else {
print "Whitespace after non-keyword:\n";
print "$file:$.: $line";
@@ -101,8 +101,10 @@ foreach my $file (@ARGV) {
}
}
# Require whitespace immediately after keywords
if ($data =~ /\b(?:if|for|while|switch|return)\(/) {
# Require whitespace immediately after keywords,
# but none after the opening bracket
if ($data =~ /\b(if|for|while|switch|return)\(/ ||
$data =~ /\b(if|for|while|switch|return)\s+\(\s/) {
print "No whitespace after keyword:\n";
print "$file:$.: $line";
$ret = 1;
@@ -116,10 +118,8 @@ foreach my $file (@ARGV) {
}
# Forbid whitespace following ( or prior to )
# but allow whitespace before ) on a single line
# (optionally followed by a semicolon)
if (($data =~ /\s\)/ && not $data =~ /^\s+\);?$/) ||
$data =~ /\((?!$)\s/) {
if ($data =~ /\S\s+\)/ ||
$data =~ /\(\s+\S/) {
print "Whitespace after '(' or before ')':\n";
print "$file:$.: $line";
$ret = 1;
@@ -135,13 +135,10 @@ foreach my $file (@ARGV) {
# errno == EINTR)
# ;
#
if ($data =~ /\s[;,]/) {
unless ($data =~ /\S; ; / ||
$data =~ /^\s+;/) {
print "Whitespace before semicolon or comma:\n";
print "$file:$.: $line";
$ret = 1;
}
if ($data =~ /[^;\s]\s+[;,]/) {
print "Whitespace before (semi)colon:\n";
print "$file:$.: $line";
$ret = 1;
}
# Require EOL, macro line continuation, or whitespace after ";".
@@ -160,8 +157,11 @@ foreach my $file (@ARGV) {
}
# Require spaces around assignment '=', compounds and '=='
if ($data =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=/ ||
$data =~ /=[^= \\\n]/) {
# with the exception of virAssertCmpInt()
$tmpdata = $data;
$tmpdata =~ s/(virAssertCmpInt\(.* ).?=,/$1op,/;
if ($tmpdata =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=[^=]/ ||
$tmpdata =~ /=[^= \\\n]/) {
print "Spacing around '=' or '==':\n";
print "$file:$.: $line";
$ret = 1;

View File

@@ -1,72 +0,0 @@
#!/usr/bin/perl
my %noninlined;
my %mocked;
# Functions in public header don't get the noinline annotation
# so whitelist them here
$noninlined{"virEventAddTimeout"} = 1;
foreach my $arg (@ARGV) {
if ($arg =~ /\.h$/) {
#print "Scan header $arg\n";
&scan_annotations($arg);
} elsif ($arg =~ /mock\.c$/) {
#print "Scan mock $arg\n";
&scan_overrides($arg);
}
}
my $warned = 0;
foreach my $func (keys %mocked) {
next if exists $noninlined{$func};
$warned++;
print STDERR "$func is mocked at $mocked{$func} but missing noinline annotation\n";
}
exit $warned ? 1 : 0;
sub scan_annotations {
my $file = shift;
open FH, $file or die "cannot read $file: $!";
my $func;
while (<FH>) {
if (/^\s*(\w+)\(/ || /^(?:\w+\*?\s+)+(?:\*\s*)?(\w+)\(/) {
my $name = $1;
if ($name !~ /ATTRIBUTE/) {
$func = $name;
}
} elsif (/^\s*$/) {
$func = undef;
}
if (/ATTRIBUTE_NOINLINE/) {
if (defined $func) {
$noninlined{$func} = 1;
}
}
}
close FH
}
sub scan_overrides {
my $file = shift;
open FH, $file or die "cannot read $file: $!";
my $func;
while (<FH>) {
if (/^(\w+)\(/ || /^\w+\s*(?:\*\s*)?(\w+)\(/) {
my $name = $1;
if ($name =~ /^vir/) {
$mocked{$name} = "$file:$.";
}
}
}
close FH
}

View File

@@ -1,26 +0,0 @@
#!/usr/bin/perl
use strict;
my $file = " ";
my $ret = 0;
my %includes = ( );
my $lineno = 0;
while (<>) {
if (not $file eq $ARGV) {
%includes = ( );
$file = $ARGV;
$lineno = 0;
}
$lineno++;
if (/^# *include *[<"]([^>"]*\.h)[">]/) {
$includes{$1}++;
if ($includes{$1} == 2) {
$ret = 1;
print STDERR "$ARGV:$lineno: $_";
print STDERR "Do not include a header more than once per file\n";
}
}
}
exit $ret;

290
cfg.mk
View File

@@ -64,7 +64,6 @@ local-checks-to-skip = \
sc_prohibit_quote_without_use \
sc_prohibit_quotearg_without_use \
sc_prohibit_stat_st_blocks \
sc_prohibit_undesirable_word_seq \
sc_root_tests \
sc_space_tab \
sc_sun_os_names \
@@ -127,6 +126,7 @@ useless_free_options = \
--name=virDomainDiskDefFree \
--name=virDomainEventCallbackListFree \
--name=virObjectEventQueueFree \
--name=virObjectEventStateFree \
--name=virDomainFSDefFree \
--name=virDomainGraphicsDefFree \
--name=virDomainHostdevDefFree \
@@ -308,7 +308,7 @@ sc_flags_usage:
| grep -c '\(long\|unsigned\) flags')" != 4 && \
{ echo '$(ME): new API should use "unsigned int flags"' 1>&2; \
exit 1; } || :
@prohibit=' flags ATTRIBUTE_UNUSED' \
@prohibit=' flags ''ATTRIBUTE_UNUSED' \
halt='flags should be checked with virCheckFlags' \
$(_sc_search_regexp)
@prohibit='^[^@]*([^d] (int|long long)|[^dg] long) flags[;,)]' \
@@ -351,8 +351,8 @@ sc_prohibit_mkstemp:
# access with X_OK accepts directories, but we can't exec() those.
# access with F_OK or R_OK is okay, though.
sc_prohibit_access_xok:
@prohibit='access(at)? *\(.*X_OK' \
halt='use virFileIsExecutable instead of access(,X_OK)' \
@prohibit='access''(at)? *\(.*X_OK' \
halt='use virFileIsExecutable instead of access''(,X_OK)' \
$(_sc_search_regexp)
# Similar to the gnulib maint.mk rule for sc_prohibit_strcmp
@@ -361,7 +361,7 @@ snp_ = strncmp *\(.+\)
sc_prohibit_strncmp:
@prohibit='! *strncmp *\(|\<$(snp_) *[!=]=|[!=]= *$(snp_)' \
exclude=':# *define STR(N?EQLEN|PREFIX)\(' \
halt='use STREQLEN or STRPREFIX instead of strncmp' \
halt='use STREQLEN or STRPREFIX instead of str''ncmp' \
$(_sc_search_regexp)
# strtol and friends are too easy to misuse
@@ -379,7 +379,7 @@ sc_prohibit_strtol:
# But for plain %s, virAsprintf is overkill compared to strdup.
sc_prohibit_asprintf:
@prohibit='\<v?a[s]printf\>' \
halt='use virAsprintf, not asprintf' \
halt='use virAsprintf, not as'printf \
$(_sc_search_regexp)
@prohibit='virAsprintf.*, *"%s",' \
halt='use VIR_STRDUP instead of virAsprintf with "%s"' \
@@ -406,7 +406,7 @@ sc_prohibit_risky_id_promotion:
# since gnulib has more guarantees for snprintf portability
sc_prohibit_sprintf:
@prohibit='\<[s]printf\>' \
halt='use snprintf, not sprintf' \
halt='use snprintf, not s'printf \
$(_sc_search_regexp)
sc_prohibit_readlink:
@@ -420,9 +420,9 @@ sc_prohibit_gethostname:
$(_sc_search_regexp)
sc_prohibit_readdir:
@prohibit='\b(read|close|open)dir *\(' \
@prohibit='\breaddir *\(' \
exclude='exempt from syntax-check' \
halt='use virDirOpen, virDirRead and VIR_DIR_CLOSE' \
halt='use virDirRead, not readdir' \
$(_sc_search_regexp)
sc_prohibit_gettext_noop:
@@ -431,36 +431,43 @@ sc_prohibit_gettext_noop:
$(_sc_search_regexp)
sc_prohibit_VIR_ERR_NO_MEMORY:
@prohibit='\<VIR_ERR_NO_MEMORY\>' \
halt='use virReportOOMError, not VIR_ERR_NO_MEMORY' \
@prohibit='\<V''IR_ERR_NO_MEMORY\>' \
halt='use virReportOOMError, not V'IR_ERR_NO_MEMORY \
$(_sc_search_regexp)
sc_prohibit_PATH_MAX:
@prohibit='\<PATH_MAX\>' \
halt='dynamically allocate paths, do not use PATH_MAX' \
@prohibit='\<P''ATH_MAX\>' \
halt='dynamically allocate paths, do not use P'ATH_MAX \
$(_sc_search_regexp)
# Use a subshell for each function, to give the optimal warning message.
include $(srcdir)/Makefile.nonreentrant
sc_prohibit_nonreentrant:
@prohibit="\\<(${NON_REENTRANT_RE}) *\\(" \
halt="use re-entrant functions (usually ending with _r)" \
$(_sc_search_regexp)
@fail=0 ; \
for i in $(NON_REENTRANT) ; \
do \
(prohibit="\\<$$i *\\(" \
halt="use $${i}_r, not $$i" \
$(_sc_search_regexp) \
) || fail=1; \
done ; \
exit $$fail
sc_prohibit_select:
@prohibit='\<select *\(' \
halt='use poll(), not select()' \
@prohibit="\\<select *\\(" \
halt="use poll(), not se""lect()" \
$(_sc_search_regexp)
# Prohibit the inclusion of <ctype.h>.
sc_prohibit_ctype_h:
@prohibit='^# *include *<ctype\.h>' \
halt='use c-ctype.h instead of ctype.h' \
halt="don't use ctype.h; instead, use c-ctype.h" \
$(_sc_search_regexp)
# Insist on correct types for [pug]id.
sc_correct_id_types:
@prohibit='\<(int|long) *[pug]id\>' \
halt='use pid_t for pid, uid_t for uid, gid_t for gid' \
halt="use pid_t for pid, uid_t for uid, gid_t for gid" \
$(_sc_search_regexp)
# "const fooPtr a" is the same as "foo * const a", even though it is
@@ -496,12 +503,12 @@ ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\
sc_avoid_ctype_macros:
@prohibit='\b($(ctype_re)) *\(' \
halt='use c-ctype.h instead of ctype macros' \
halt="don't use ctype macros (use c-ctype.h)" \
$(_sc_search_regexp)
sc_avoid_strcase:
@prohibit='\bstrn?case(cmp|str) *\(' \
halt='use c-strcase.h instead of raw strcase functions' \
halt="don't use raw strcase functions (use c-strcase instead)" \
$(_sc_search_regexp)
sc_prohibit_virBufferAdd_with_string_literal:
@@ -519,6 +526,13 @@ sc_forbid_manual_xml_indent:
halt='use virBufferAdjustIndent instead of spaces when indenting xml' \
$(_sc_search_regexp)
# Not only do they fail to deal well with ipv6, but the gethostby*
# functions are also not thread-safe.
sc_prohibit_gethostby:
@prohibit='\<gethostby(addr|name2?) *\(' \
halt='use getaddrinfo, not gethostby*' \
$(_sc_search_regexp)
# dirname and basename from <libgen.h> are not required to be thread-safe
sc_prohibit_libgen:
@prohibit='( (base|dir)name *\(|include .libgen\.h)' \
@@ -558,13 +572,12 @@ sc_prohibit_int_index:
sc_prohibit_int_ijk:
@prohibit='\<(int|unsigned) ([^(=]* )*(i|j|k)\>(\s|,|;)' \
exclude='exempt from syntax-check' \
halt='use size_t, not int/unsigned int for loop vars i, j, k' \
$(_sc_search_regexp)
sc_prohibit_loop_iijjkk:
@prohibit='\<(int|unsigned) ([^=]+ )*(ii|jj|kk)\>(\s|,|;)' \
halt='use i, j, k for loop iterators, not ii, jj, kk' \
halt='use i, j, k for loop iterators, not ii, jj, kk' \
$(_sc_search_regexp)
# RHEL 5 gcc can't grok "for (int i..."
@@ -580,11 +593,6 @@ sc_prohibit_int_assign_bool:
halt='use bool type for boolean values' \
$(_sc_search_regexp)
sc_prohibit_unsigned_pid:
@prohibit='\<unsigned\> [^,=;(]+pid' \
halt='use signed type for pid values' \
$(_sc_search_regexp)
# Many of the function names below came from this filter:
# git grep -B2 '\<_('|grep -E '\.c- *[[:alpha:]_][[:alnum:]_]* ?\(.*[,;]$' \
# |sed 's/.*\.c- *//'|perl -pe 's/ ?\(.*//'|sort -u \
@@ -611,9 +619,8 @@ msg_gen_function += xenapiSessionErrorHandler
# msg_gen_function += vshPrint
# msg_gen_function += vshError
space =
space +=
func_re= ($(subst $(space),|,$(msg_gen_function)))
func_or := $(shell echo $(msg_gen_function)|tr -s ' ' '|')
func_re := ($(func_or))
# Look for diagnostics that aren't marked for translation.
# This won't find any for which error's format string is on a separate line.
@@ -666,7 +673,7 @@ sc_prohibit_useless_translation:
halt='found useless translation' \
$(_sc_search_regexp)
@prohibit='\<N?_ *\(' \
in_vc_files='(tests|examples)/' \
in_vc_files='^(tests|examples)/' \
halt='no translations in tests or examples' \
$(_sc_search_regexp)
@@ -735,7 +742,7 @@ sc_copyright_format:
@prohibit='Copyright [^(].*Red 'Hat \
halt='consistently use (C) in Red Hat copyright' \
$(_sc_search_regexp)
@prohibit='\<RedHat\>' \
@prohibit='\<Red''Hat\>' \
halt='spell Red Hat as two words' \
$(_sc_search_regexp)
@@ -777,7 +784,7 @@ sc_prohibit_cross_inclusion:
locking/) safe="($$dir|util|conf|rpc)";; \
cpu/| network/| node_device/| rpc/| security/| storage/) \
safe="($$dir|util|conf|storage)";; \
xenapi/ | xenconfig/ ) safe="($$dir|util|conf|xen|cpu)";; \
xenapi/ | xenconfig/ ) safe="($$dir|util|conf|xen)";; \
*) safe="($$dir|$(mid_dirs)|util)";; \
esac; \
in_vc_files="^src/$$dir" \
@@ -802,16 +809,40 @@ sc_require_enum_last_marker:
sc_prohibit_semicolon_at_eol_in_python:
@prohibit='^[^#].*\;$$' \
in_vc_files='\.py$$' \
halt='python does not require to end lines with a semicolon' \
halt="Don't use semicolon at eol in python files" \
$(_sc_search_regexp)
# mymain() in test files should use return, not exit, for nicer output
sc_prohibit_exit_in_tests:
@prohibit='\<exit *\(' \
in_vc_files='tests/.*\.c$$' \
in_vc_files='^tests/' \
halt='use return, not exit(), in tests' \
$(_sc_search_regexp)
# Don't include duplicate header in the source (either *.c or *.h)
sc_prohibit_duplicate_header:
@fail=0; for i in $$($(VC_LIST_EXCEPT) | grep '\.[chx]$$'); do \
awk '/# *include.*\.h/ { \
match($$0, /[<"][^>"]*[">]/); \
arr[substr($$0, RSTART + 1, RLENGTH - 2)]++; \
} \
END { \
for (key in arr) { \
if (arr[key] > 1) { \
fail=1; \
printf("%d %s are included\n", arr[key], key); \
} \
} \
if (fail == 1) { \
printf("duplicate header(s) in " FILENAME "\n"); \
exit 1; \
} \
}' $$i || fail=1; \
done; \
if test $$fail -eq 1; then \
{ echo '$(ME): avoid duplicate headers' 1>&2; exit 1; } \
fi;
# Don't include "libvirt/*.h" in "" form.
sc_prohibit_include_public_headers_quote:
@prohibit='# *include *"libvirt/.*\.h"' \
@@ -878,14 +909,14 @@ sc_prohibit_wrong_filename_in_comment:
sc_prohibit_virConnectOpen_in_virsh:
@prohibit='\bvirConnectOpen[a-zA-Z]* *\(' \
in_vc_files='tools/virsh-.*\.[ch]$$' \
in_vc_files='^tools/virsh-.*\.[ch]$$' \
halt='Use vshConnect() in virsh instead of virConnectOpen*' \
$(_sc_search_regexp)
sc_require_space_before_label:
@prohibit='^( ?)?[_a-zA-Z0-9]+:$$' \
in_vc_files='\.[ch]$$' \
halt='Top-level labels should be indented by one space' \
halt="Top-level labels should be indented by one space" \
$(_sc_search_regexp)
# Allow for up to three spaces before the label: this is to avoid running
@@ -894,14 +925,14 @@ sc_require_space_before_label:
sc_prohibit_space_in_label:
@prohibit='^ {0,3}[_a-zA-Z0-9]+ +:$$' \
in_vc_files='\.[ch]$$' \
halt='There should be no space between label name and colon' \
halt="There should be no space between label name and colon" \
$(_sc_search_regexp)
# Doesn't catch all cases of mismatched braces across if-else, but it helps
sc_require_if_else_matching_braces:
@prohibit='( else( if .*\))? {|} else( if .*\))?$$)' \
in_vc_files='\.[chx]$$' \
halt='if one side of if-else uses {}, both sides must use it' \
halt="if one side of if-else uses {}, both sides must use it" \
$(_sc_search_regexp)
sc_curly_braces_style:
@@ -961,7 +992,7 @@ sc_prohibit_static_zero_init:
sc_prohibit_devname:
@prohibit='\bdevname\b' \
exclude='sc_prohibit_devname' \
halt='avoid using devname as FreeBSD exports the symbol' \
halt='avoid using 'devname' as FreeBSD exports the symbol' \
$(_sc_search_regexp)
sc_prohibit_system_error_with_vir_err:
@@ -975,7 +1006,7 @@ sc_prohibit_system_error_with_vir_err:
sc_prohibit_virXXXFree:
@prohibit='\bvir(Domain|Network|NodeDevice|StorageVol|StoragePool|Stream|Secret|NWFilter|Interface|DomainSnapshot)Free\b' \
exclude='sc_prohibit_virXXXFree' \
halt='avoid using virXXXFree, use virObjectUnref instead' \
halt='avoid using 'virXXXFree', use 'virObjectUnref' instead' \
$(_sc_search_regexp)
sc_prohibit_sysconf_pagesize:
@@ -983,42 +1014,20 @@ sc_prohibit_sysconf_pagesize:
halt='use virGetSystemPageSize[KB] instead of sysconf(_SC_PAGESIZE)' \
$(_sc_search_regexp)
sc_prohibit_virSecurity:
@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:
@prohibit='\bpthread_create\b' \
exclude='sc_prohibit_pthread_create' \
halt='avoid using pthread_create, use virThreadCreate instead' \
halt="avoid using 'pthread_create', use 'virThreadCreate' instead" \
$(_sc_search_regexp)
sc_prohibit_not_streq:
@prohibit='! *STRN?EQ *\(.*\)' \
halt='Use STRNEQ instead of !STREQ and STREQ instead of !STRNEQ' \
@prohibit='! *STREQ *\(.*\)' \
halt='Use STRNEQ instead of !STREQ' \
$(_sc_search_regexp)
sc_prohibit_verbose_strcat:
@prohibit='strncat\([^,]*,\s+([^,]*),\s+strlen\(\1\)\)' \
in_vc_files='\.[ch]$$' \
halt='Use strcat(a, b) instead of strncat(a, b, strlen(b))' \
$(_sc_search_regexp)
# Ensure that each .c file containing a "main" function also
# calls virGettextInitialize
sc_gettext_init:
@require='virGettextInitialize *\(' \
in_vc_files='\.c$$' \
containing='\<main *(' \
halt='the above files do not call virGettextInitialize' \
$(_sc_search_regexp)
sc_prohibit_obj_free_apis_in_virsh:
@prohibit='\bvir(Domain|DomainSnapshot)Free\b' \
in_vc_files='virsh.*\.[ch]$$' \
exclude='sc_prohibit_obj_free_apis_in_virsh' \
halt='avoid using virDomain(Snapshot)Free in virsh, use virsh-prefixed wrappers instead' \
sc_prohibit_not_strneq:
@prohibit='! *STRNEQ *\(.*\)' \
halt='Use STREQ instead of !STRNEQ' \
$(_sc_search_regexp)
# We don't use this feature of maint.mk.
@@ -1026,30 +1035,33 @@ prev_version_file = /dev/null
ifneq ($(_gl-Makefile),)
ifeq (0,$(MAKELEVEL))
_dry_run_result := $(shell \
cd '$(srcdir)'; \
test -d .git || test -f .git || { echo 0; exit; }; \
$(srcdir)/autogen.sh --dry-run >/dev/null 2>&1; \
echo $$?; \
)
_curr_status = .git-module-status
# The sed filter accommodates those who check out on a commit from which
# no tag is reachable. In that case, git submodule status prints a "-"
# in column 1 and does not print a "git describe"-style string after the
# submodule name. Contrast these:
# -b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib
# b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib (v0.0-2286-gb653eda)
# $ cat .git-module-status
# b653eda3ac4864de205419d9f41eec267cb89eeb
#
# Keep this logic in sync with autogen.sh.
_submodule_hash = $(SED) 's/^[ +-]//;s/ .*//'
_update_required := $(shell \
cd '$(srcdir)'; \
test -d .git || { echo 0; exit; }; \
test -f po/Makevars || { echo 1; exit; }; \
test -f AUTHORS || { echo 1; exit; }; \
test "no-git" = "$$(cat $(_curr_status))" && { echo 0; exit; }; \
actual=$$(git submodule status | $(_submodule_hash); \
git hash-object bootstrap.conf; \
git ls-tree -d HEAD gnulib/local | awk '{print $$3}'; \
git diff .gnulib); \
stamp="$$($(_submodule_hash) $(_curr_status) 2>/dev/null)"; \
test "$$stamp" = "$$actual"; echo $$?)
_clean_requested = $(filter %clean,$(MAKECMDGOALS))
# A return value of 0 means no action is required
# A return value of 1 means a genuine error has occurred while
# performing the dry run, and it should be reported so it can
# be investigated
ifeq (1,$(_dry_run_result))
$(info INFO: autogen.sh error, running again to show details)
maint.mk Makefile: _autogen_error
endif
# A return value of 2 means that autogen.sh needs to be executed
# in earnest before building, probably because of gnulib updates.
# We don't run autogen.sh if the clean target has been invoked,
# though, as it would be quite pointless
ifeq (2,$(_dry_run_result)$(_clean_requested))
$(info INFO: running autogen.sh is required, running it now...)
ifeq (1,$(_update_required)$(_clean_requested))
$(info INFO: gnulib update required; running ./autogen.sh first)
$(shell touch $(srcdir)/AUTHORS $(srcdir)/ChangeLog)
maint.mk Makefile: _autogen
endif
@@ -1063,34 +1075,30 @@ _autogen:
$(srcdir)/autogen.sh
./config.status
.PHONY: _autogen_error
_autogen_error:
$(srcdir)/autogen.sh --dry-run
# regenerate HACKING as part of the syntax-check
ifneq ($(_gl-Makefile),)
syntax-check: $(top_srcdir)/HACKING spacing-check test-wrap-argv \
prohibit-duplicate-header mock-noinline
syntax-check: $(top_srcdir)/HACKING bracket-spacing-check test-wrap-argv
endif
# Don't include duplicate header in the source (either *.c or *.h)
prohibit-duplicate-header:
$(AM_V_GEN)files=$$($(VC_LIST_EXCEPT) | grep '\.[chx]$$'); \
$(PERL) -W $(top_srcdir)/build-aux/prohibit-duplicate-header.pl $$files
spacing-check:
bracket-spacing-check:
$(AM_V_GEN)files=`$(VC_LIST) | grep '\.c$$'`; \
$(PERL) $(top_srcdir)/build-aux/check-spacing.pl $$files || \
$(PERL) $(top_srcdir)/build-aux/bracket-spacing.pl $$files || \
{ echo '$(ME): incorrect formatting, see HACKING for rules' 1>&2; \
exit 1; }
mock-noinline:
$(AM_V_GEN)files=`$(VC_LIST) | grep '\.[ch]$$'`; \
$(PERL) $(top_srcdir)/build-aux/mock-noinline.pl $$files
test-wrap-argv:
$(AM_V_GEN)files=`$(VC_LIST) | grep -E '\.(ldargs|args)'`; \
$(PERL) $(top_srcdir)/tests/test-wrap-argv.pl --check $$files
for file in $$files ; \
do \
$(PERL) $(top_srcdir)/tests/test-wrap-argv.pl $$file > $${file}-t ; \
diff $$file $${file}-t; \
res=$$? ; \
rm $${file}-t ; \
test $$res == 0 || { \
echo "$(ME): Incorrect line wrapping in $$file" 1>&2; \
echo "$(ME): Use test-wrap-argv.pl to wrap test data files" 1>&2; \
exit 1; } \
done
# sc_po_check can fail if generated files are not built first
sc_po_check: \
@@ -1113,23 +1121,18 @@ $(srcdir)/src/admin/admin_client.h: $(srcdir)/src/admin/admin_protocol.x
# List all syntax-check exemptions:
exclude_file_name_regexp--sc_avoid_strcase = ^tools/vsh\.h$$
_src1=libvirt-stream|qemu/qemu_monitor|util/vir(command|file|fdstream)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon|logging/log_daemon
_src1=libvirt-stream|fdstream|qemu/qemu_monitor|util/(vircommand|virfile)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon|logging/log_daemon
_test1=shunloadtest|virnettlscontexttest|virnettlssessiontest|vircgroupmock
exclude_file_name_regexp--sc_avoid_write = \
^(src/($(_src1))|daemon/libvirtd|tools/virsh-console|tests/($(_test1)))\.c$$
exclude_file_name_regexp--sc_bindtextdomain = .*
exclude_file_name_regexp--sc_gettext_init = ^(tests|examples)/
exclude_file_name_regexp--sc_copyright_format = \
^cfg\.mk$$
exclude_file_name_regexp--sc_bindtextdomain = ^(tests|examples)/
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)mock\.c$$)
^(docs/|src/util/virnetdevtap\.c$$|tests/vir(cgroup|pci|usb)mock\.c$$)
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
^(src/rpc/gendispatch\.pl$$|tests/)
@@ -1137,25 +1140,21 @@ exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
exclude_file_name_regexp--sc_po_check = ^(docs/|src/rpc/gendispatch\.pl$$)
exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \
^(cfg\.mk|include/libvirt/virterror\.h|daemon/dispatch\.c|src/util/virerror\.c|docs/internals/oomtesting\.html\.in)$$
^(include/libvirt/virterror\.h|daemon/dispatch\.c|src/util/virerror\.c|docs/internals/oomtesting\.html\.in)$$
exclude_file_name_regexp--sc_prohibit_PATH_MAX = \
^cfg\.mk$$
exclude_file_name_regexp--sc_prohibit_access_xok = \
^(cfg\.mk|src/util/virutil\.c)$$
exclude_file_name_regexp--sc_prohibit_access_xok = ^src/util/virutil\.c$$
exclude_file_name_regexp--sc_prohibit_asprintf = \
^(cfg\.mk|bootstrap.conf$$|examples/|src/util/virstring\.[ch]$$|tests/vircgroupmock\.c$$)
^(bootstrap.conf$$|src/util/virstring\.[ch]$$|tests/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_prohibit_strdup = \
^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.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)$$)
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir(cgroup|pci)mock\.c)$$)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
(^tests/(qemuhelp|virhostcpu|virpcitest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
(^tests/(qemuhelp|nodeinfo|virpcitest)data/|\.diff$$)
_src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon|logging/log_daemon)
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
@@ -1170,13 +1169,10 @@ exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
^src/rpc/gendispatch\.pl$$
exclude_file_name_regexp--sc_prohibit_nonreentrant = \
^((po|tests)/|docs/.*(py|js|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
exclude_file_name_regexp--sc_prohibit_select = \
^cfg\.mk$$
^((po|tests)/|docs/.*(py|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
^(docs/hacking\.html\.in|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock)\.c|tools/wireshark/src/packet-libvirt\.c)$$
^(docs/hacking\.html\.in|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|vircgroupmock)\.c|tools/wireshark/src/packet-libvirt\.c)$$
exclude_file_name_regexp--sc_prohibit_readlink = \
^src/(util/virutil|lxc/lxc_container)\.c$$
@@ -1184,11 +1180,11 @@ exclude_file_name_regexp--sc_prohibit_readlink = \
exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/virutil\.c$$
exclude_file_name_regexp--sc_prohibit_sprintf = \
^(cfg\.mk|docs/hacking\.html\.in|.*\.stp|.*\.pl)$$
(^docs/hacking\.html\.in|\.stp|\.pl)$$
exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$
exclude_file_name_regexp--sc_prohibit_strtol = ^examples/.*$$
exclude_file_name_regexp--sc_prohibit_strtol = ^examples/dom.*/.*\.c$$
exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$
@@ -1203,10 +1199,10 @@ exclude_file_name_regexp--sc_require_config_h_first = \
^(examples/|tools/virsh-edit\.c$$)
exclude_file_name_regexp--sc_trailing_blank = \
/qemuhelpdata/|/sysinfodata/.*\.data|/virhostcpudata/.*\.cpuinfo$$
/qemuhelpdata/|/sysinfodata/.*\.data|/nodeinfodata/.*\.cpuinfo$$
exclude_file_name_regexp--sc_unmarked_diagnostics = \
^(docs/apibuild.py|tests/virt-aa-helper-test|docs/js/.*\.js)$$
^(docs/apibuild.py|tests/virt-aa-helper-test)$$
exclude_file_name_regexp--sc_size_of_brackets = cfg.mk
@@ -1222,10 +1218,7 @@ exclude_file_name_regexp--sc_prohibit_include_public_headers_brackets = \
^(tools/|examples/|include/libvirt/(virterror|libvirt(-(admin|qemu|lxc))?)\.h$$)
exclude_file_name_regexp--sc_prohibit_int_ijk = \
^(src/remote_protocol-structs|src/remote/remote_protocol\.x|cfg\.mk|include/libvirt/libvirt.+|src/admin_protocol-structs|src/admin/admin_protocol\.x)$$
exclude_file_name_regexp--sc_prohibit_unsigned_pid = \
^(include/libvirt/.*\.h|src/(qemu/qemu_driver\.c|driver-hypervisor\.h|libvirt(-[a-z]*)?\.c|.*\.x|util/vir(polkit|systemd)\.c)|tests/virpolkittest\.c|tools/virsh-domain\.c)$$
^(src/remote_protocol-structs|src/remote/remote_protocol\.x|cfg\.mk|include/libvirt/libvirt.+)$$
exclude_file_name_regexp--sc_prohibit_getenv = \
^tests/.*\.[ch]$$
@@ -1237,7 +1230,7 @@ exclude_file_name_regexp--sc_prohibit_mixed_case_abbreviations = \
^src/(vbox/vbox_CAPI.*.h|esx/esx_vi.(c|h)|esx/esx_storage_backend_iscsi.c)$$
exclude_file_name_regexp--sc_prohibit_empty_first_line = \
^(README|daemon/THREADS\.txt|src/esx/README|tests/(vmwarever|virhostcpu)data/.*)$$
^(README|daemon/THREADS\.txt|src/esx/README|docs/library.xen|tests/(vmwarever|nodeinfo)data/.*)$$
exclude_file_name_regexp--sc_prohibit_useless_translation = \
^tests/virpolkittest.c
@@ -1254,11 +1247,8 @@ exclude_file_name_regexp--sc_prohibit_sysconf_pagesize = \
exclude_file_name_regexp--sc_prohibit_pthread_create = \
^(cfg\.mk|src/util/virthread\.c|tests/.*)$$
exclude_file_name_regexp--sc_prohibit_always-defined_macros = \
^tests/virtestmock.c$$
exclude_file_name_regexp--sc_prohibit_not_streq = \
^tests/.*\.[ch]$$
exclude_file_name_regexp--sc_prohibit_readdir = \
^tests/.*mock\.c$$
exclude_file_name_regexp--sc_prohibit_cross_inclusion = \
^(src/util/virclosecallbacks\.h|src/util/virhostdev\.h)$$
exclude_file_name_regexp--sc_prohibit_not_strneq = \
^tests/.*\.[ch]$$

View File

@@ -20,74 +20,26 @@
* 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 __atttribute__((constructor)).
* The only way to avoid such deps is to re-compile the
* The only way avoid 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 :-(
*/
#ifdef LIBVIRT_SETUID_RPC_CLIENT
# undef HAVE_LIBDEVMAPPER_H
# undef HAVE_LIBNL
# undef HAVE_LIBNL3
# undef HAVE_LIBSASL2
# undef HAVE_SYS_ACL_H
# undef WITH_CAPNG
# undef WITH_CURL
# undef WITH_DBUS
# undef WITH_DEVMAPPER
# undef WITH_DTRACE_PROBES
# undef WITH_GNUTLS
# undef WITH_GNUTLS_GCRYPT
# undef WITH_LIBSSH
# undef WITH_MACVTAP
# undef WITH_NUMACTL
# undef WITH_SASL
# undef WITH_SSH2
# undef WITH_SYSTEMD_DAEMON
# undef WITH_VIRTUALPORT
# undef WITH_YAJL
# undef WITH_YAJL2
#endif
/*
* With the NSS module it's the same story as virt-login-shell. See the
* explanation above.
*/
#ifdef LIBVIRT_NSS
# undef HAVE_LIBNL
# undef HAVE_LIBNL3
# undef HAVE_LIBSASL2
# undef HAVE_SYS_ACL_H
# undef WITH_CAPNG
# undef WITH_CURL
# undef WITH_DEVMAPPER
# undef WITH_DTRACE_PROBES
# undef WITH_GNUTLS
# undef WITH_GNUTLS_GCRYPT
# undef WITH_LIBSSH
# undef WITH_MACVTAP
# undef WITH_NUMACTL
# undef WITH_SASL
# undef WITH_SSH2
# undef WITH_VIRTUALPORT
# undef WITH_SECDRIVER_SELINUX
# undef WITH_SECDRIVER_APPARMOR
# undef WITH_CAPNG
#endif /* LIBVIRT_NSS */
/*
* Define __GNUC__ to a sane default if it isn't yet defined.
* This is done here so that it's included as early as possible; gnulib relies
* on this to be defined in features.h, which should be included from ctype.h.
* This doesn't happen on many non-glibc systems.
* When __GNUC__ is not defined, gnulib defines it to 0, which breaks things.
*/
#ifdef __GNUC__
# ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
# else
# define __GNUC_PREREQ(maj, min) 0
# endif
# endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -31,8 +31,6 @@ INCLUDES = \
CLEANFILES =
WARN_CFLAGS += $(STRICT_FRAME_LIMIT_CFLAGS)
DAEMON_GENERATED = \
remote_dispatch.h \
lxc_dispatch.h \
@@ -48,14 +46,6 @@ DAEMON_SOURCES = \
LIBVIRTD_CONF_SOURCES = libvirtd-config.c libvirtd-config.h
PODFILES = \
libvirtd.pod \
$(NULL)
MANINFILES = \
libvirtd.8.in \
$(NULL)
DISTCLEANFILES =
EXTRA_DIST = \
remote_dispatch.h \
@@ -69,7 +59,7 @@ EXTRA_DIST = \
libvirt.rules \
libvirtd.sasl \
libvirtd.service.in \
virt-guest-shutdown.target \
libvirtd.socket.in \
libvirtd.sysconf \
libvirtd.sysctl \
libvirtd.aug \
@@ -80,8 +70,8 @@ EXTRA_DIST = \
libvirtd.uml.logrotate.in \
test_libvirtd.aug.in \
THREADS.txt \
$(PODFILES) \
$(MANINFILES) \
libvirtd.pod.in \
libvirtd.8.in \
$(DAEMON_SOURCES) \
$(LIBVIRTD_CONF_SOURCES) \
$(NULL)
@@ -138,7 +128,7 @@ libvirtd_conf_la_LIBADD = $(LIBXML_LIBS)
noinst_LTLIBRARIES += libvirtd_admin.la
libvirtd_admin_la_SOURCES = \
admin.c admin.h admin_server.c admin_server.h
admin_server.c admin_server.h
libvirtd_admin_la_CFLAGS = \
$(AM_CFLAGS) \
@@ -172,6 +162,13 @@ augeastests_DATA = test_libvirtd.aug
CLEANFILES += test_libvirtd.aug
libvirtd.8: $(srcdir)/libvirtd.8.in
$(AM_V_GEN)sed \
-e 's|[@]sysconfdir[@]|$(sysconfdir)|g' \
-e 's|[@]localstatedir[@]|$(localstatedir)|g' \
< $< > $@-t && \
mv $@-t $@
libvirtd_SOURCES = $(DAEMON_SOURCES)
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
@@ -236,10 +233,6 @@ if WITH_VBOX
libvirtd_LDADD += ../src/libvirt_driver_vbox.la
endif WITH_VBOX
if WITH_VZ
libvirtd_LDADD += ../src/libvirt_driver_vz.la
endif WITH_VZ
if WITH_STORAGE
libvirtd_LDADD += ../src/libvirt_driver_storage.la
endif WITH_STORAGE
@@ -326,8 +319,7 @@ endif ! WITH_POLKIT
remote.c: $(DAEMON_GENERATED)
remote.h: $(DAEMON_GENERATED)
admin.c: $(DAEMON_GENERATED)
admin.h: $(DAEMON_GENERATED)
admin_server.c: $(DAEMON_GENERATED)
LOGROTATE_CONFS = libvirtd.qemu.logrotate libvirtd.lxc.logrotate \
libvirtd.libxl.logrotate libvirtd.uml.logrotate \
@@ -453,18 +445,18 @@ endif ! LIBVIRT_INIT_SCRIPT_UPSTART
if LIBVIRT_INIT_SCRIPT_SYSTEMD
SYSTEMD_UNIT_DIR = $(prefix)/lib/systemd/system
BUILT_SOURCES += libvirtd.service
BUILT_SOURCES += libvirtd.service libvirtd.socket
install-init-systemd: install-sysconfig libvirtd.service
install-init-systemd: install-sysconfig libvirtd.service libvirtd.socket
$(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR)
$(INSTALL_DATA) libvirtd.service \
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
$(INSTALL_DATA) $(srcdir)/virt-guest-shutdown.target \
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/virt-guest-shutdown.target
$(INSTALL_DATA) libvirtd.socket \
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.socket
uninstall-init-systemd: uninstall-sysconfig
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/virt-guest-shutdown.target
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.socket
rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || :
else ! LIBVIRT_INIT_SCRIPT_SYSTEMD
install-init-systemd:
@@ -488,6 +480,12 @@ libvirtd.service: libvirtd.service.in $(top_builddir)/config.status
< $< > $@-t && \
mv $@-t $@
libvirtd.socket: libvirtd.socket.in $(top_builddir)/config.status
$(AM_V_GEN)sed \
-e 's|[@]runstatedir[@]|$(runstatedir)|g' \
< $< > $@-t && \
mv $@-t $@
check-local: check-augeas
@@ -511,24 +509,12 @@ install-data-local: install-data-sasl
uninstall-local:: uninstall-data-sasl
endif ! WITH_LIBVIRTD
POD2MAN = pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)"
POD2MAN = pod2man -c "Virtualization Support" \
-r "$(PACKAGE)-$(VERSION)" -s 8
%.8.in: %.pod
$(AM_V_GEN)$(POD2MAN) --section=8 $< $@-t1 && \
if grep 'POD ERROR' $@-t1; then rm $@-t1; exit 1; fi && \
sed \
-e 's|SYSCONFDIR|\@sysconfdir\@|g' \
-e 's|LOCALSTATEDIR|\@localstatedir\@|g' \
< $@-t1 > $@-t2 && \
rm -f $@-t1 && \
mv $@-t2 $@
%.8: %.8.in $(top_srcdir)/configure.ac
$(AM_V_GEN)sed \
-e 's|[@]sysconfdir[@]|$(sysconfdir)|g' \
-e 's|[@]localstatedir[@]|$(localstatedir)|g' \
< $< > $@-t && \
mv $@-t $@
$(srcdir)/libvirtd.8.in: libvirtd.pod.in $(top_srcdir)/configure.ac
$(AM_V_GEN)$(POD2MAN) --name LIBVIRTD $< $@ \
&& if grep 'POD ERROR' $@ ; then rm $@; exit 1; fi
# This is needed for clients too, so can't wrap in
# the WITH_LIBVIRTD conditional
@@ -549,4 +535,4 @@ endif ! WITH_SASL
CLEANFILES += $(BUILT_SOURCES) $(man8_MANS)
CLEANFILES += *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
MAINTAINERCLEANFILES = $(MANINFILES) $(DAEMON_GENERATED)
MAINTAINERCLEANFILES = $(srcdir)/libvirtd.8.in $(DAEMON_GENERATED)

View File

@@ -42,7 +42,7 @@ event loop thread handles I/O from the client socket, and once a
complete RPC message has been read off the wire (and optionally
decrypted), it will be placed on the 'dx' job queue for the
associated client object. The job condition will be signalled and
a worker will wakeup and process it.
a worker will wakup and process it.
The worker thread must quickly drop its locks on the server and
client to allow the main event loop thread to continue running

View File

@@ -1,490 +0,0 @@
/*
* admin.c: handlers for admin RPC method calls
*
* Copyright (C) 2014-2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* 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: Martin Kletzander <mkletzan@redhat.com>
*/
#include <config.h>
#include "internal.h"
#include "libvirtd.h"
#include "libvirt_internal.h"
#include "admin_protocol.h"
#include "admin.h"
#include "admin_server.h"
#include "datatypes.h"
#include "viralloc.h"
#include "virerror.h"
#include "virlog.h"
#include "virnetdaemon.h"
#include "virnetserver.h"
#include "virstring.h"
#include "virthreadjob.h"
#include "virtypedparam.h"
#define VIR_FROM_THIS VIR_FROM_ADMIN
VIR_LOG_INIT("daemon.admin");
void
remoteAdmClientFreeFunc(void *data)
{
struct daemonAdmClientPrivate *priv = data;
virMutexDestroy(&priv->lock);
virObjectUnref(priv->dmn);
VIR_FREE(priv);
}
void *
remoteAdmClientInitHook(virNetServerClientPtr client ATTRIBUTE_UNUSED,
void *opaque)
{
struct daemonAdmClientPrivate *priv;
if (VIR_ALLOC(priv) < 0)
return NULL;
if (virMutexInit(&priv->lock) < 0) {
VIR_FREE(priv);
virReportSystemError(errno, "%s", _("unable to init mutex"));
return NULL;
}
/*
* We don't necessarily need to ref this object right now as there
* must be one ref being held throughout the life of the daemon,
* but let's just be safe for future.
*/
priv->dmn = virObjectRef(opaque);
return priv;
}
/* Helpers */
static virNetServerPtr
get_nonnull_server(virNetDaemonPtr dmn, admin_nonnull_server srv)
{
return virNetDaemonGetServer(dmn, srv.name);
}
static void
make_nonnull_server(admin_nonnull_server *srv_dst,
virNetServerPtr srv_src)
{
ignore_value(VIR_STRDUP_QUIET(srv_dst->name, virNetServerGetName(srv_src)));
}
static virNetServerClientPtr
get_nonnull_client(virNetServerPtr srv, admin_nonnull_client clnt)
{
return virNetServerGetClient(srv, clnt.id);
}
static void
make_nonnull_client(admin_nonnull_client *clt_dst,
virNetServerClientPtr clt_src)
{
clt_dst->id = virNetServerClientGetID(clt_src);
clt_dst->timestamp = virNetServerClientGetTimestamp(clt_src);
clt_dst->transport = virNetServerClientGetTransport(clt_src);
}
/* Functions */
static int
adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
struct admin_connect_open_args *args)
{
unsigned int flags;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
int ret = -1;
VIR_DEBUG("priv=%p dmn=%p", priv, priv->dmn);
virMutexLock(&priv->lock);
flags = args->flags;
virCheckFlagsGoto(0, cleanup);
ret = 0;
cleanup:
if (ret < 0)
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
return ret;
}
static int
adminDispatchConnectClose(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED)
{
virNetServerClientDelayedClose(client);
return 0;
}
static int
adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
unsigned long long *libVer)
{
if (libVer)
*libVer = LIBVIR_VERSION_NUMBER;
return 0;
}
static int
adminDispatchServerGetThreadpoolParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
struct admin_server_get_threadpool_parameters_args *args,
struct admin_server_get_threadpool_parameters_ret *ret)
{
int rv = -1;
virNetServerPtr srv = NULL;
virTypedParameterPtr params = NULL;
int nparams = 0;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
if (!(srv = virNetDaemonGetServer(priv->dmn, args->srv.name)))
goto cleanup;
if (adminServerGetThreadPoolParameters(srv, &params, &nparams,
args->flags) < 0)
goto cleanup;
if (nparams > ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of threadpool parameters %d exceeds max "
"allowed limit: %d"), nparams,
ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX);
goto cleanup;
}
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len, 0) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
virTypedParamsFree(params, nparams);
virObjectUnref(srv);
return rv;
}
static int
adminDispatchServerSetThreadpoolParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
struct admin_server_set_threadpool_parameters_args *args)
{
int rv = -1;
virNetServerPtr srv = NULL;
virTypedParameterPtr params = NULL;
int nparams = 0;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
if (!(srv = virNetDaemonGetServer(priv->dmn, args->srv.name))) {
virReportError(VIR_ERR_NO_SERVER,
_("no server with matching name '%s' found"),
args->srv.name);
goto cleanup;
}
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) args->params.params_val,
args->params.params_len,
ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX,
&params,
&nparams) < 0)
goto cleanup;
if (adminServerSetThreadPoolParameters(srv, params,
nparams, args->flags) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
virTypedParamsFree(params, nparams);
virObjectUnref(srv);
return rv;
}
static int
adminDispatchClientGetInfo(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
struct admin_client_get_info_args *args,
struct admin_client_get_info_ret *ret)
{
int rv = -1;
virNetServerPtr srv = NULL;
virNetServerClientPtr clnt = NULL;
virTypedParameterPtr params = NULL;
int nparams = 0;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
if (!(srv = virNetDaemonGetServer(priv->dmn, args->clnt.srv.name))) {
virReportError(VIR_ERR_NO_SERVER,
_("no server with matching name '%s' found"),
args->clnt.srv.name);
goto cleanup;
}
if (!(clnt = virNetServerGetClient(srv, args->clnt.id))) {
virReportError(VIR_ERR_NO_CLIENT,
_("no client with matching id '%llu' found"),
(unsigned long long) args->clnt.id);
goto cleanup;
}
if (adminClientGetInfo(clnt, &params, &nparams, args->flags) < 0)
goto cleanup;
if (nparams > ADMIN_CLIENT_INFO_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of client info parameters %d exceeds max "
"allowed limit: %d"), nparams,
ADMIN_CLIENT_INFO_PARAMETERS_MAX);
goto cleanup;
}
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
virTypedParamsFree(params, nparams);
virObjectUnref(clnt);
virObjectUnref(srv);
return rv;
}
static int
adminDispatchServerGetClientLimits(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
admin_server_get_client_limits_args *args,
admin_server_get_client_limits_ret *ret)
{
int rv = -1;
virNetServerPtr srv = NULL;
virTypedParameterPtr params = NULL;
int nparams = 0;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
if (!(srv = virNetDaemonGetServer(priv->dmn, args->srv.name)))
goto cleanup;
if (adminServerGetClientLimits(srv, &params, &nparams, args->flags) < 0)
goto cleanup;
if (nparams > ADMIN_SERVER_CLIENT_LIMITS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of client processing parameters %d exceeds "
"max allowed limit: %d"), nparams,
ADMIN_SERVER_CLIENT_LIMITS_MAX);
goto cleanup;
}
if (virTypedParamsSerialize(params, nparams,
(virTypedParameterRemotePtr *) &ret->params.params_val,
&ret->params.params_len, 0) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
virTypedParamsFree(params, nparams);
virObjectUnref(srv);
return rv;
}
static int
adminDispatchServerSetClientLimits(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
admin_server_set_client_limits_args *args)
{
int rv = -1;
virNetServerPtr srv = NULL;
virTypedParameterPtr params = NULL;
int nparams = 0;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
if (!(srv = virNetDaemonGetServer(priv->dmn, args->srv.name))) {
virReportError(VIR_ERR_NO_SERVER,
_("no server with matching name '%s' found"),
args->srv.name);
goto cleanup;
}
if (virTypedParamsDeserialize((virTypedParameterRemotePtr) args->params.params_val,
args->params.params_len,
ADMIN_SERVER_CLIENT_LIMITS_MAX, &params, &nparams) < 0)
goto cleanup;
if (adminServerSetClientLimits(srv, params, nparams, args->flags) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
virTypedParamsFree(params, nparams);
virObjectUnref(srv);
return rv;
}
/* Returns the number of outputs stored in @outputs */
static int
adminConnectGetLoggingOutputs(char **outputs, unsigned int flags)
{
char *tmp = NULL;
virCheckFlags(0, -1);
if (!(tmp = virLogGetOutputs()))
return -1;
*outputs = tmp;
return virLogGetNbOutputs();
}
/* Returns the number of defined filters or -1 in case of an error */
static int
adminConnectGetLoggingFilters(char **filters, unsigned int flags)
{
char *tmp = NULL;
int ret = 0;
virCheckFlags(0, -1);
if ((ret = virLogGetNbFilters()) > 0 && !(tmp = virLogGetFilters()))
return -1;
*filters = tmp;
return ret;
}
static int
adminConnectSetLoggingOutputs(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
const char *outputs,
unsigned int flags)
{
virCheckFlags(0, -1);
return virLogSetOutputs(outputs);
}
static int
adminConnectSetLoggingFilters(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
const char *filters,
unsigned int flags)
{
virCheckFlags(0, -1);
return virLogSetFilters(filters);
}
static int
adminDispatchConnectGetLoggingOutputs(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client ATTRIBUTE_UNUSED,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
admin_connect_get_logging_outputs_args *args,
admin_connect_get_logging_outputs_ret *ret)
{
char *outputs = NULL;
int noutputs = 0;
if ((noutputs = adminConnectGetLoggingOutputs(&outputs, args->flags) < 0)) {
virNetMessageSaveError(rerr);
return -1;
}
VIR_STEAL_PTR(ret->outputs, outputs);
ret->noutputs = noutputs;
return 0;
}
static int
adminDispatchConnectGetLoggingFilters(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client ATTRIBUTE_UNUSED,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
admin_connect_get_logging_filters_args *args,
admin_connect_get_logging_filters_ret *ret)
{
char *filters = NULL;
int nfilters = 0;
if ((nfilters = adminConnectGetLoggingFilters(&filters, args->flags)) < 0) {
virNetMessageSaveError(rerr);
return -1;
}
if (nfilters == 0) {
ret->filters = NULL;
} else {
char **ret_filters = NULL;
if (VIR_ALLOC(ret_filters) < 0)
return -1;
*ret_filters = filters;
ret->filters = ret_filters;
}
ret->nfilters = nfilters;
return 0;
}
#include "admin_dispatch.h"

View File

@@ -1,7 +1,7 @@
/*
* admin_server.c: admin methods to manage daemons and clients
* admin_server.c:
*
* Copyright (C) 2016 Red Hat, Inc.
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,374 +17,110 @@
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Authors: Erik Skultety <eskultet@redhat.com>
* Martin Kletzander <mkletzan@redhat.com>
* Author: Martin Kletzander <mkletzan@redhat.com>
*/
#include <config.h>
#include "internal.h"
#include "libvirtd.h"
#include "libvirt_internal.h"
#include "admin_protocol.h"
#include "admin_server.h"
#include "datatypes.h"
#include "viralloc.h"
#include "virerror.h"
#include "viridentity.h"
#include "virlog.h"
#include "virnetdaemon.h"
#include "virnetserver.h"
#include "virstring.h"
#include "virthreadpool.h"
#include "virtypedparam.h"
#include "virthreadjob.h"
#define VIR_FROM_THIS VIR_FROM_ADMIN
VIR_LOG_INIT("daemon.admin_server");
VIR_LOG_INIT("daemon.admin");
int
adminConnectListServers(virNetDaemonPtr dmn,
virNetServerPtr **servers,
unsigned int flags)
void
remoteAdmClientFreeFunc(void *data)
{
int ret = -1;
virNetServerPtr *srvs = NULL;
struct daemonAdmClientPrivate *priv = data;
virCheckFlags(0, -1);
if ((ret = virNetDaemonGetServers(dmn, &srvs)) < 0)
goto cleanup;
if (servers) {
*servers = srvs;
srvs = NULL;
}
cleanup:
if (ret > 0)
virObjectListFreeCount(srvs, ret);
return ret;
virMutexDestroy(&priv->lock);
virObjectUnref(priv->dmn);
VIR_FREE(priv);
}
virNetServerPtr
adminConnectLookupServer(virNetDaemonPtr dmn,
const char *name,
unsigned int flags)
void *
remoteAdmClientInitHook(virNetServerClientPtr client ATTRIBUTE_UNUSED,
void *opaque)
{
virCheckFlags(flags, NULL);
struct daemonAdmClientPrivate *priv;
return virNetDaemonGetServer(dmn, name);
}
if (VIR_ALLOC(priv) < 0)
return NULL;
int
adminServerGetThreadPoolParameters(virNetServerPtr srv,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
int ret = -1;
int maxparams = 0;
size_t minWorkers;
size_t maxWorkers;
size_t nWorkers;
size_t freeWorkers;
size_t nPrioWorkers;
size_t jobQueueDepth;
virTypedParameterPtr tmpparams = NULL;
virCheckFlags(0, -1);
if (virNetServerGetThreadPoolParameters(srv, &minWorkers, &maxWorkers,
&nWorkers, &freeWorkers,
&nPrioWorkers,
&jobQueueDepth) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to retrieve threadpool parameters"));
goto cleanup;
if (virMutexInit(&priv->lock) < 0) {
VIR_FREE(priv);
virReportSystemError(errno, "%s", _("unable to init mutex"));
return NULL;
}
if (virTypedParamsAddUInt(&tmpparams, nparams,
&maxparams, VIR_THREADPOOL_WORKERS_MIN,
minWorkers) < 0)
goto cleanup;
/*
* We don't necessarily need to ref this object right now as there
* must be one ref being held throughout the life of the daemon,
* but let's just be safe for future.
*/
priv->dmn = virObjectRef(opaque);
if (virTypedParamsAddUInt(&tmpparams, nparams,
&maxparams, VIR_THREADPOOL_WORKERS_MAX,
maxWorkers) < 0)
goto cleanup;
return priv;
}
if (virTypedParamsAddUInt(&tmpparams, nparams,
&maxparams, VIR_THREADPOOL_WORKERS_CURRENT,
nWorkers) < 0)
goto cleanup;
/* Functions */
static int
adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
struct admin_connect_open_args *args)
{
unsigned int flags;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
int ret = -1;
if (virTypedParamsAddUInt(&tmpparams, nparams,
&maxparams, VIR_THREADPOOL_WORKERS_FREE,
freeWorkers) < 0)
goto cleanup;
VIR_DEBUG("priv=%p dmn=%p", priv, priv->dmn);
virMutexLock(&priv->lock);
if (virTypedParamsAddUInt(&tmpparams, nparams,
&maxparams, VIR_THREADPOOL_WORKERS_PRIORITY,
nPrioWorkers) < 0)
goto cleanup;
flags = args->flags;
virCheckFlagsGoto(0, cleanup);
if (virTypedParamsAddUInt(&tmpparams, nparams,
&maxparams, VIR_THREADPOOL_JOB_QUEUE_DEPTH,
jobQueueDepth) < 0)
goto cleanup;
*params = tmpparams;
tmpparams = NULL;
ret = 0;
cleanup:
virTypedParamsFree(tmpparams, *nparams);
if (ret < 0)
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
return ret;
}
int
adminServerSetThreadPoolParameters(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags)
static int
adminDispatchConnectClose(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED)
{
long long int minWorkers = -1;
long long int maxWorkers = -1;
long long int prioWorkers = -1;
virTypedParameterPtr param = NULL;
virCheckFlags(0, -1);
if (virTypedParamsValidate(params, nparams,
VIR_THREADPOOL_WORKERS_MIN,
VIR_TYPED_PARAM_UINT,
VIR_THREADPOOL_WORKERS_MAX,
VIR_TYPED_PARAM_UINT,
VIR_THREADPOOL_WORKERS_PRIORITY,
VIR_TYPED_PARAM_UINT,
NULL) < 0)
return -1;
if ((param = virTypedParamsGet(params, nparams,
VIR_THREADPOOL_WORKERS_MIN)))
minWorkers = param->value.ui;
if ((param = virTypedParamsGet(params, nparams,
VIR_THREADPOOL_WORKERS_MAX)))
maxWorkers = param->value.ui;
if ((param = virTypedParamsGet(params, nparams,
VIR_THREADPOOL_WORKERS_PRIORITY)))
prioWorkers = param->value.ui;
if (virNetServerSetThreadPoolParameters(srv, minWorkers,
maxWorkers, prioWorkers) < 0)
return -1;
virNetServerClientDelayedClose(client);
return 0;
}
int
adminServerListClients(virNetServerPtr srv,
virNetServerClientPtr **clients,
unsigned int flags)
static int
adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
unsigned long long *libVer)
{
int ret = -1;
virNetServerClientPtr *clts;
virCheckFlags(0, -1);
if ((ret = virNetServerGetClients(srv, &clts)) < 0)
return -1;
if (clients) {
*clients = clts;
clts = NULL;
}
virObjectListFreeCount(clts, ret);
return ret;
}
virNetServerClientPtr
adminServerLookupClient(virNetServerPtr srv,
unsigned long long id,
unsigned int flags)
{
virCheckFlags(0, NULL);
return virNetServerGetClient(srv, id);
}
int
adminClientGetInfo(virNetServerClientPtr client,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
int ret = -1;
int maxparams = 0;
bool readonly;
char *sock_addr = NULL;
const char *attr = NULL;
virTypedParameterPtr tmpparams = NULL;
virIdentityPtr identity = NULL;
virCheckFlags(0, -1);
if (virNetServerClientGetInfo(client, &readonly,
&sock_addr, &identity) < 0)
goto cleanup;
if (virTypedParamsAddBoolean(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_READONLY,
readonly) < 0)
goto cleanup;
if (virIdentityGetSASLUserName(identity, &attr) < 0 ||
(attr &&
virTypedParamsAddString(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_SASL_USER_NAME,
attr) < 0))
goto cleanup;
if (!virNetServerClientIsLocal(client)) {
if (virTypedParamsAddString(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_SOCKET_ADDR,
sock_addr) < 0)
goto cleanup;
if (virIdentityGetX509DName(identity, &attr) < 0 ||
(attr &&
virTypedParamsAddString(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_X509_DISTINGUISHED_NAME,
attr) < 0))
goto cleanup;
} else {
pid_t pid;
uid_t uid;
gid_t gid;
if (virIdentityGetUNIXUserID(identity, &uid) < 0 ||
virTypedParamsAddInt(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_UNIX_USER_ID, uid) < 0)
goto cleanup;
if (virIdentityGetUNIXUserName(identity, &attr) < 0 ||
virTypedParamsAddString(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_UNIX_USER_NAME,
attr) < 0)
goto cleanup;
if (virIdentityGetUNIXGroupID(identity, &gid) < 0 ||
virTypedParamsAddInt(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_UNIX_GROUP_ID, gid) < 0)
goto cleanup;
if (virIdentityGetUNIXGroupName(identity, &attr) < 0 ||
virTypedParamsAddString(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_UNIX_GROUP_NAME,
attr) < 0)
goto cleanup;
if (virIdentityGetUNIXProcessID(identity, &pid) < 0 ||
virTypedParamsAddInt(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_UNIX_PROCESS_ID, pid) < 0)
goto cleanup;
}
if (virIdentityGetSELinuxContext(identity, &attr) < 0 ||
(attr &&
virTypedParamsAddString(&tmpparams, nparams, &maxparams,
VIR_CLIENT_INFO_SELINUX_CONTEXT, attr) < 0))
goto cleanup;
*params = tmpparams;
tmpparams = NULL;
ret = 0;
cleanup:
virObjectUnref(identity);
VIR_FREE(sock_addr);
return ret;
}
int adminClientClose(virNetServerClientPtr client,
unsigned int flags)
{
virCheckFlags(0, -1);
virNetServerClientClose(client);
if (libVer)
*libVer = LIBVIR_VERSION_NUMBER;
return 0;
}
int
adminServerGetClientLimits(virNetServerPtr srv,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
int ret = -1;
int maxparams = 0;
virTypedParameterPtr tmpparams = NULL;
virCheckFlags(0, -1);
if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams,
VIR_SERVER_CLIENTS_MAX,
virNetServerGetMaxClients(srv)) < 0)
goto cleanup;
if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams,
VIR_SERVER_CLIENTS_CURRENT,
virNetServerGetCurrentClients(srv)) < 0)
goto cleanup;
if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams,
VIR_SERVER_CLIENTS_UNAUTH_MAX,
virNetServerGetMaxUnauthClients(srv)) < 0)
goto cleanup;
if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams,
VIR_SERVER_CLIENTS_UNAUTH_CURRENT,
virNetServerGetCurrentUnauthClients(srv)) < 0)
goto cleanup;
*params = tmpparams;
tmpparams = NULL;
ret = 0;
cleanup:
virTypedParamsFree(tmpparams, *nparams);
return ret;
}
int
adminServerSetClientLimits(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags)
{
long long int maxClients = -1;
long long int maxClientsUnauth = -1;
virTypedParameterPtr param = NULL;
virCheckFlags(0, -1);
if (virTypedParamsValidate(params, nparams,
VIR_SERVER_CLIENTS_MAX,
VIR_TYPED_PARAM_UINT,
VIR_SERVER_CLIENTS_UNAUTH_MAX,
VIR_TYPED_PARAM_UINT,
NULL) < 0)
return -1;
if ((param = virTypedParamsGet(params, nparams,
VIR_SERVER_CLIENTS_MAX)))
maxClients = param->value.ui;
if ((param = virTypedParamsGet(params, nparams,
VIR_SERVER_CLIENTS_UNAUTH_MAX)))
maxClientsUnauth = param->value.ui;
if (virNetServerSetClientLimits(srv, maxClients,
maxClientsUnauth) < 0)
return -1;
return 0;
}
#include "admin_dispatch.h"

View File

@@ -1,7 +1,7 @@
/*
* admin_server.h: admin methods to manage daemons and clients
* admin_server.h
*
* Copyright (C) 2016 Red Hat, Inc.
* Copyright (C) 2014 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,59 +17,20 @@
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Authors: Erik Skultety <eskultet@redhat.com>
* Martin Kletzander <mkletzan@redhat.com>
* Author: Martin Kletzander <mkletzan@redhat.com>
*/
#ifndef __LIBVIRTD_ADMIN_SERVER_H__
# define __LIBVIRTD_ADMIN_SERVER_H__
#ifndef __LIBVIRTD_ADMIN_H__
# define __LIBVIRTD_ADMIN_H__
# include "rpc/virnetdaemon.h"
# include "rpc/virnetserver.h"
# include "rpc/virnetserverprogram.h"
# include "rpc/virnetserverclient.h"
int adminConnectListServers(virNetDaemonPtr dmn,
virNetServerPtr **servers,
unsigned int flags);
virNetServerPtr adminConnectLookupServer(virNetDaemonPtr dmn,
const char *name,
unsigned int flags);
extern virNetServerProgramProc adminProcs[];
extern size_t adminNProcs;
int
adminServerGetThreadPoolParameters(virNetServerPtr srv,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags);
int
adminServerSetThreadPoolParameters(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags);
void remoteAdmClientFreeFunc(void *data);
void *remoteAdmClientInitHook(virNetServerClientPtr client, void *opaque);
int adminServerListClients(virNetServerPtr srv,
virNetServerClientPtr **clients,
unsigned int flags);
virNetServerClientPtr adminServerLookupClient(virNetServerPtr srv,
unsigned long long id,
unsigned int flags);
int adminClientGetInfo(virNetServerClientPtr client,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags);
int adminClientClose(virNetServerClientPtr client,
unsigned int flags);
int adminServerGetClientLimits(virNetServerPtr srv,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags);
int adminServerSetClientLimits(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags);
#endif /* __LIBVIRTD_ADMIN_SERVER_H__ */
#endif /* __ADMIN_REMOTE_H__ */

View File

@@ -32,7 +32,6 @@
#include "configmake.h"
#include "remote/remote_protocol.h"
#include "remote/remote_driver.h"
#include "util/virnetdevopenvswitch.h"
#include "virstring.h"
#include "virutil.h"
@@ -40,38 +39,171 @@
VIR_LOG_INIT("daemon.libvirtd-config");
/* Allocate an array of malloc'd strings from the config file, filename
* (used only in diagnostics), using handle "conf". Upon error, return -1
* and free any allocated memory. Otherwise, save the array in *list_arg
* and return 0.
*/
static int
remoteConfigGetAuth(virConfPtr conf,
const char *filename,
const char *key,
int *auth)
remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
const char *filename)
{
char *authstr = NULL;
if (virConfGetValueString(conf, key, &authstr) < 0)
return -1;
if (!authstr)
char **list;
virConfValuePtr p = virConfGetValue(conf, key);
if (!p)
return 0;
if (STREQ(authstr, "none")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
#if WITH_SASL
} else if (STREQ(authstr, "sasl")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
#endif
} else if (STREQ(authstr, "polkit")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
} else {
switch (p->type) {
case VIR_CONF_STRING:
if (VIR_ALLOC_N(list, 2) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("failed to allocate memory for %s config list"),
key);
return -1;
}
if (VIR_STRDUP(list[0], p->str) < 0) {
VIR_FREE(list);
return -1;
}
list[1] = NULL;
break;
case VIR_CONF_LIST: {
int len = 0;
size_t i;
virConfValuePtr pp;
for (pp = p->list; pp; pp = pp->next)
len++;
if (VIR_ALLOC_N(list, 1+len) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("failed to allocate memory for %s config list"),
key);
return -1;
}
for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
if (pp->type != VIR_CONF_STRING) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("remoteReadConfigFile: %s: %s:"
" must be a string or list of strings"),
filename, key);
VIR_FREE(list);
return -1;
}
if (VIR_STRDUP(list[i], pp->str) < 0) {
size_t j;
for (j = 0; j < i; j++)
VIR_FREE(list[j]);
VIR_FREE(list);
return -1;
}
}
list[i] = NULL;
break;
}
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("%s: %s: unsupported auth %s"),
filename, key, authstr);
VIR_FREE(authstr);
_("remoteReadConfigFile: %s: %s:"
" must be a string or list of strings"),
filename, key);
return -1;
}
*list_arg = list;
return 0;
}
/* A helper function used by each of the following macros. */
static int
checkType(virConfValuePtr p, const char *filename,
const char *key, virConfType required_type)
{
if (p->type != required_type) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("remoteReadConfigFile: %s: %s: invalid type:"
" got %s; expected %s"), filename, key,
virConfTypeToString(p->type),
virConfTypeToString(required_type));
return -1;
}
return 0;
}
/* If there is no config data for the key, #var_name, then do nothing.
If there is valid data of type VIR_CONF_STRING, and VIR_STRDUP succeeds,
store the result in var_name. Otherwise, (i.e. invalid type, or VIR_STRDUP
failure), give a diagnostic and "goto" the cleanup-and-fail label. */
#define GET_CONF_STR(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue(conf, #var_name); \
if (p) { \
if (checkType(p, filename, #var_name, VIR_CONF_STRING) < 0) \
goto error; \
VIR_FREE(data->var_name); \
if (VIR_STRDUP(data->var_name, p->str) < 0) \
goto error; \
} \
} while (0)
/* Like GET_CONF_STR, but for signed integral values. */
#define GET_CONF_INT(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue(conf, #var_name); \
if (p) { \
if (p->type != VIR_CONF_ULONG && \
checkType(p, filename, #var_name, VIR_CONF_LONG) < 0) \
goto error; \
data->var_name = p->l; \
} \
} while (0)
/* Like GET_CONF_STR, but for unsigned integral values. */
#define GET_CONF_UINT(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue(conf, #var_name); \
if (p) { \
if (checkType(p, filename, #var_name, VIR_CONF_ULONG) < 0) \
goto error; \
data->var_name = p->l; \
} \
} while (0)
static int
remoteConfigGetAuth(virConfPtr conf,
const char *key,
int *auth,
const char *filename)
{
virConfValuePtr p;
p = virConfGetValue(conf, key);
if (!p)
return 0;
if (checkType(p, filename, key, VIR_CONF_STRING) < 0)
return -1;
if (!p->str)
return 0;
if (STREQ(p->str, "none")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
#if WITH_SASL
} else if (STREQ(p->str, "sasl")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
#endif
} else if (STREQ(p->str, "polkit")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("remoteReadConfigFile: %s: %s: unsupported auth %s"),
filename, key, p->str);
return -1;
}
VIR_FREE(authstr);
return 0;
}
@@ -148,7 +280,6 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
data->min_workers = 5;
data->max_workers = 20;
data->max_clients = 5000;
data->max_queued_clients = 1000;
data->max_anonymous_clients = 20;
data->prio_workers = 5;
@@ -171,8 +302,6 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
data->admin_keepalive_interval = 5;
data->admin_keepalive_count = 5;
data->ovs_timeout = VIR_NETDEV_OVS_DEFAULT_TIMEOUT;
localhost = virGetHostname();
if (localhost == NULL) {
/* we couldn't resolve the hostname; assume that we are
@@ -237,7 +366,6 @@ daemonConfigFree(struct daemonConfig *data)
tmp++;
}
VIR_FREE(data->sasl_allowed_username_list);
VIR_FREE(data->tls_priority);
VIR_FREE(data->key_file);
VIR_FREE(data->ca_file);
@@ -245,7 +373,6 @@ daemonConfigFree(struct daemonConfig *data)
VIR_FREE(data->crl_file);
VIR_FREE(data->host_uuid);
VIR_FREE(data->host_uuid_source);
VIR_FREE(data->log_filters);
VIR_FREE(data->log_outputs);
@@ -257,18 +384,13 @@ daemonConfigLoadOptions(struct daemonConfig *data,
const char *filename,
virConfPtr conf)
{
if (virConfGetValueBool(conf, "listen_tcp", &data->listen_tcp) < 0)
goto error;
if (virConfGetValueBool(conf, "listen_tls", &data->listen_tls) < 0)
goto error;
if (virConfGetValueString(conf, "tls_port", &data->tls_port) < 0)
goto error;
if (virConfGetValueString(conf, "tcp_port", &data->tcp_port) < 0)
goto error;
if (virConfGetValueString(conf, "listen_addr", &data->listen_addr) < 0)
goto error;
GET_CONF_UINT(conf, filename, listen_tcp);
GET_CONF_UINT(conf, filename, listen_tls);
GET_CONF_STR(conf, filename, tls_port);
GET_CONF_STR(conf, filename, tcp_port);
GET_CONF_STR(conf, filename, listen_addr);
if (remoteConfigGetAuth(conf, filename, "auth_unix_rw", &data->auth_unix_rw) < 0)
if (remoteConfigGetAuth(conf, "auth_unix_rw", &data->auth_unix_rw, filename) < 0)
goto error;
#if WITH_POLKIT
/* Change default perms to be wide-open if PolicyKit is enabled.
@@ -280,119 +402,76 @@ daemonConfigLoadOptions(struct daemonConfig *data,
goto error;
}
#endif
if (remoteConfigGetAuth(conf, filename, "auth_unix_ro", &data->auth_unix_ro) < 0)
if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
goto error;
if (remoteConfigGetAuth(conf, filename, "auth_tcp", &data->auth_tcp) < 0)
if (remoteConfigGetAuth(conf, "auth_tcp", &data->auth_tcp, filename) < 0)
goto error;
if (remoteConfigGetAuth(conf, filename, "auth_tls", &data->auth_tls) < 0)
if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
goto error;
if (virConfGetValueStringList(conf, "access_drivers", false,
&data->access_drivers) < 0)
if (remoteConfigGetStringList(conf, "access_drivers",
&data->access_drivers, filename) < 0)
goto error;
if (virConfGetValueString(conf, "unix_sock_group", &data->unix_sock_group) < 0)
goto error;
if (virConfGetValueString(conf, "unix_sock_admin_perms", &data->unix_sock_admin_perms) < 0)
goto error;
if (virConfGetValueString(conf, "unix_sock_ro_perms", &data->unix_sock_ro_perms) < 0)
goto error;
if (virConfGetValueString(conf, "unix_sock_rw_perms", &data->unix_sock_rw_perms) < 0)
goto error;
GET_CONF_STR(conf, filename, unix_sock_group);
GET_CONF_STR(conf, filename, unix_sock_admin_perms);
GET_CONF_STR(conf, filename, unix_sock_ro_perms);
GET_CONF_STR(conf, filename, unix_sock_rw_perms);
if (virConfGetValueString(conf, "unix_sock_dir", &data->unix_sock_dir) < 0)
goto error;
GET_CONF_STR(conf, filename, unix_sock_dir);
if (virConfGetValueBool(conf, "mdns_adv", &data->mdns_adv) < 0)
goto error;
if (virConfGetValueString(conf, "mdns_name", &data->mdns_name) < 0)
goto error;
GET_CONF_UINT(conf, filename, mdns_adv);
GET_CONF_STR(conf, filename, mdns_name);
if (virConfGetValueBool(conf, "tls_no_sanity_certificate", &data->tls_no_sanity_certificate) < 0)
goto error;
if (virConfGetValueBool(conf, "tls_no_verify_certificate", &data->tls_no_verify_certificate) < 0)
goto error;
GET_CONF_UINT(conf, filename, tls_no_sanity_certificate);
GET_CONF_UINT(conf, filename, tls_no_verify_certificate);
if (virConfGetValueString(conf, "key_file", &data->key_file) < 0)
goto error;
if (virConfGetValueString(conf, "cert_file", &data->cert_file) < 0)
goto error;
if (virConfGetValueString(conf, "ca_file", &data->ca_file) < 0)
goto error;
if (virConfGetValueString(conf, "crl_file", &data->crl_file) < 0)
goto error;
GET_CONF_STR(conf, filename, key_file);
GET_CONF_STR(conf, filename, cert_file);
GET_CONF_STR(conf, filename, ca_file);
GET_CONF_STR(conf, filename, crl_file);
if (virConfGetValueStringList(conf, "tls_allowed_dn_list", false,
&data->tls_allowed_dn_list) < 0)
if (remoteConfigGetStringList(conf, "tls_allowed_dn_list",
&data->tls_allowed_dn_list, filename) < 0)
goto error;
if (virConfGetValueStringList(conf, "sasl_allowed_username_list", false,
&data->sasl_allowed_username_list) < 0)
if (remoteConfigGetStringList(conf, "sasl_allowed_username_list",
&data->sasl_allowed_username_list, filename) < 0)
goto error;
if (virConfGetValueString(conf, "tls_priority", &data->tls_priority) < 0)
goto error;
if (virConfGetValueUInt(conf, "min_workers", &data->min_workers) < 0)
goto error;
if (virConfGetValueUInt(conf, "max_workers", &data->max_workers) < 0)
goto error;
if (virConfGetValueUInt(conf, "max_clients", &data->max_clients) < 0)
goto error;
if (virConfGetValueUInt(conf, "max_queued_clients", &data->max_queued_clients) < 0)
goto error;
if (virConfGetValueUInt(conf, "max_anonymous_clients", &data->max_anonymous_clients) < 0)
goto error;
GET_CONF_UINT(conf, filename, min_workers);
GET_CONF_UINT(conf, filename, max_workers);
GET_CONF_UINT(conf, filename, max_clients);
GET_CONF_UINT(conf, filename, max_queued_clients);
GET_CONF_UINT(conf, filename, max_anonymous_clients);
if (virConfGetValueUInt(conf, "prio_workers", &data->prio_workers) < 0)
goto error;
GET_CONF_UINT(conf, filename, prio_workers);
if (virConfGetValueUInt(conf, "max_requests", &data->max_requests) < 0)
goto error;
if (virConfGetValueUInt(conf, "max_client_requests", &data->max_client_requests) < 0)
goto error;
GET_CONF_INT(conf, filename, max_requests);
GET_CONF_UINT(conf, filename, max_client_requests);
if (virConfGetValueUInt(conf, "admin_min_workers", &data->admin_min_workers) < 0)
goto error;
if (virConfGetValueUInt(conf, "admin_max_workers", &data->admin_max_workers) < 0)
goto error;
if (virConfGetValueUInt(conf, "admin_max_clients", &data->admin_max_clients) < 0)
goto error;
if (virConfGetValueUInt(conf, "admin_max_queued_clients", &data->admin_max_queued_clients) < 0)
goto error;
if (virConfGetValueUInt(conf, "admin_max_client_requests", &data->admin_max_client_requests) < 0)
goto error;
GET_CONF_UINT(conf, filename, admin_min_workers);
GET_CONF_UINT(conf, filename, admin_max_workers);
GET_CONF_UINT(conf, filename, admin_max_clients);
GET_CONF_UINT(conf, filename, admin_max_queued_clients);
GET_CONF_UINT(conf, filename, admin_max_client_requests);
if (virConfGetValueUInt(conf, "audit_level", &data->audit_level) < 0)
goto error;
if (virConfGetValueBool(conf, "audit_logging", &data->audit_logging) < 0)
goto error;
GET_CONF_UINT(conf, filename, audit_level);
GET_CONF_UINT(conf, filename, audit_logging);
if (virConfGetValueString(conf, "host_uuid", &data->host_uuid) < 0)
goto error;
if (virConfGetValueString(conf, "host_uuid_source", &data->host_uuid_source) < 0)
goto error;
GET_CONF_STR(conf, filename, host_uuid);
if (virConfGetValueUInt(conf, "log_level", &data->log_level) < 0)
goto error;
if (virConfGetValueString(conf, "log_filters", &data->log_filters) < 0)
goto error;
if (virConfGetValueString(conf, "log_outputs", &data->log_outputs) < 0)
goto error;
GET_CONF_UINT(conf, filename, log_level);
GET_CONF_STR(conf, filename, log_filters);
GET_CONF_STR(conf, filename, log_outputs);
if (virConfGetValueInt(conf, "keepalive_interval", &data->keepalive_interval) < 0)
goto error;
if (virConfGetValueUInt(conf, "keepalive_count", &data->keepalive_count) < 0)
goto error;
GET_CONF_INT(conf, filename, keepalive_interval);
GET_CONF_UINT(conf, filename, keepalive_count);
if (virConfGetValueInt(conf, "admin_keepalive_interval", &data->admin_keepalive_interval) < 0)
goto error;
if (virConfGetValueUInt(conf, "admin_keepalive_count", &data->admin_keepalive_count) < 0)
goto error;
if (virConfGetValueUInt(conf, "ovs_timeout", &data->ovs_timeout) < 0)
goto error;
GET_CONF_INT(conf, filename, admin_keepalive_interval);
GET_CONF_UINT(conf, filename, admin_keepalive_count);
return 0;

View File

@@ -28,10 +28,9 @@
struct daemonConfig {
char *host_uuid;
char *host_uuid_source;
bool listen_tls;
bool listen_tcp;
int listen_tls;
int listen_tcp;
char *listen_addr;
char *tls_port;
char *tcp_port;
@@ -49,51 +48,48 @@ struct daemonConfig {
char **access_drivers;
bool mdns_adv;
int mdns_adv;
char *mdns_name;
bool tls_no_verify_certificate;
bool tls_no_sanity_certificate;
int tls_no_verify_certificate;
int tls_no_sanity_certificate;
char **tls_allowed_dn_list;
char **sasl_allowed_username_list;
char *tls_priority;
char *key_file;
char *cert_file;
char *ca_file;
char *crl_file;
unsigned int min_workers;
unsigned int max_workers;
unsigned int max_clients;
unsigned int max_queued_clients;
unsigned int max_anonymous_clients;
int min_workers;
int max_workers;
int max_clients;
int max_queued_clients;
int max_anonymous_clients;
unsigned int prio_workers;
int prio_workers;
unsigned int max_requests;
unsigned int max_client_requests;
int max_requests;
int max_client_requests;
unsigned int log_level;
int log_level;
char *log_filters;
char *log_outputs;
unsigned int audit_level;
bool audit_logging;
int audit_level;
int audit_logging;
int keepalive_interval;
unsigned int keepalive_count;
unsigned int admin_min_workers;
unsigned int admin_max_workers;
unsigned int admin_max_clients;
unsigned int admin_max_queued_clients;
unsigned int admin_max_client_requests;
int admin_min_workers;
int admin_max_workers;
int admin_max_clients;
int admin_max_queued_clients;
int admin_max_client_requests;
int admin_keepalive_interval;
unsigned int admin_keepalive_count;
unsigned int ovs_timeout;
};

View File

@@ -13,7 +13,7 @@ module Libvirtd =
let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
let bool_val = store /0|1/
let int_val = store /-?[0-9]+/
let int_val = store /[0-9]+/
let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ ""
let str_array_val = counter "el" . array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end
@@ -53,7 +53,6 @@ module Libvirtd =
| str_array_entry "tls_allowed_dn_list"
| str_array_entry "sasl_allowed_username_list"
| str_array_entry "access_drivers"
| str_entry "tls_priority"
let processing_entry = int_entry "min_workers"
| int_entry "max_workers"
@@ -87,8 +86,6 @@ module Libvirtd =
| bool_entry "admin_keepalive_required"
let misc_entry = str_entry "host_uuid"
| str_entry "host_uuid_source"
| int_entry "ovs_timeout"
(* Each enty in the config is one of the following three ... *)
let entry = network_entry

View File

@@ -30,6 +30,7 @@
#include <getopt.h>
#include <stdlib.h>
#include <grp.h>
#include <locale.h>
#include "libvirt_internal.h"
#include "virerror.h"
@@ -43,7 +44,7 @@
#include "libvirtd.h"
#include "libvirtd-config.h"
#include "admin.h"
#include "admin_server.h"
#include "viruuid.h"
#include "remote_driver.h"
#include "viralloc.h"
@@ -57,8 +58,6 @@
#include "locking/lock_manager.h"
#include "viraccessmanager.h"
#include "virutil.h"
#include "virgettext.h"
#include "util/virnetdevopenvswitch.h"
#ifdef WITH_DRIVER_MODULES
# include "driver.h"
@@ -103,9 +102,6 @@
# include "nwfilter/nwfilter_driver.h"
# endif
#endif
#ifdef WITH_VZ
# include "vz/vz_driver.h"
#endif
#include "configmake.h"
@@ -334,22 +330,12 @@ static int daemonErrorLogFilter(virErrorPtr err, int priority)
case VIR_ERR_NO_DOMAIN_SNAPSHOT:
case VIR_ERR_OPERATION_INVALID:
case VIR_ERR_NO_DOMAIN_METADATA:
case VIR_ERR_NO_SERVER:
case VIR_ERR_NO_CLIENT:
return VIR_LOG_DEBUG;
}
return priority;
}
#ifdef WITH_DRIVER_MODULES
# define VIR_DAEMON_LOAD_MODULE(func, module) \
virDriverLoadModule(module, #func)
#else
# define VIR_DAEMON_LOAD_MODULE(func, module) \
func()
#endif
static void daemonInitialize(void)
{
/*
@@ -359,55 +345,93 @@ static void daemonInitialize(void)
* driver, since their resources must be auto-started before any
* domains can be auto-started.
*/
#ifdef WITH_DRIVER_MODULES
/* We don't care if any of these fail, because the whole point
* is to allow users to only install modules they want to use.
* If they try to open a connection for a module that
* is not loaded they'll get a suitable error at that point
*/
#ifdef WITH_NETWORK
VIR_DAEMON_LOAD_MODULE(networkRegister, "network");
#endif
#ifdef WITH_INTERFACE
VIR_DAEMON_LOAD_MODULE(interfaceRegister, "interface");
#endif
#ifdef WITH_STORAGE
VIR_DAEMON_LOAD_MODULE(storageRegister, "storage");
#endif
#ifdef WITH_NODE_DEVICES
VIR_DAEMON_LOAD_MODULE(nodedevRegister, "nodedev");
#endif
#ifdef WITH_SECRETS
VIR_DAEMON_LOAD_MODULE(secretRegister, "secret");
#endif
#ifdef WITH_NWFILTER
VIR_DAEMON_LOAD_MODULE(nwfilterRegister, "nwfilter");
#endif
#ifdef WITH_XEN
VIR_DAEMON_LOAD_MODULE(xenRegister, "xen");
#endif
#ifdef WITH_LIBXL
VIR_DAEMON_LOAD_MODULE(libxlRegister, "libxl");
#endif
#ifdef WITH_QEMU
VIR_DAEMON_LOAD_MODULE(qemuRegister, "qemu");
#endif
#ifdef WITH_LXC
VIR_DAEMON_LOAD_MODULE(lxcRegister, "lxc");
#endif
#ifdef WITH_UML
VIR_DAEMON_LOAD_MODULE(umlRegister, "uml");
#endif
#ifdef WITH_VBOX
VIR_DAEMON_LOAD_MODULE(vboxRegister, "vbox");
#endif
#ifdef WITH_BHYVE
VIR_DAEMON_LOAD_MODULE(bhyveRegister, "bhyve");
#endif
#ifdef WITH_VZ
VIR_DAEMON_LOAD_MODULE(vzRegister, "vz");
# ifdef WITH_NETWORK
virDriverLoadModule("network");
# endif
# ifdef WITH_INTERFACE
virDriverLoadModule("interface");
# endif
# ifdef WITH_STORAGE
virDriverLoadModule("storage");
# endif
# ifdef WITH_NODE_DEVICES
virDriverLoadModule("nodedev");
# endif
# ifdef WITH_SECRETS
virDriverLoadModule("secret");
# endif
# ifdef WITH_NWFILTER
virDriverLoadModule("nwfilter");
# endif
# ifdef WITH_XEN
virDriverLoadModule("xen");
# endif
# ifdef WITH_LIBXL
virDriverLoadModule("libxl");
# endif
# ifdef WITH_QEMU
virDriverLoadModule("qemu");
# endif
# ifdef WITH_LXC
virDriverLoadModule("lxc");
# endif
# ifdef WITH_UML
virDriverLoadModule("uml");
# endif
# ifdef WITH_VBOX
virDriverLoadModule("vbox");
# endif
# ifdef WITH_BHYVE
virDriverLoadModule("bhyve");
# endif
#else
# ifdef WITH_NETWORK
networkRegister();
# endif
# ifdef WITH_INTERFACE
interfaceRegister();
# endif
# ifdef WITH_STORAGE
storageRegister();
# endif
# ifdef WITH_NODE_DEVICES
nodedevRegister();
# endif
# ifdef WITH_SECRETS
secretRegister();
# endif
# ifdef WITH_NWFILTER
nwfilterRegister();
# endif
# ifdef WITH_XEN
xenRegister();
# endif
# ifdef WITH_LIBXL
libxlRegister();
# endif
# ifdef WITH_QEMU
qemuRegister();
# endif
# ifdef WITH_LXC
lxcRegister();
# endif
# ifdef WITH_UML
umlRegister();
# endif
# ifdef WITH_VBOX
vboxRegister();
# endif
# ifdef WITH_BHYVE
bhyveRegister();
# endif
#endif
}
#undef VIR_DAEMON_LOAD_MODULE
static int ATTRIBUTE_NONNULL(3)
@@ -498,7 +522,8 @@ daemonSetupNetworking(virNetServerPtr srv,
virNetServerAddService(srv, svcRO, NULL) < 0)
goto cleanup;
if (sock_path_adm) {
/* Temporarily disabled */
if (sock_path_adm && false) {
VIR_DEBUG("Registering unix socket %s", sock_path_adm);
if (!(svcAdm = virNetServerServiceNewUNIX(sock_path_adm,
unix_sock_adm_mask,
@@ -507,7 +532,7 @@ daemonSetupNetworking(virNetServerPtr srv,
#if WITH_GNUTLS
NULL,
#endif
false,
true,
config->admin_max_queued_clients,
config->admin_max_client_requests)))
goto cleanup;
@@ -544,29 +569,11 @@ daemonSetupNetworking(virNetServerPtr srv,
if (config->ca_file ||
config->cert_file ||
config->key_file) {
if (!config->ca_file) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("No CA certificate path set to match server key/cert"));
goto cleanup;
}
if (!config->cert_file) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("No server certificate path set to match server key"));
goto cleanup;
}
if (!config->key_file) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("No server key path set to match server cert"));
goto cleanup;
}
VIR_DEBUG("Using CA='%s' cert='%s' key='%s'",
config->ca_file, config->cert_file, config->key_file);
if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
config->crl_file,
config->cert_file,
config->key_file,
(const char *const*)config->tls_allowed_dn_list,
config->tls_priority,
config->tls_no_sanity_certificate ? false : true,
config->tls_no_verify_certificate ? false : true)))
goto cleanup;
@@ -574,7 +581,6 @@ daemonSetupNetworking(virNetServerPtr srv,
if (!(ctxt = virNetTLSContextNewServerPath(NULL,
!privileged,
(const char *const*)config->tls_allowed_dn_list,
config->tls_priority,
config->tls_no_sanity_certificate ? false : true,
config->tls_no_verify_certificate ? false : true)))
goto cleanup;
@@ -639,16 +645,6 @@ daemonSetupNetworking(virNetServerPtr srv,
}
/*
* Set up the openvswitch timeout
*/
static void
daemonSetupNetDevOpenvswitch(struct daemonConfig *config)
{
virNetDevOpenvswitchSetTimeout(config->ovs_timeout);
}
/*
* Set up the logging environment
* By default if daemonized all errors go to the logfile libvirtd.log,
@@ -667,33 +663,103 @@ daemonSetupLogging(struct daemonConfig *config,
* Libvirtd's order of precedence is:
* cmdline > environment > config
*
* The default output is applied only if there was no setting from either
* the config or the environment. Because we don't have a way to determine
* if the log level has been set, we must process variables in the opposite
* In order to achieve this, we must process configuration in
* different order for the log level versus the filters and
* outputs. Because filters and outputs append, we have to look at
* the environment first and then only check the config file if
* there was no result from the environment. The default output is
* then applied only if there was no setting from either of the
* first two. Because we don't have a way to determine if the log
* level has been set, we must process variables in the opposite
* order, each one overriding the previous.
*/
if (config->log_level != 0)
virLogSetDefaultPriority(config->log_level);
if (virLogSetDefaultOutput("libvirtd.log", godaemon, privileged) < 0)
return -1;
/* In case the config is empty, the filters become empty and outputs will
* be set to default
*/
ignore_value(virLogSetFilters(config->log_filters));
ignore_value(virLogSetOutputs(config->log_outputs));
/* If there are some environment variables defined, use those instead */
virLogSetFromEnv();
if (virLogGetNbFilters() == 0)
virLogParseFilters(config->log_filters);
if (virLogGetNbOutputs() == 0)
virLogParseOutputs(config->log_outputs);
/*
* Command line override for --verbose
*/
if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO))
virLogSetDefaultPriority(VIR_LOG_INFO);
/*
* If no defined outputs, and either running
* as daemon or not on a tty, then first try
* to direct it to the systemd journal
* (if it exists)....
*/
if (virLogGetNbOutputs() == 0 &&
(godaemon || !isatty(STDIN_FILENO))) {
char *tmp;
if (access("/run/systemd/journal/socket", W_OK) >= 0) {
virLogPriority priority = virLogGetDefaultPriority();
/* By default we don't want to log too much stuff into journald as
* it may employ rate limiting and thus block libvirt execution. */
if (priority == VIR_LOG_DEBUG)
priority = VIR_LOG_INFO;
if (virAsprintf(&tmp, "%d:journald", priority) < 0)
goto error;
virLogParseOutputs(tmp);
VIR_FREE(tmp);
}
}
/*
* otherwise direct to libvirtd.log when running
* as daemon. Otherwise the default output is stderr.
*/
if (virLogGetNbOutputs() == 0) {
char *tmp = NULL;
if (godaemon) {
if (privileged) {
if (virAsprintf(&tmp, "%d:file:%s/log/libvirt/libvirtd.log",
virLogGetDefaultPriority(),
LOCALSTATEDIR) == -1)
goto error;
} else {
char *logdir = virGetUserCacheDirectory();
mode_t old_umask;
if (!logdir)
goto error;
old_umask = umask(077);
if (virFileMakePath(logdir) < 0) {
umask(old_umask);
goto error;
}
umask(old_umask);
if (virAsprintf(&tmp, "%d:file:%s/libvirtd.log",
virLogGetDefaultPriority(), logdir) == -1) {
VIR_FREE(logdir);
goto error;
}
VIR_FREE(logdir);
}
} else {
if (virAsprintf(&tmp, "%d:stderr", virLogGetDefaultPriority()) < 0)
goto error;
}
virLogParseOutputs(tmp);
VIR_FREE(tmp);
}
return 0;
error:
return -1;
}
@@ -1001,39 +1067,6 @@ static int migrateProfile(void)
return ret;
}
static int
daemonSetupHostUUID(const struct daemonConfig *config)
{
static const char *machine_id = "/etc/machine-id";
char buf[VIR_UUID_STRING_BUFLEN];
const char *uuid;
if (config->host_uuid) {
uuid = config->host_uuid;
} else if (!config->host_uuid_source ||
STREQ(config->host_uuid_source, "smbios")) {
/* smbios UUID is fetched on demand in virGetHostUUID */
return 0;
} else if (STREQ(config->host_uuid_source, "machine-id")) {
if (virFileReadBufQuiet(machine_id, buf, sizeof(buf)) < 0) {
VIR_ERROR(_("Can't read %s"), machine_id);
return -1;
}
uuid = buf;
} else {
VIR_ERROR(_("invalid UUID source: %s"), config->host_uuid_source);
return -1;
}
if (virSetHostUUIDStr(uuid)) {
VIR_ERROR(_("invalid host UUID: %s"), uuid);
return -1;
}
return 0;
}
/* Print command-line usage. */
static void
daemonUsage(const char *argv0, bool privileged)
@@ -1139,7 +1172,9 @@ int main(int argc, char **argv) {
{0, 0, 0, 0}
};
if (virGettextInitialize() < 0 ||
if (setlocale(LC_ALL, "") == NULL ||
bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
textdomain(PACKAGE) == NULL ||
virInitialize() < 0) {
fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
exit(EXIT_FAILURE);
@@ -1238,8 +1273,12 @@ int main(int argc, char **argv) {
/* Read the config file if it exists*/
if (remote_config_file &&
daemonConfigLoadFile(config, remote_config_file, implicit_conf) < 0) {
VIR_ERROR(_("Can't load config file: %s: %s"),
virGetLastErrorMessage(), remote_config_file);
virErrorPtr err = virGetLastError();
if (err && err->message)
VIR_ERROR(_("Can't load config file: %s: %s"),
err->message, remote_config_file);
else
VIR_ERROR(_("Can't load config file: %s"), remote_config_file);
exit(EXIT_FAILURE);
}
@@ -1249,8 +1288,9 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
if (daemonSetupHostUUID(config) < 0) {
VIR_ERROR(_("Can't setup host uuid"));
if (config->host_uuid &&
virSetHostUUIDStr(config->host_uuid) < 0) {
VIR_ERROR(_("invalid host UUID: %s"), config->host_uuid);
exit(EXIT_FAILURE);
}
@@ -1259,8 +1299,6 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
daemonSetupNetDevOpenvswitch(config);
if (daemonSetupAccessManager(config) < 0) {
VIR_ERROR(_("Can't initialize access manager"));
exit(EXIT_FAILURE);
@@ -1344,8 +1382,7 @@ int main(int argc, char **argv) {
goto cleanup;
}
if (!(srv = virNetServerNew("libvirtd", 1,
config->min_workers,
if (!(srv = virNetServerNew(config->min_workers,
config->max_workers,
config->prio_workers,
config->max_clients,
@@ -1419,8 +1456,7 @@ int main(int argc, char **argv) {
goto cleanup;
}
if (!(srvAdm = virNetServerNew("admin", 1,
config->admin_min_workers,
if (!(srvAdm = virNetServerNew(config->admin_min_workers,
config->admin_max_workers,
0,
config->admin_max_clients,
@@ -1552,6 +1588,7 @@ int main(int argc, char **argv) {
virObjectUnref(qemuProgram);
virObjectUnref(adminProgram);
virNetDaemonClose(dmn);
virObjectUnref(dmn);
virObjectUnref(srv);
virObjectUnref(srvAdm);
virNetlinkShutdown();
@@ -1581,9 +1618,6 @@ int main(int argc, char **argv) {
driversInitialized = false;
virStateCleanup();
}
/* Now that the hypervisor shutdown inhibition functions that use
* 'dmn' as a parameter are done, we can finally unref 'dmn' */
virObjectUnref(dmn);
return ret;
}

View File

@@ -77,6 +77,11 @@
# UNIX socket access controls
#
# Beware that if you are changing *any* of these options, and you use
# socket activation with systemd, you need to adjust the settings in
# the libvirtd.socket file as well since it could impose a security
# risk if you rely on file permission checking only.
# Set the UNIX domain socket group ownership. This can be used to
# allow a 'trusted' set of users access to management capabilities
# without becoming root.
@@ -242,7 +247,7 @@
#tls_allowed_dn_list = ["DN1", "DN2"]
# A whitelist of allowed SASL usernames. The format for username
# A whitelist of allowed SASL usernames. The format for usernames
# depends on the SASL authentication mechanism. Kerberos usernames
# look like username@REALM
#
@@ -259,13 +264,6 @@
#sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]
# Override the compile time default TLS priority string. The
# default is usually "NORMAL" unless overridden at build time.
# Only set this is it is desired for libvirt to deviate from
# the global default settings.
#
#tls_priority="NORMAL"
#################################################################
#
@@ -283,8 +281,8 @@
#max_queued_clients = 1000
# The maximum length of queue of accepted but not yet
# authenticated clients. The default value is 20. Set this to
# zero to turn this feature off.
# authenticated clients. The default value is zero, meaning
# the feature is disabled.
#max_anonymous_clients = 20
# The minimum limit sets the number of workers to start up
@@ -417,16 +415,10 @@
###################################################################
# UUID of the host:
# Host UUID is read from one of the sources specified in host_uuid_source.
#
# - 'smbios': fetch the UUID from 'dmidecode -s system-uuid'
# - 'machine-id': fetch the UUID from /etc/machine-id
#
# The host_uuid_source default is 'smbios'. If 'dmidecode' does not provide
# a valid UUID a temporary UUID will be generated.
#
# Another option is to specify host UUID in host_uuid.
#
# Provide the UUID of the host here in case the command
# 'dmidecode -s system-uuid' does not provide a valid uuid. In case
# 'dmidecode' does not provide a valid UUID and none is provided here, a
# temporary UUID will be generated.
# Keep the format of the example UUID below. UUID must not have all digits
# be the same.
@@ -434,7 +426,6 @@
# it with the output of the 'uuidgen' command and then
# uncomment this entry
#host_uuid = "00000000-0000-0000-0000-000000000000"
#host_uuid_source = "smbios"
###################################################################
# Keepalive protocol:
@@ -467,12 +458,3 @@
# Keepalive settings for the admin interface
#admin_keepalive_interval = 5
#admin_keepalive_count = 5
###################################################################
# Open vSwitch:
# This allows to specify a timeout for openvswitch calls made by
# libvirt. The ovs-vsctl utility is used for the configuration and
# its timeout option is set by default to 5 seconds to avoid
# potential infinite waits blocking libvirt.
#
#ovs_timeout = 5

View File

@@ -60,13 +60,6 @@ struct daemonClientPrivate {
size_t nnetworkEventCallbacks;
daemonClientEventCallbackPtr *qemuEventCallbacks;
size_t nqemuEventCallbacks;
daemonClientEventCallbackPtr *storageEventCallbacks;
size_t nstorageEventCallbacks;
daemonClientEventCallbackPtr *nodeDeviceEventCallbacks;
size_t nnodeDeviceEventCallbacks;
daemonClientEventCallbackPtr *secretEventCallbacks;
size_t nsecretEventCallbacks;
bool closeRegistered;
# if WITH_SASL
virNetSASLSessionPtr sasl;

View File

@@ -4,7 +4,9 @@ libvirtd - libvirtd management daemon
=head1 SYNOPSIS
B<libvirtd> [I<OPTION>]...
B<libvirtd> [ -dlv ] [ -f config_file ] [ -p pid_file ] [ -t timeout_seconds ]
B<libvirtd> --version
=head1 DESCRIPTION

View File

@@ -1,45 +1,31 @@
# If you want to use the non-TLS socket, then you *must* pick a
# mechanism which provides session encryption as well as
# authentication.
# If you want to use the non-TLS socket, then you *must* include
# the GSSAPI or DIGEST-MD5 mechanisms, because they are the only
# ones that can offer session encryption as well as authentication.
#
# If you are only using TLS, then you can turn on any mechanisms
# If you're only using TLS, then you can turn on any mechanisms
# you like for authentication, because TLS provides the encryption
#
# If you are only using UNIX, sockets then encryption is not
# required at all.
#
# Since SASL is the default for the libvirtd non-TLS socket, we
# pick a strong mechanism by default.
#
# NB, previously DIGEST-MD5 was set as the default mechanism for
# libvirt. Per RFC 6331 this is vulnerable to many serious security
# flaws and should no longer be used. Thus GSSAPI is now the default.
#
# To use GSSAPI requires that a libvirtd service principal is
# added to the Kerberos server for each host running libvirtd.
# This principal needs to be exported to the keytab file listed below
mech_list: gssapi
# If using a TLS socket or UNIX socket only, it is possible to
# enable plugins which don't provide session encryption. The
# 'scram-sha-1' plugin allows plain username/password authentication
# to be performed
#
#mech_list: scram-sha-1
# Default to a simple username+password mechanism
mech_list: digest-md5
# Before you can use GSSAPI, you need a service principle on the
# KDC server for libvirt, and that to be exported to the keytab
# file listed below
#mech_list: gssapi
#
# You can also list many mechanisms at once, then the user can choose
# by adding '?auth=sasl.gssapi' to their libvirt URI, eg
# qemu+tcp://hostname/system?auth=sasl.gssapi
#mech_list: scram-sha-1 gssapi
#mech_list: digest-md5 gssapi
# Some older builds of MIT kerberos on Linux ignore this option &
# instead need KRB5_KTNAME env var.
# For modern Linux, and other OS, this should be sufficient
#
keytab: /etc/libvirt/krb5.tab
# There is no default value here, uncomment if you need this
#keytab: /etc/libvirt/krb5.tab
# If using scram-sha-1 for username/passwds, then this is the file
# If using digest-md5 for username/passwds, then this is the file
# containing the passwds. Use 'saslpasswd2 -a libvirt [username]'
# to add entries, and 'sasldblistusers2 -f [sasldb_path]' to browse it
#sasldb_path: /etc/libvirt/passwd.db
sasldb_path: /etc/libvirt/passwd.db

View File

@@ -1,12 +1,5 @@
# NB we don't use socket activation. When libvirtd starts it will
# spawn any virtual machines registered for autostart. We want this
# to occur on every boot, regardless of whether any client connects
# to a socket. Thus socket activation doesn't have any benefit
[Unit]
Description=Virtualization daemon
Requires=virtlogd.socket
Requires=virtlockd.socket
Before=libvirt-guests.service
After=network.target
After=dbus.service
@@ -24,16 +17,8 @@ ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
# At least 1 FD per guest, often 2 (eg qemu monitor + qemu agent).
# eg if we want to support 4096 guests, we'll typically need 8192 FDs
# If changing this, also consider virtlogd.service & virtlockd.service
# limits which are also related to number of guests
LimitNOFILE=8192
# The cgroups pids controller can limit the number of tasks started by
# the daemon, which can limit the number of domains for some hypervisors.
# A conservative default of 8 tasks per guest results in a TasksMax of
# 32k to support 4096 guests.
TasksMax=32768
# Override the maximum number of opened files
#LimitNOFILE=2048
[Install]
WantedBy=multi-user.target

11
daemon/libvirtd.socket.in Normal file
View File

@@ -0,0 +1,11 @@
[Socket]
ListenStream=@runstatedir@/libvirt/libvirt-sock
ListenStream=@runstatedir@/libvirt/libvirt-sock-ro
; The following settings must match libvirtd.conf file in order to
; work as expected because libvirtd can't change them later.
; SocketMode=0777 is safe only if authentication on the socket is set
; up. For further information, please see the libvirtd.conf file.
SocketMode=0777
SocketUser=root
SocketGroup=root

File diff suppressed because it is too large Load Diff

View File

@@ -42,15 +42,15 @@ struct daemonClientStream {
virStreamPtr st;
int procedure;
unsigned int serial;
int serial;
bool recvEOF;
bool closed;
unsigned int recvEOF : 1;
unsigned int closed : 1;
int filterID;
virNetMessagePtr rx;
bool tx;
int tx;
daemonClientStreamPtr next;
};
@@ -76,8 +76,6 @@ static void
daemonStreamUpdateEvents(daemonClientStream *stream)
{
int newEvents = 0;
if (stream->closed)
return;
if (stream->rx)
newEvents |= VIR_STREAM_EVENT_WRITABLE;
if (stream->tx && !stream->recvEOF)
@@ -94,14 +92,14 @@ daemonStreamUpdateEvents(daemonClientStream *stream)
* fast stream, but slow client
*/
static void
daemonStreamMessageFinished(virNetMessagePtr msg,
daemonStreamMessageFinished(virNetMessagePtr msg ATTRIBUTE_UNUSED,
void *opaque)
{
daemonClientStream *stream = opaque;
VIR_DEBUG("stream=%p proc=%d serial=%u",
VIR_DEBUG("stream=%p proc=%d serial=%d",
stream, msg->header.proc, msg->header.serial);
stream->tx = true;
stream->tx = 1;
daemonStreamUpdateEvents(stream);
daemonFreeClientStream(NULL, stream);
@@ -199,8 +197,8 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
(events & VIR_STREAM_EVENT_HANGUP)) {
virNetMessagePtr msg;
events &= ~(VIR_STREAM_EVENT_HANGUP);
stream->tx = false;
stream->recvEOF = true;
stream->tx = 0;
stream->recvEOF = 1;
if (!(msg = virNetMessageNew(false))) {
daemonRemoveClientStream(client, stream);
virNetServerClientClose(client);
@@ -229,7 +227,7 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
virNetMessageError rerr;
memset(&rerr, 0, sizeof(rerr));
stream->closed = true;
stream->closed = 1;
virStreamEventRemoveCallback(stream->st);
virStreamAbort(stream->st);
if (events & VIR_STREAM_EVENT_HANGUP)
@@ -295,7 +293,7 @@ daemonStreamFilter(virNetServerClientPtr client ATTRIBUTE_UNUSED,
msg->header.serial != stream->serial)
goto cleanup;
VIR_DEBUG("Incoming client=%p, rx=%p, serial=%u, proc=%d, status=%d",
VIR_DEBUG("Incoming client=%p, rx=%p, serial=%d, proc=%d, status=%d",
client, stream->rx, msg->header.proc,
msg->header.serial, msg->header.status);
@@ -326,7 +324,7 @@ daemonCreateClientStream(virNetServerClientPtr client,
daemonClientStream *stream;
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
VIR_DEBUG("client=%p, proc=%d, serial=%u, st=%p",
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
client, header->proc, header->serial, st);
if (VIR_ALLOC(stream) < 0)
@@ -362,7 +360,7 @@ int daemonFreeClientStream(virNetServerClientPtr client,
if (stream->refs)
return 0;
VIR_DEBUG("client=%p, proc=%d, serial=%u",
VIR_DEBUG("client=%p, proc=%d, serial=%d",
client, stream->procedure, stream->serial);
virObjectUnref(stream->prog);
@@ -400,7 +398,7 @@ int daemonAddClientStream(virNetServerClientPtr client,
daemonClientStream *stream,
bool transmit)
{
VIR_DEBUG("client=%p, proc=%d, serial=%u, st=%p, transmit=%d",
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p, transmit=%d",
client, stream->procedure, stream->serial, stream->st, transmit);
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
@@ -424,7 +422,7 @@ int daemonAddClientStream(virNetServerClientPtr client,
}
if (transmit)
stream->tx = true;
stream->tx = 1;
virMutexLock(&priv->lock);
stream->next = priv->streams;
@@ -444,13 +442,13 @@ int daemonAddClientStream(virNetServerClientPtr client,
*
* Removes a stream from the list of active streams for the client
*
* Returns 0 if the stream was removed, -1 if it doesn't exist
* Returns 0 if the stream was removd, -1 if it doesn't exist
*/
int
daemonRemoveClientStream(virNetServerClientPtr client,
daemonClientStream *stream)
{
VIR_DEBUG("client=%p, proc=%d, serial=%u, st=%p",
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
client, stream->procedure, stream->serial, stream->st);
daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
daemonClientStream *curr = priv->streams;
@@ -463,7 +461,6 @@ daemonRemoveClientStream(virNetServerClientPtr client,
}
if (!stream->closed) {
stream->closed = true;
virStreamEventRemoveCallback(stream->st);
virStreamAbort(stream->st);
}
@@ -494,7 +491,6 @@ daemonRemoveAllClientStreams(daemonClientStream *stream)
tmp = stream->next;
if (!stream->closed) {
stream->closed = true;
virStreamEventRemoveCallback(stream->st);
virStreamAbort(stream->st);
}
@@ -519,7 +515,7 @@ daemonStreamHandleWriteData(virNetServerClientPtr client,
{
int ret;
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%u, len=%zu, offset=%zu",
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d, len=%zu, offset=%zu",
client, stream, msg->header.proc, msg->header.serial,
msg->bufferLength, msg->bufferOffset);
@@ -542,10 +538,7 @@ daemonStreamHandleWriteData(virNetServerClientPtr client,
memset(&rerr, 0, sizeof(rerr));
VIR_INFO("Stream send failed");
stream->closed = true;
virStreamEventRemoveCallback(stream->st);
virStreamAbort(stream->st);
stream->closed = 1;
return virNetServerProgramSendReplyError(stream->prog,
client,
msg,
@@ -572,10 +565,10 @@ daemonStreamHandleFinish(virNetServerClientPtr client,
{
int ret;
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%u",
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d",
client, stream, msg->header.proc, msg->header.serial);
stream->closed = true;
stream->closed = 1;
virStreamEventRemoveCallback(stream->st);
ret = virStreamFinish(stream->st);
@@ -609,42 +602,31 @@ daemonStreamHandleAbort(virNetServerClientPtr client,
daemonClientStream *stream,
virNetMessagePtr msg)
{
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%u",
VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d",
client, stream, msg->header.proc, msg->header.serial);
int ret;
bool raise_error = false;
virNetMessageError rerr;
stream->closed = true;
memset(&rerr, 0, sizeof(rerr));
stream->closed = 1;
virStreamEventRemoveCallback(stream->st);
ret = virStreamAbort(stream->st);
virStreamAbort(stream->st);
if (msg->header.status == VIR_NET_ERROR) {
VIR_INFO("stream aborted at client request");
raise_error = (ret < 0);
virReportError(VIR_ERR_RPC,
"%s", _("stream aborted at client request"));
} else {
VIR_WARN("unexpected stream status %d", msg->header.status);
virReportError(VIR_ERR_RPC,
_("stream aborted with unexpected status %d"),
msg->header.status);
raise_error = true;
}
if (raise_error) {
virNetMessageError rerr;
memset(&rerr, 0, sizeof(rerr));
return virNetServerProgramSendReplyError(remoteProgram,
client,
msg,
&rerr,
&msg->header);
} else {
/* Send zero-length confirm */
return virNetServerProgramSendStreamData(stream->prog,
client,
msg,
stream->procedure,
stream->serial,
NULL, 0);
}
return virNetServerProgramSendReplyError(remoteProgram,
client,
msg,
&rerr,
&msg->header);
}
@@ -719,7 +701,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
* worth of data, and then queues that for transmission
* to the client.
*
* Returns 0 if data was queued for TX, or an error RPC
* Returns 0 if data was queued for TX, or a error RPC
* was sent, or -1 on fatal error, indicating client should
* be killed
*/
@@ -727,12 +709,9 @@ static int
daemonStreamHandleRead(virNetServerClientPtr client,
daemonClientStream *stream)
{
virNetMessagePtr msg = NULL;
virNetMessageError rerr;
char *buffer;
size_t bufferLen = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
int ret = -1;
int rv;
int ret;
VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
client, stream, stream->tx, stream->closed);
@@ -749,48 +728,50 @@ daemonStreamHandleRead(virNetServerClientPtr client,
if (!stream->tx)
return 0;
memset(&rerr, 0, sizeof(rerr));
if (VIR_ALLOC_N(buffer, bufferLen) < 0)
return -1;
if (!(msg = virNetMessageNew(false)))
goto cleanup;
rv = virStreamRecv(stream->st, buffer, bufferLen);
if (rv == -2) {
ret = virStreamRecv(stream->st, buffer, bufferLen);
if (ret == -2) {
/* Should never get this, since we're only called when we know
* we're readable, but hey things change... */
} else if (rv < 0) {
if (virNetServerProgramSendStreamError(remoteProgram,
client,
msg,
&rerr,
stream->procedure,
stream->serial) < 0)
goto cleanup;
msg = NULL;
} else {
stream->tx = false;
if (rv == 0)
stream->recvEOF = true;
ret = 0;
} else if (ret < 0) {
virNetMessagePtr msg;
virNetMessageError rerr;
msg->cb = daemonStreamMessageFinished;
msg->opaque = stream;
stream->refs++;
if (virNetServerProgramSendStreamData(remoteProgram,
client,
msg,
stream->procedure,
stream->serial,
buffer, rv) < 0)
goto cleanup;
msg = NULL;
memset(&rerr, 0, sizeof(rerr));
if (!(msg = virNetMessageNew(false)))
ret = -1;
else
ret = virNetServerProgramSendStreamError(remoteProgram,
client,
msg,
&rerr,
stream->procedure,
stream->serial);
} else {
virNetMessagePtr msg;
stream->tx = 0;
if (ret == 0)
stream->recvEOF = 1;
if (!(msg = virNetMessageNew(false)))
ret = -1;
if (msg) {
msg->cb = daemonStreamMessageFinished;
msg->opaque = stream;
stream->refs++;
ret = virNetServerProgramSendStreamData(remoteProgram,
client,
msg,
stream->procedure,
stream->serial,
buffer, ret);
}
}
ret = 0;
cleanup:
VIR_FREE(buffer);
virNetMessageFree(msg);
return ret;
}

View File

@@ -26,6 +26,8 @@
# include "libvirtd.h"
daemonClientStream *
daemonCreateClientStream(virNetServerClientPtr client,
virStreamPtr st,

View File

@@ -35,7 +35,6 @@ module Test_libvirtd =
{ "1" = "joe@EXAMPLE.COM" }
{ "2" = "fred@EXAMPLE.COM" }
}
{ "tls_priority" = "NORMAL" }
{ "max_clients" = "5000" }
{ "max_queued_clients" = "1000" }
{ "max_anonymous_clients" = "20" }
@@ -56,11 +55,9 @@ module Test_libvirtd =
{ "audit_level" = "2" }
{ "audit_logging" = "1" }
{ "host_uuid" = "00000000-0000-0000-0000-000000000000" }
{ "host_uuid_source" = "smbios" }
{ "keepalive_interval" = "5" }
{ "keepalive_count" = "5" }
{ "keepalive_required" = "1" }
{ "admin_keepalive_required" = "1" }
{ "admin_keepalive_interval" = "5" }
{ "admin_keepalive_count" = "5" }
{ "ovs_timeout" = "5" }

View File

@@ -1,3 +0,0 @@
[Unit]
Description=Libvirt guests shutdown
Documentation=http://libvirt.org

View File

@@ -15,5 +15,10 @@
locate the content on this site or mailing list archives</li>
</ul>
<p class="image">
<img src="/libvirtLogo404.png" alt="libvirt Logo"/>
</p>
</body>
</html>

View File

@@ -16,6 +16,11 @@
## License along with this library. If not, see
## <http://www.gnu.org/licenses/>.
PERL = perl
# The directory containing the source code (if it contains documentation).
DOC_SOURCE_DIR=../src
DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
apihtml = \
@@ -23,7 +28,6 @@ apihtml = \
$(apihtml_generated)
apihtml_generated = \
html/libvirt-libvirt-common.html \
html/libvirt-libvirt-domain.html \
html/libvirt-libvirt-domain-snapshot.html \
html/libvirt-libvirt-event.html \
@@ -64,30 +68,20 @@ devhelpcss = devhelp/style.css
devhelpxsl = devhelp/devhelp.xsl devhelp/html.xsl
logofiles = \
logos/logo-base.svg \
logos/logo-square.svg \
logos/logo-square-powered.svg \
logos/logo-banner-dark.svg \
logos/logo-banner-light.svg \
logos/logo-square-96.png \
logos/logo-square-128.png \
logos/logo-square-192.png \
logos/logo-square-256.png \
logos/logo-square-powered-96.png \
logos/logo-square-powered-128.png \
logos/logo-square-powered-192.png \
logos/logo-square-powered-256.png \
logos/logo-banner-dark-256.png \
logos/logo-banner-dark-800.png \
logos/logo-banner-light-256.png \
logos/logo-banner-light-800.png
png = \
32favicon.png \
footer_corner.png \
footer_pattern.png \
libvirt-header-bg.png \
libvirt-header-logo.png \
libvirtLogo.png \
libvirt-net-logical.png \
libvirt-net-physical.png \
libvirt-daemon-arch.png \
libvirt-driver-arch.png \
libvirt-object-model.png \
madeWith.png \
et.png \
migration-managed-direct.png \
migration-managed-p2p.png \
migration-native.png \
@@ -103,14 +97,15 @@ internals_html_in = \
$(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
internals_html = $(internals_html_in:%.html.in=%.html)
# Since we ship pre-built html in the tarball, we must also
# ship the sources, even when those sources are themselves
# generated.
# Generate hvsupport.html and news.html first, since they take one extra step.
dot_html_in = \
hvsupport.html.in \
news.html.in \
$(notdir $(wildcard $(srcdir)/*.html.in))
# todo.html is special - it is shipped in the tarball, but we
# have a dedicated 'todo' target to rebuild it from a proper
# config file, all other users are able to build it locally.
# For all other files, since we ship pre-built html in the
# tarball, we must also ship the sources, even when those
# sources are themselves generated.
dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) \
todo.html.in \
hvsupport.html.in
dot_html = $(dot_html_in:%.html.in=%.html)
dot_php_in = $(notdir $(wildcard $(srcdir)/*.php.in))
@@ -139,10 +134,11 @@ apidir = $(pkgdatadir)/api
api_DATA = \
libvirt-api.xml \
libvirt-qemu-api.xml \
libvirt-lxc-api.xml \
libvirt-admin-api.xml
libvirt-lxc-api.xml
fig = \
libvirt-net-logical.fig \
libvirt-net-physical.fig \
libvirt-daemon-arch.fig \
libvirt-driver-arch.fig \
libvirt-object-model.fig \
@@ -157,15 +153,15 @@ schema_DATA = $(wildcard $(srcdir)/schemas/*.rng)
EXTRA_DIST= \
apibuild.py genaclperms.pl \
site.xsl subsite.xsl newapi.xsl page.xsl \
site.xsl newapi.xsl news.xsl page.xsl \
hacking1.xsl hacking2.xsl wrapstring.xsl \
$(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
$(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
$(xml) $(qemu_xml) $(lxc_xml) $(admin_xml) $(fig) $(png) $(css) \
$(logofiles) $(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
$(xml) $(qemu_xml) $(lxc_xml) $(fig) $(png) $(css) \
$(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
$(internals_html_in) $(internals_html) \
aclperms.htmlinc \
hvsupport.pl \
sitemap.html.in aclperms.htmlinc \
todo.pl hvsupport.pl todo.cfg-example \
$(schema_DATA)
acl_generated = aclperms.htmlinc
@@ -192,6 +188,24 @@ admin_api: $(srcdir)/libvirt-admin-api.xml $(srcdir)/libvirt-admin-refs.xml
web: $(dot_html) $(internals_html) html/index.html devhelp/index.html \
$(dot_php)
todo.html.in: todo.pl
if [ -f todo.cfg ]; then \
echo "Generating $@"; \
$(PERL) $< > $@ \
|| { rm $@ && exit 1; }; \
else \
echo "Stubbing $@"; \
printf "%s\n" \
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" \
"<body>" \
"<h1>Todo list unavailable: no config file</h1>" \
"</body></html>" > $@ ; \
fi
todo:
rm -f todo.html.in
$(MAKE) todo.html
hvsupport.html: $(srcdir)/hvsupport.html.in
$(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
@@ -201,48 +215,26 @@ $(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(top_srcdir)/src > $@ \
|| { rm $@ && exit 1; }
# xsltproc seems to add the xmlns="" attribute to random output elements:
# use sed to strip it out, as leaving it there triggers XML errors during
# further transformation steps
news.html.in: \
$(srcdir)/news.xml \
$(srcdir)/news-html.xsl
$(AM_V_GEN) \
if [ -x $(XSLTPROC) ]; then \
$(XSLTPROC) --nonet \
$(srcdir)/news-html.xsl \
$(srcdir)/news.xml \
>$@-tmp \
|| { rm -f $@-tmp; exit 1; }; \
sed 's/ xmlns=""//g' $@-tmp >$@ \
|| { rm -f $@-tmp; exit 1; }; \
rm -f $@-tmp; \
fi
EXTRA_DIST += \
$(srcdir)/news.xml \
$(srcdir)/news.rng \
$(srcdir)/news-html.xsl
MAINTAINERCLEANFILES += \
$(srcdir)/news.html.in
.PHONY: todo
%.png: %.fig
convert -rotate 90 $< $@
%.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \
$(acl_generated)
internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
@if [ -x $(XSLTPROC) ] ; then \
echo "Generating $@"; \
$(MKDIR_P) internals; \
name=`echo $@ | sed -e 's/.tmp//'`; \
$(XSLTPROC) --stringparam pagename $$name --nonet \
$(top_srcdir)/docs/subsite.xsl $< > $@ \
|| { rm $@ && exit 1; }; fi
%.html.tmp: %.html.in site.xsl page.xsl sitemap.html.in $(acl_generated)
@if [ -x $(XSLTPROC) ] ; then \
echo "Generating $@"; \
name=`echo $@ | sed -e 's/.tmp//'`; \
dir=`dirname $@` ; \
if test "$$dir" = "."; \
then \
style=site.xsl; \
else \
$(MKDIR_P) $$dir; \
style=subsite.xsl; \
fi; \
$(XSLTPROC) --stringparam pagename $$name --nonet \
$(top_srcdir)/docs/$$style $< > $@ \
$(top_srcdir)/docs/site.xsl $< > $@ \
|| { rm $@ && exit 1; }; fi
%.html: %.html.tmp
@@ -255,7 +247,7 @@ MAINTAINERCLEANFILES += \
|| { rm $(srcdir)/$@ && exit 1; }; \
else echo "missing XHTML1 DTD"; cat $< > $(srcdir)/$@ ; fi ; fi
%.php.tmp: %.php.in site.xsl page.xsl
%.php.tmp: %.php.in site.xsl page.xsl sitemap.html.in
@if [ -x $(XSLTPROC) ] ; then \
echo "Generating $@"; \
$(XSLTPROC) --stringparam pagename $(@:.tmp=) --nonet \
@@ -271,7 +263,7 @@ MAINTAINERCLEANFILES += \
$(apihtml_generated): html/index.html
html/index.html: libvirt-api.xml newapi.xsl page.xsl $(APIBUILD_STAMP)
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
$(XSLTPROC) --nonet -o $(srcdir)/ \
--stringparam builddir '$(abs_top_builddir)' \
@@ -329,23 +321,13 @@ $(APIBUILD_STAMP): $(srcdir)/apibuild.py \
$(top_srcdir)/include/libvirt/libvirt-admin.h \
$(top_srcdir)/include/libvirt/virterror.h \
$(top_srcdir)/src/libvirt.c \
$(top_srcdir)/src/libvirt-domain-snapshot.c \
$(top_srcdir)/src/libvirt-domain.c \
$(top_srcdir)/src/libvirt-host.c \
$(top_srcdir)/src/libvirt-interface.c \
$(top_srcdir)/src/libvirt-network.c \
$(top_srcdir)/src/libvirt-nodedev.c \
$(top_srcdir)/src/libvirt-nwfilter.c \
$(top_srcdir)/src/libvirt-secret.c \
$(top_srcdir)/src/libvirt-storage.c \
$(top_srcdir)/src/libvirt-stream.c \
$(top_srcdir)/src/libvirt-lxc.c \
$(top_srcdir)/src/libvirt-qemu.c \
$(top_srcdir)/src/libvirt-admin.c \
$(top_srcdir)/src/util/virerror.c \
$(top_srcdir)/src/util/virevent.c \
$(top_srcdir)/src/util/virtypedparam.c
$(AM_V_GEN)srcdir=$(srcdir) builddir=$(builddir) $(PYTHON) $(APIBUILD)
$(AM_V_GEN)srcdir=$(srcdir) $(PYTHON) $(APIBUILD)
touch $@
@@ -353,10 +335,11 @@ check-local: all
dist-local: all
clean-local:
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html html/*.html
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
maintainer-clean-local: clean-local
rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml \
todo.html.in
rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
rm -rf $(srcdir)/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-refs.xml
rm -rf $(srcdir)/libvirt-admin-api.xml $(srcdir)/libvirt-admin-refs.xml
@@ -368,9 +351,6 @@ install-data-local:
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
for f in $(css) $(dot_html) $(gif) $(png); do \
$(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR); done
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/logos
for f in $(logofiles); do \
$(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR)/logos; done
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/html
for h in $(apihtml); do \
$(INSTALL) -m 0644 $(srcdir)/$$h $(DESTDIR)$(HTML_DIR)/html; done
@@ -383,19 +363,11 @@ install-data-local:
for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
$(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
done
$(INSTALL_DATA) $(srcdir)/libvirtLogo.png $(DESTDIR)$(pkgdatadir)
uninstall-local:
for f in $(css) $(dot_html) $(gif) $(png); do \
rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
done
for f in $(logofiles); do \
rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
done
for h in $(apihtml); do rm -f $(DESTDIR)$(HTML_DIR)/$$h; done
for p in $(apipng); do rm -f $(DESTDIR)$(HTML_DIR)/$$p; done
for f in $(internals_html); do \
rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
done
for h in $(apihtml); do rm $(DESTDIR)$(HTML_DIR)/$$h; done
for p in $(apipng); do rm $(DESTDIR)$(HTML_DIR)/$$p; done
for f in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
rm -f $(DESTDIR)$(DEVHELP_DIR)/$$(basename $$f); \
rm $(DESTDIR)$(DEVHELP_DIR)/$$(basename $$f); \
done

View File

@@ -224,10 +224,6 @@
<td>secret_usage_target</td>
<td>Name of the associated iSCSI target, if any</td>
</tr>
<tr>
<td>secret_usage_name</td>
<td>Name of the associated TLS secret, if any</td>
</tr>
</tbody>
</table>
@@ -334,9 +330,9 @@
</p>
<pre>
polkit.addRule(function(action, subject) {
....logic to check 'action' and 'subject'...
});
polkit.addRule(function(action, subject) {
....logic to check 'action' and 'subject'...
});
</pre>
<p>

View File

@@ -21,7 +21,6 @@ debugsym=None
# C parser analysis code
#
included_files = {
"libvirt-common.h": "header with general libvirt API definitions",
"libvirt-domain.h": "header with general libvirt API definitions",
"libvirt-domain-snapshot.h": "header with general libvirt API definitions",
"libvirt-event.h": "header with general libvirt API definitions",
@@ -112,12 +111,6 @@ ignored_macros = {
"_virMemoryParameter": "backward compatibility macro for virTypedParameter",
}
# macros that should be completely skipped
hidden_macros = {
"VIR_DEPRECATED": "internal macro to mark deprecated apis",
"VIR_EXPORT_VAR": "internal macro to mark exported vars",
}
def escape(raw):
raw = string.replace(raw, '&', '&amp;')
raw = string.replace(raw, '<', '&lt;')
@@ -240,11 +233,6 @@ class index:
self.references = {}
self.info = {}
def warning(self, msg):
global warnings
warnings = warnings + 1
print msg
def add_ref(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
if name[0:2] == '__':
return None
@@ -1046,11 +1034,6 @@ class CParser:
name = string.split(name, '(') [0]
except:
pass
# skip hidden macros
if name in hidden_macros:
return token
strValue = None
if len(lst) == 1 and lst[0][0] == '"' and lst[0][-1] == '"':
strValue = lst[0][1:-1]
@@ -1398,8 +1381,7 @@ class CParser:
token = self.token()
while token[0] != "sep" or (token[1] != ',' and
token[1] != '}'):
# We might be dealing with '1U << 12' here
value = value + re.sub("^(\d+)U$","\\1", token[1])
value = value + token[1]
token = self.token()
else:
try:
@@ -2267,7 +2249,6 @@ class docBuilder:
if name == debugsym and not quiet:
print "=>", id
# NB: this is consumed by a regex in 'getAPIFilenames' in hvsupport.pl
output.write(" <%s name='%s' file='%s' module='%s'>\n" % (id.type,
name, self.modulename_file(id.header),
self.modulename_file(id.module)))
@@ -2586,64 +2567,52 @@ class docBuilder:
output.close()
class app:
def warning(self, msg):
global warnings
warnings = warnings + 1
print msg
def rebuild(self, name):
if name not in ["libvirt", "libvirt-qemu", "libvirt-lxc", "libvirt-admin"]:
self.warning("rebuild() failed, unknown module %s" % name)
return None
builder = None
srcdir = os.path.abspath((os.environ["srcdir"]))
builddir = os.path.abspath((os.environ["builddir"]))
if srcdir == builddir:
builddir = None
if glob.glob(srcdir + "/../src/libvirt.c") != [] :
if not quiet:
print "Rebuilding API description for %s" % name
dirs = [srcdir + "/../src",
srcdir + "/../src/util",
srcdir + "/../include/libvirt"]
if (builddir and
not os.path.exists(srcdir + "/../include/libvirt/libvirt-common.h")):
dirs.append(builddir + "/../include/libvirt")
builder = docBuilder(name, srcdir, dirs, [])
elif glob.glob("src/libvirt.c") != [] :
if not quiet:
print "Rebuilding API description for %s" % name
builder = docBuilder(name, srcdir,
["src", "src/util", "include/libvirt"],
[])
else:
self.warning("rebuild() failed, unable to guess the module")
return None
builder.scan()
builder.analyze()
builder.serialize()
return builder
#
# for debugging the parser
#
def parse(self, filename):
parser = CParser(filename)
idx = parser.parse()
return idx
def rebuild(name):
if name not in ["libvirt", "libvirt-qemu", "libvirt-lxc", "libvirt-admin"]:
self.warning("rebuild() failed, unknown module %s") % name
return None
builder = None
srcdir = os.environ["srcdir"]
if glob.glob(srcdir + "/../src/libvirt.c") != [] :
if not quiet:
print "Rebuilding API description for %s" % name
dirs = [srcdir + "/../src",
srcdir + "/../src/util",
srcdir + "/../include/libvirt"]
if glob.glob(srcdir + "/../include/libvirt/libvirt.h") == [] :
dirs.append("../include/libvirt")
builder = docBuilder(name, srcdir, dirs, [])
elif glob.glob("src/libvirt.c") != [] :
if not quiet:
print "Rebuilding API description for %s" % name
builder = docBuilder(name, srcdir,
["src", "src/util", "include/libvirt"],
[])
else:
self.warning("rebuild() failed, unable to guess the module")
return None
builder.scan()
builder.analyze()
builder.serialize()
return builder
#
# for debugging the parser
#
def parse(filename):
parser = CParser(filename)
idx = parser.parse()
return idx
if __name__ == "__main__":
app = app()
if len(sys.argv) > 1:
debug = 1
app.parse(sys.argv[1])
parse(sys.argv[1])
else:
app.rebuild("libvirt")
app.rebuild("libvirt-qemu")
app.rebuild("libvirt-lxc")
app.rebuild("libvirt-admin")
rebuild("libvirt")
rebuild("libvirt-qemu")
rebuild("libvirt-lxc")
rebuild("libvirt-admin")
if warnings > 0:
sys.exit(2)
else:

View File

@@ -2,7 +2,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Applications using libvirt</h1>
<h1>Applications using <strong>libvirt</strong></h1>
<p>
This page provides an illustration of the wide variety of
@@ -19,15 +19,12 @@
be added here, or simply send a patch against the documentation
in the libvirt.git docs subdirectory.
If your application uses libvirt as its API,
the following graphics are available for your website to advertise
the following graphic is available for your website to advertise
support for libvirt:
</p>
<p class="image">
<img src="logos/logo-square-powered-96.png" alt="libvirt powered"/>
<img src="logos/logo-square-powered-128.png" alt="libvirt powered"/>
<img src="logos/logo-square-powered-192.png" alt="libvirt powered"/>
<img src="logos/logo-square-powered-256.png" alt="libvirt powered"/>
<img src="madeWith.png" alt="Made with libvirt"/>
</p>
<h2><a name="clientserver">Client/Server applications</a></h2>
@@ -211,17 +208,6 @@
to remote consoles supporting the VNC protocol. Also provides
an optional mozilla browser plugin.
</dd>
<dt><a href="http://f1ash.github.io/qt-virt-manager">qt-virt-manager</a></dt>
<dd>
The Qt GUI for create and control VMs and another virtual entities
(aka networks, storages, interfaces, secrets, network filters).
Contains integrated LXC/SPICE/VNC viewer for accessing the graphical or
text console associated with a virtual machine or container.
</dd>
<dt><a href="http://f1ash.github.io/qt-virt-manager/#virtual-machines-viewer">qt-remote-viewer</a></dt>
<dd>
The Qt VNC/SPICE viewer for access to remote desktops or VMs.
</dd>
</dl>
<h2><a name="iaas">Infrastructure as a Service (IaaS)</a></h2>
@@ -365,14 +351,6 @@
your Xen or QEMU/KVM guests, or to integrate with your existing Nagios
installation.
</dd>
<dt><a href="http://www.pcp.io/man/man1/pmdalibvirt.1.html" shape="rect">PCP</a></dt>
<dd>
The PCP libvirt PMDA (plugin) is part of the
<a href="http://pcp.io/" shape="rect">PCP</a> toolkit and provides
hypervisor and guest information and complete set of guest performance
metrics. It supports pCPU, vCPU, memory, block device, network interface,
and performance event metrics for each virtual guest.
</dd>
<dt><a href="http://community.zenoss.org/docs/DOC-4687">Zenoss</a></dt>
<dd>
The Zenoss libvirt Zenpack adds support for monitoring virtualization
@@ -426,14 +404,6 @@
infrastructure. You can deploy a new service just dragging and
dropping a VM.
</dd>
<dt><a href="https://kimchi-project.github.io/kimchi/">Kimchi</a></dt>
<dd>
Kimchi is an HTML5 based management tool for KVM. It is designed to
make it as easy as possible to get started with KVM and create your first guest.
Kimchi manages KVM guests through libvirt. The management interface is accessed
over the web using a browser that supports HTML5.
</dd>
<dt><a href="http://ovirt.org/">oVirt</a></dt>
<dd>
oVirt provides the ability to manage large numbers of virtual

7
docs/archdomain.html.in Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Domain management architecture</h1>
</body>
</html>

54
docs/archnetwork.html.in Normal file
View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Network management architecture</h1>
<ul id="toc"></ul>
<h2><a name="architecture">Architecture illustration</a></h2>
<p>
The diagrams below illustrate some of the network configurations
enabled by the libvirt networking APIs
</p>
<ul>
<li><strong>VLAN 1</strong>. This virtual network has connectivity
to <code>LAN 2</code> with traffic forwarded and NATed.
</li>
<li><strong>VLAN 2</strong>. This virtual network is completely
isolated from any physical LAN.
</li>
<li><strong>Guest A</strong>. The first network interface is bridged
to the physical <code>LAN 1</code>. The second interface is connected
to a virtual network <code>VLAN 1</code>.
</li>
<li><strong>Guest B</strong>. The first network interface is connected
to a virtual network <code>VLAN 1</code>, giving it limited NAT
based connectivity to LAN2. It has a second network interface
connected to <code>VLAN 2</code>. It acts a router allowing limited
traffic between the two VLANs, thus giving <code>Guest C</code>
connectivity to the physical <code>LAN 2</code>.
</li>
<li><strong>Guest C</strong>. The only network interface is connected
to a virtual network <code>VLAN 2</code>. It has no direct connectivity
to a physical LAN, relying on <code>Guest B</code> to route traffic
on its behalf.
</li>
</ul>
<h3><a name="logical">Logical diagram</a></h3>
<p class="image">
<img src="libvirt-net-logical.png" alt="Logical network architecture"/>
</p>
<h3><a name="physical">Physical diagram</a></h3>
<p class="image">
<img src="libvirt-net-physical.png" alt="Physical network architecture"/>
</p>
</body>
</html>

7
docs/archnode.html.in Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Node device management architecture</h1>
</body>
</html>

32
docs/archstorage.html.in Normal file
View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Storage management architecture</h1>
<p>
The storage management APIs are based around 2 core concepts
</p>
<ol>
<li>
<strong>Volume</strong> - a single storage volume which can
be assigned to a guest, or used for creating further pools. A
volume is either a block device, a raw file, or a special format
file.
</li>
<li>
<strong>Pool</strong> - provides a means for taking a chunk
of storage and carving it up into volumes. A pool can be used to
manage things such as a physical disk, a NFS server, a iSCSI target,
a host adapter, an LVM group.
</li>
</ol>
<p>
These two concepts are mapped through to two libvirt objects, a
<code>virStorageVolPtr</code> and a <code>virStoragePoolPtr</code>,
each with a collection of APIs for their management.
</p>
</body>
</html>

View File

@@ -57,13 +57,13 @@
</p>
<dl>
<dt><code>pid</code></dt>
<dt>pid</dt>
<dd>Process ID of the libvirtd daemon generating the audit record.</dd>
<dt><code>uid</code></dt>
<dt>uid</dt>
<dd>User ID of the libvirtd daemon process generating the audit record.</dd>
<dt><code>subj</code></dt>
<dt>subj</dt>
<dd>Security context of the libvirtd daemon process generating the audit record.</dd>
<dt><code>msg</code></dt>
<dt>msg</dt>
<dd>String containing a list of key=value pairs specific to the type of audit record being reported.</dd>
</dl>
@@ -72,21 +72,21 @@
</p>
<dl>
<dt><code>virt</code></dt>
<dt>virt</dt>
<dd>Type of virtualization driver used. One of <code>qemu</code> or <code>lxc</code></dd>
<dt><code>vm</code></dt>
<dt>vm</dt>
<dd>Host driver unique name of the guest</dd>
<dt><code>uuid</code></dt>
<dt>uuid</dt>
<dd>Globally unique identifier for the guest</dd>
<dt><code>exe</code></dt>
<dt>exe</dt>
<dd>Path of the libvirtd daemon</dd>
<dt><code>hostname</code></dt>
<dt>hostname</dt>
<dd>Currently unused</dd>
<dt><code>addr</code></dt>
<dt>addr</dt>
<dd>Currently unused</dd>
<dt><code>terminal</code></dt>
<dt>terminal</dt>
<dd>Currently unused</dd>
<dt><code>res</code></dt>
<dt>res</dt>
<dd>Result of the action, either <code>success</code> or <code>failed</code></dd>
</dl>
@@ -98,15 +98,15 @@
</p>
<dl>
<dt><code>op</code></dt>
<dt>op</dt>
<dd>Type of operation performed. One of <code>start</code>, <code>stop</code> or <code>init</code></dd>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the operation to happen</dd>
<dt><code>vm-pid</code></dt>
<dt>vm-pid</dt>
<dd>ID of the primary/leading process associated with the guest</dd>
<dt><code>init-pid</code></dt>
<dt>init-pid</dt>
<dd>ID of the <code>init</code> process in a container. Only if <code>op=init</code> and <code>virt=lxc</code></dd>
<dt><code>pid-ns</code></dt>
<dt>pid-ns</dt>
<dd>Namespace ID of the <code>init</code> process in a container. Only if <code>op=init</code> and <code>virt=lxc</code></dd>
</dl>
@@ -118,11 +118,11 @@
</p>
<dl>
<dt><code>model</code></dt>
<dt>model</dt>
<dd>The security driver type. One of <code>selinux</code> or <code>apparmor</code></dd>
<dt><code>vm-ctx</code></dt>
<dt>vm-ctx</dt>
<dd>Security context for the guest process</dd>
<dt><code>img-ctx</code></dt>
<dt>img-ctx</dt>
<dd>Security context for the guest disk images and other assigned host resources</dd>
</dl>
@@ -144,13 +144,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>vcpu</code></dd>
<dt><code>old-vcpu</code></dt>
<dt>old-vcpu</dt>
<dd>Original vCPU count, or 0</dd>
<dt><code>new-vcpu</code></dt>
<dt>new-vcpu</dt>
<dd>Updated vCPU count</dd>
</dl>
@@ -162,13 +162,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>mem</code></dd>
<dt><code>old-mem</code></dt>
<dt>old-mem</dt>
<dd>Original memory size in bytes, or 0</dd>
<dt><code>new-mem</code></dt>
<dt>new-mem</dt>
<dd>Updated memory size in bytes</dd>
</dl>
@@ -178,13 +178,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>disk</code></dd>
<dt><code>old-disk</code></dt>
<dt>old-disk</dt>
<dd>Original host file or device path acting as the disk backing file</dd>
<dt><code>new-disk</code></dt>
<dt>new-disk</dt>
<dd>Updated host file or device path acting as the disk backing file</dd>
</dl>
@@ -195,13 +195,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>net</code></dd>
<dt><code>old-net</code></dt>
<dt>old-net</dt>
<dd>Original MAC address of the guest network interface</dd>
<dt><code>new-net</code></dt>
<dt>new-net</dt>
<dd>Updated MAC address of the guest network interface</dd>
</dl>
@@ -211,13 +211,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>net</code></dd>
<dt><code>net</code></dt>
<dt>net</dt>
<dd>MAC address of the host network interface</dd>
<dt><code>rdev</code></dt>
<dt>rdev</dt>
<dd>Name of the host network interface</dd>
</dl>
@@ -227,13 +227,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>fs</code></dd>
<dt><code>old-fs</code></dt>
<dt>old-fs</dt>
<dd>Original host directory, file or device path backing the filesystem </dd>
<dt><code>new-fs</code></dt>
<dt>new-fs</dt>
<dd>Updated host directory, file or device path backing the filesystem</dd>
</dl>
@@ -243,15 +243,15 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>hostdev</code> or <code>dev</code></dd>
<dt><code>dev</code></dt>
<dt>dev</dt>
<dd>The unique bus identifier of the USB, PCI or SCSI device, if <code>resrc=dev</code></dd>
<dt><code>disk</code></dt>
<dt>disk</dt>
<dd>The path of the block device assigned to the guest, if <code>resrc=hostdev</code></dd>
<dt><code>chardev</code></dt>
<dt>chardev</dt>
<dd>The path of the character device assigned to the guest, if <code>resrc=hostdev</code></dd>
</dl>
@@ -261,11 +261,11 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>tpm</code></dd>
<dt><code>device</code></dt>
<dt>device</dt>
<dd>The path of the host TPM device assigned to the guest</dd>
</dl>
@@ -275,13 +275,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>rng</code></dd>
<dt><code>old-rng</code></dt>
<dt>old-rng</dt>
<dd>Original path of the host entropy source for the RNG</dd>
<dt><code>new-rng</code></dt>
<dt>new-rng</dt>
<dd>Updated path of the host entropy source for the RNG</dd>
</dl>
@@ -291,13 +291,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>chardev</code></dd>
<dt><code>old-chardev</code></dt>
<dt>old-chardev</dt>
<dd>Original path of the backing character device for given emulated device</dd>
<dt><code>new-chardev</code></dt>
<dt>new-chardev</dt>
<dd>Updated path of the backing character device for given emulated device</dd>
</dl>
@@ -307,15 +307,15 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>smartcard</code></dd>
<dt><code>old-smartcard</code></dt>
<dt>old-smartcard</dt>
<dd>Original path of the backing character device, certificate store or
"nss-smartcard-device" for host smartcard passthrough.
</dd>
<dt><code>new-smartcard</code></dt>
<dt>new-smartcard</dt>
<dd>Updated path of the backing character device, certificate store or
"nss-smartcard-device" for host smartcard passthrough.
</dd>
@@ -327,13 +327,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>redir</code></dd>
<dt><code>bus</code></dt>
<dt>bus</dt>
<dd>The bus type, only <code>usb</code> allowed</dd>
<dt><code>device</code></dt>
<dt>device</dt>
<dd>The device type, only <code>USB redir</code> allowed</dd>
</dl>
@@ -344,32 +344,13 @@
</p>
<dl>
<dt><code>reason</code></dt>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>resrc</code></dt>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>cgroup</code></dd>
<dt><code>cgroup</code></dt>
<dt>cgroup</dt>
<dd>The name of the cgroup controller</dd>
</dl>
<h4><a name="typeresourceshmem">Shared memory</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt><code>resrc</code></dt>
<dd>The type of resource assigned. Set to <code>shmem</code></dd>
<dt><code>reason</code></dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt><code>size</code></dt>
<dd>The size of the shared memory region</dd>
<dt><code>shmem</code></dt>
<dd>Name of the shared memory region</dd>
<dt><code>source</code></dt>
<dd>Path of the backing character device for given emulated device</dd>
</dl>
</body>
</html>

View File

@@ -76,11 +76,7 @@ password=letmein
[credentials-dev]
username=joe
password=hello
[credentials-defgrp]
username=defuser
password=defpw</pre>
password=hello</pre>
<p>
The second set of groups provide mappings of credentials to
@@ -94,8 +90,7 @@ credentials=$CREDENTIALS</pre>
<p>
For example, following the previous example, here is how to
map some machines. For convenience libvirt supports a default
mapping of credentials to machines:
list some machines
</p>
<pre>
@@ -111,15 +106,8 @@ credentials=test
[auth-libvirt-prod1.example.com]
credentials=prod
[auth-libvirt-default]
credentials=defgrp
[auth-esx-dev1.example.com]
credentials=dev
[auth-esx-default]
credentials=defgrp</pre>
credentials=dev</pre>
<p>
The following service types are known to libvirt
@@ -173,7 +161,7 @@ the libvirt daemon.
<h2><a name="ACL_server_polkit">UNIX socket PolicyKit auth</a></h2>
<p>
If libvirt contains support for PolicyKit, then access control options are
more advanced. The <code>auth_unix_rw</code> parameter will default to
more advanced. The <code>unix_sock_auth</code> parameter will default to
<code>polkit</code>, and the file permissions will default to <code>0777</code>
even on the RW socket. Upon connecting to the socket, the client application
will be required to identify itself with PolicyKit. The default policy for the
@@ -204,72 +192,16 @@ ResultActive=yes</pre>
Further examples of PolicyKit setup can be found on the
<a href="http://wiki.libvirt.org/page/SSHPolicyKitSetup">wiki page</a>.
</p>
<h2><a name="ACL_server_sasl">SASL pluggable authentication</a></h2>
<h2><a name="ACL_server_username">Username/password auth</a></h2>
<p>
Libvirt integrates with the cyrus-sasl library to provide a pluggable authentication
system using the SASL protocol. SASL can be used in combination with libvirtd's TLS
or TCP socket listeners. When used with the TCP listener, the SASL mechanism is
rqeuired to provide session encryption in addition to authentication. Only a very
few SASL mechanisms are able to do this, and of those that can do it, only the
GSSAPI plugin is considered acceptably secure by modern standards:
</p>
<dl>
<dt>GSSAPI</dt>
<dd><strong>This is the current default mechanism to use with libvirtd</strong>.
It uses the Kerberos v5 authentication protocol underneath, and assuming
the Kerberos client/server are configured with modern ciphers (AES),
it provides strong session encryption capabilities.</dd>
<dt>DIGEST-MD5</dt>
<dd>This was previously set as the default mechanism to use with libvirtd.
It provides a simple username/password based authentication mechanism
that includes session encryption.
<a href="https://tools.ietf.org/html/rfc6331">RFC 6331</a>, however,
documents a number of serious security flaws with DIGEST-MD5 and as a
result marks it as <code>OBSOLETE</code>. Specific concerns are that
it is vulnerable to MITM attacks and the MD5 hash can be brute-forced
to reveal the password. A replacement is provided via the SCRAM mechanism,
however, note that this does not provide encryption, so the SCRAM
mechanism can only be used on the libvirtd TLS listener.
</dd>
<dt>PASSDSS-3DES-1</dt>
<dd>This provides a simple username/password based authentication
mechanism that includes session encryption. The current cyrus-sasl
implementation does not provide a way to validate the server's
public key identity, thus it is susceptible to a MITM attacker
impersonating the server. It is also not enabled in many OS
distros when building SASL libraries.</dd>
<dt>KERBEROS_V4</dt>
<dd>This uses the obsolete Kerberos v4 protocol to provide both authentication
and session encryption. Kerberos v4 protocol has been obsolete since the
early 1990's and has known security vulnerabilities so this will never be
used in practice.</dd>
</dl>
<p>
Other SASL mechanisms, not listed above, can only be used when the libvirtd
TLS or UNIX socket listeners.
</p>
<h3><a name="ACL_server_username">Username/password auth</a></h3>
<p>
As noted above, the DIGEST-MD5 mechanism is considered obsolete and should
not be used anymore. To provide a simple username/password auth scheme on
the libvirt UNIX socket or TLS listeners, however, it is possible to use
the SCRAM mechanism. The <code>auth_unix_ro</code>, <code>auth_unix_rw</code>,
<code>auth_tls</code> config params in <code>libvirt.conf</code> can be used
to turn on SASL auth in these listeners.
</p>
<p>
Since the libvirt SASL config file defaults to using GSSAPI (Kerberos), a
config change is rquired to enable plain password auth. This is done by
editting <code>/etc/sasl2/libvirt.conf</code> to set the <code>mech_list</code>
parameter to <code>scram-sha-1</code>.
</p>
The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
username+password style authentication. It also provides for encryption of the data
stream, so the security of the plain TCP socket is on a par with that of the TLS
socket. If desired the UNIX socket and TLS socket can also have SASL enabled by
setting the <code>auth_unix_ro</code>, <code>auth_unix_rw</code>, <code>auth_tls</code>
config params in <code>libvirt.conf</code>.
</p>
<p>
Out of the box, no user accounts are defined, so no clients will be able to authenticate
on the TCP socket. Adding users and setting their passwords is done with the <code>saslpasswd2</code>
@@ -297,13 +229,17 @@ again:
<pre>
# saslpasswd2 -a libvirt -d fred
</pre>
<h3><a name="ACL_server_kerberos">GSSAPI/Kerberos auth</a></h3>
<h2><a name="ACL_server_kerberos">Kerberos auth</a></h2>
<p>
The plain TCP listener of the libvirt daemon defaults to using SASL for authentication.
The libvirt SASL config also defaults to GSSAPI, so there is no need to edit the
SASL config when using GSSAPI. If the libvirtd TLS or UNIX listeners are used,
then the Kerberos session encryption will be disabled since it is not required
in these scenarios - only the plain TCP listener needs encryption
The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
username+password style authentication. To enable Kerberos single-sign-on instead,
the libvirt SASL configuration file must be changed. This is <code>/etc/sasl2/libvirt.conf</code>.
The <code>mech_list</code> parameter must first be changed to <code>gssapi</code>
instead of the default <code>digest-md5</code>, and keytab should be set to
<code>/etc/libvirt/krb5.tab</code> . If SASL is enabled on the UNIX
and/or TLS sockets, Kerberos will also be used for them. Like DIGEST-MD5, the Kerberos
mechanism provides data encryption of the session.
</p>
<p>
Some operating systems do not install the SASL kerberos plugin by default. It

View File

@@ -14,10 +14,6 @@
<strong>C#</strong>: Arnaud Champion develops
<a href="csharp.html">C# bindings</a>.
</li>
<li>
<strong>Go</strong>: Daniel Berrange develops
<a href="https://godoc.org/github.com/libvirt/libvirt-go">Go bindings</a>.
</li>
<li>
<strong>Java</strong>: Daniel Veillard develops
<a href="java.html">Java bindings</a>.

View File

@@ -221,11 +221,11 @@ $ROOT
</p>
<pre>
...
&lt;resource&gt;
&lt;partition&gt;/machine/production&lt;/partition&gt;
&lt;/resource&gt;
...
...
&lt;resource&gt;
&lt;partition&gt;/machine/production&lt;/partition&gt;
&lt;/resource&gt;
...
</pre>
<p>

View File

@@ -13,9 +13,9 @@
</p>
<pre>
$ xz -c libvirt-x.x.x.tar.xz | tar xvf -
$ cd libvirt-x.x.x
$ ./configure</pre>
$ gunzip -c libvirt-x.x.x.tar.gz | tar xvf -
$ cd libvirt-x.x.x
$ ./configure</pre>
<p>
The <i>configure</i> script can be given options to change its default
@@ -28,7 +28,7 @@ $ ./configure</pre>
</p>
<pre>
$ ./configure <i>--help</i></pre>
$ ./configure <i>--help</i></pre>
<p>
When you have determined which options you want to use (if any),
@@ -49,9 +49,9 @@ $ ./configure <i>--help</i></pre>
</p>
<pre>
$ ./configure <i>[possible options]</i>
$ make
$ <b>sudo</b> <i>make install</i></pre>
$ ./configure <i>[possible options]</i>
$ make
$ <b>sudo</b> <i>make install</i></pre>
<p>
At this point you <b>may</b> have to run ldconfig or a similar utility
@@ -91,7 +91,7 @@ $ <b>sudo</b> <i>make install</i></pre>
drive or manual download, and run this any time libvirt.git
updates the commit stored in the .gnulib submodule:</p>
<pre>
$ GNULIB_SRCDIR=/path/to/gnulib ./autogen.sh --no-git
$ GNULIB_SRCDIR=/path/to/gnulib ./autogen.sh --no-git
</pre>
<p>To build &amp; install libvirt to your home
@@ -99,9 +99,9 @@ $ GNULIB_SRCDIR=/path/to/gnulib ./autogen.sh --no-git
</p>
<pre>
$ ./autogen.sh --prefix=$HOME/usr
$ make
$ <b>sudo</b> make install</pre>
$ ./autogen.sh --prefix=$HOME/usr
$ make
$ <b>sudo</b> make install</pre>
<p>
Be aware though, that binaries built with a custom prefix will not
@@ -111,8 +111,8 @@ $ <b>sudo</b> make install</pre>
</p>
<pre>
$ ./autogen.sh --system
$ make
$ ./autogen.sh --system
$ make
</pre>
<p>
@@ -123,9 +123,9 @@ $ make
</p>
<pre>
$ su -
# service libvirtd stop (or systemctl stop libvirtd.service)
# /home/to/your/checkout/daemon/libvirtd
$ su -
# service libvirtd stop (or systemctl stop libvirtd.service)
# /home/to/your/checkout/daemon/libvirtd
</pre>
<p>
@@ -134,7 +134,7 @@ $ su -
</p>
<pre>
$ ./run ./tools/virsh ....
$ ./run ./tools/virsh ....
</pre>
</body>
</html>

View File

@@ -2,7 +2,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Contacting the project contributors</h1>
<h1>Contacting the development team</h1>
<ul id="toc"></ul>
@@ -24,7 +24,7 @@
There are three mailing-lists:
</p>
<dl class="mail">
<dl>
<dt><a href="https://www.redhat.com/mailman/listinfo/libvir-list">libvir-list@redhat.com</a> (for development)</dt>
<dd>
Archives at <a href="https://www.redhat.com/archives/libvir-list">https://www.redhat.com/archives/libvir-list</a>

View File

@@ -1,140 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Contributing to libvirt</h1>
<p>
This page provides guidance on how to contribute to the
libvirt project
</p>
<ul id="toc"></ul>
<h2><a name="skills">Contributions required</a></h2>
<p>
The libvirt project is always looking for new contributors to
participate in ongoing activities. While code development is a
major part of the project, assistance is needed in many other
areas including documentation writing, bug triage, testing,
application integration, website / wiki content management,
translation, branding, social media and more. The only
requirement is an interest in virtualization and desire to
help.
</p>
<p>
The following is a non-exhaustive list of areas in which
people can contribute to libvirt. If you have ideas for
other contributions feel free to follow them.
</p>
<ul>
<li><strong>Software development</strong>. The core library / daemon (and
thus the bulk of coding) is written in C, but there are
language bindings written in Python, Perl, Java, Ruby,
Php, OCaml and Go. There are also higher level wrappers
mapping libvirt into other object frameworks, such GLib,
CIM and SNMP</li>
<li><strong>Translation</strong>. All the libvirt modules aim to support
translations where appropriate. All translation is
handling outside of the normal libvirt review process,
using the <a href="http://fedora.zanata.org">Fedora
instance</a> of the Zanata tool. Thus people wishing
to contribute to translation should join the Fedora
translation team</li>
<li><strong>Documentation</strong>. There are docbook guides on various
aspects of libvirt, particularly application development
guides for the C library and Python, and a virsh command
reference. There is thus scope for work by people who are
familiar with using or developing against libvirt, to
write further content for these guides. There is also a
need for people to review existing content for copy editing
and identifying gaps in the docs</li>
<li><strong>Website / wiki curation</strong>. The bulk of the website is
maintained in the primary GIT repository, while the wiki
site uses mediawiki. In both cases there is a need for
people to both write new content and curate existing
content to identify outdated information, improve its
organization and target gaps.</li>
<li><strong>Testing</strong>. There are a number of tests suites that can run
automated tests against libvirt. The coverage of the tests
is never complete, so there is a need for people to create
new test suites and / or provide environments to actually
run the tests in a variety of deployment scenarios.</li>
<li><strong>Code analysis</strong>. The libvirt project has access to the coverity
tool to run static analysis against the codebase, however,
there are other types of code analysis that can be useful.
In particular fuzzing of the inputs can be very effective
at identifying problematic edge cases.</li>
<li><strong>Security handling</strong>. Downstream (operating system) vendors
who distribute libvirt may wish to propose a person to
be part of the security handling team, to get early access
to information about forthcoming vulnerability fixes.</li>
<li><strong>Evangalism</strong>. Work done by the project is of no benefit
unless the (potential) user community knows that it
exists. Thus it is critically important to the health
and future growth of the project, that there are a people
who evangalise the work created by the project. This can
take many forms, writing blog posts (about usage of features,
personal user experiances, areas for future work, and more),
syndicating docs and blogs via social media, giving user
group and/or conference talks about libvirt.</li>
<li><strong>User assistance</strong>. Since documentation
is never perfect, there are inevitably cases where users
will struggle to attain a deployment goal they have, or
run into trouble with managing an existing deployment.
While some users may be able to contact a software vendor
to obtain support, it is common to rely on community help
forums such as <a href="contact.html#email">libvirt users
mailing list</a>, or sites such as
<a href="http://stackoverflow.com/questions/tagged/libvirt">stackoverflow.</a>
People who are familiar with libvirt and have ability &amp;
desire to help other users are encouraged to participate in
these help forums.</li>
</ul>
<h2><a name="comms">Communication</a></h2>
<p>
For full details on contacting other project contributors
read the <a href="contact.html">contact</a> page. There
are two main channels that libvirt uses for communication
between contributors:
</p>
<h3><a name="email">Mailing lists</a></h3>
<p>
The project has a number of
<a href="contact.html#email">mailing lists</a> for
general communication between contributors.
In general any design discussions and review
of contributions will take place on the mailing
lists, so it is important for all contributors
to follow the traffic.
</p>
<h3><a name="irc">Instant messaging / chat</a></h3>
<p>
Contributors to libvirt are encouraged to join the
<a href="contact.html#irc">IRC channel</a> used by
the project, where they can have live conversations
with others members.
</p>
<h2><a name="outreach">Student / outreach coding programs</a></h2>
<p>
Since 2016, the libvirt project directly participates as an
organization in the <a href="http://wiki.libvirt.org/page/Google_Summer_of_Code_Ideas">Google Summer of Code program</a>. Prior to
this the project had a number of students in the program
via a joint application with the QEMU project. People are
encouraged to look at both the libvirt and QEMU programs
to identify potentially interesting projects to work on.
</p>
</body>
</html>

50
docs/deployment.html.in Normal file
View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Deployment</h1>
<ul id="toc"></ul>
<h2><a name="packages">Pre-packaged releases</a></h2>
<p>
The libvirt API is now available in all major Linux distributions,
so the simplest deployment approach is to use your distributions'
package management software to install the <code>libvirt</code>
module.
</p>
<h2><a name="tarball">Self-built releases</a></h2>
<p>
libvirt uses GNU autotools for its build system, so deployment
follows the usual process of <code>configure; make ; make install</code>
</p>
<pre>
# ./configure --prefix=$HOME/usr
# make
# make install
</pre>
<h2><a name="git">Built from GIT</a></h2>
<p>
When building from GIT it is necessary to generate the autotools
support files. This requires having <code>autoconf</code>,
<code>automake</code>, <code>libtool</code> and <code>intltool</code>
installed. The process can be automated with the <code>autogen.sh</code>
script.
</p>
<pre>
# ./autogen.sh --prefix=$HOME/usr
# make
# make install
</pre>
</body>
</html>

View File

@@ -28,14 +28,14 @@
</p>
<pre>
# C language
$ git clone <a href="http://libvirt.org/git/?p=libvirt-appdev-guide.git">git://libvirt.org/libvirt-appdev-guide.git</a>
# C language
$ git clone <a href="http://libvirt.org/git/?p=libvirt-appdev-guide.git">git://libvirt.org/libvirt-appdev-guide.git</a>
# Python language
$ git clone <a href="http://libvirt.org/git/?p=libvirt-appdev-guide-python.git">git://libvirt.org/libvirt-appdev-guide-python.git</a>
# Python language
$ git clone <a href="http://libvirt.org/git/?p=libvirt-appdev-guide-python.git">git://libvirt.org/libvirt-appdev-guide-python.git</a>
# Publican Style/Theme
$ git clone <a href="http://libvirt.org/git/?p=libvirt-publican.git">git://libvirt.org/libvirt-publican.git</a>
# Publican Style/Theme
$ git clone <a href="http://libvirt.org/git/?p=libvirt-publican.git">git://libvirt.org/libvirt-publican.git</a>
</pre>
</body>

View File

@@ -1,166 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body class="docs">
<div class="panel">
<h2>Deployment / operation</h2>
<dl>
<dt><a href="apps.html">Applications</a></dt>
<dd>Applications known to use libvirt</dd>
<dt><a href="windows.html">Windows</a></dt>
<dd>Downloads for Windows</dd>
<dt><a href="migration.html">Migration</a></dt>
<dd>Migrating guests between machines</dd>
<dt><a href="remote.html">Remote access</a></dt>
<dd>Enable remote access over TCP</dd>
<dt><a href="auth.html">Authentication</a></dt>
<dd>Configure authentication for the libvirt daemon</dd>
<dt><a href="acl.html">Access control</a></dt>
<dd>Configure access control libvirt APIs with <a href="aclpolkit.html">polkit</a></dd>
<dt><a href="logging.html">Logging</a></dt>
<dd>The library and the daemon logging support</dd>
<dt><a href="auditlog.html">Audit log</a></dt>
<dd>Audit trail logs for host operations</dd>
<dt><a href="firewall.html">Firewall</a></dt>
<dd>Firewall and network filter configuration</dd>
<dt><a href="hooks.html">Hooks</a></dt>
<dd>Hooks for system specific management</dd>
<dt><a href="nss.html">NSS module</a></dt>
<dd>Enable domain host name translation to IP addresses</dd>
<dt><a href="http://wiki.libvirt.org/page/FAQ">FAQ</a></dt>
<dd>Frequently asked questions</dd>
</dl>
</div>
<div class="panel">
<h2>Application development</h2>
<dl>
<dt><a href="devguide.html">Development Guide</a></dt>
<dd>A guide and reference for developing with libvirt</dd>
<dt><a href="virshcmdref.html">Virsh Commands</a></dt>
<dd>Command reference for virsh</dd>
<dt><a href="bindings.html">Language bindings</a></dt>
<dd>Bindings of the libvirt API for
<a href="csharp.html">c#</a>,
<a href="https://godoc.org/github.com/libvirt/libvirt-go">go</a>,
<a href="java.html">java</a>,
<a href="http://libvirt.org/ocaml/">ocaml</a>.
<a href="http://search.cpan.org/dist/Sys-Virt/">perl</a>,
<a href="python.html">python</a>,
<a href="php.html">php</a>,
<a href="http://libvirt.org/ruby/">ruby</a></dd>
<dt><a href="format.html">XML schemas</a></dt>
<dd>Description of the XML schemas for
<a href="formatdomain.html">domains</a>,
<a href="formatnetwork.html">networks</a>,
<a href="formatnwfilter.html">network filtering</a>,
<a href="formatstorage.html">storage</a>,
<a href="formatstorageencryption.html">storage encryption</a>,
<a href="formatcaps.html">capabilities</a>,
<a href="formatdomaincaps.html">domain capabilities</a>,
<a href="formatnode.html">node devices</a>,
<a href="formatsecret.html">secrets</a>,
<a href="formatsnapshot.html">snapshots</a></dd>
<dt><a href="uri.html">URI format</a></dt>
<dd>The URI formats used for connecting to libvirt</dd>
<dt><a href="locking.html">Disk locking</a></dt>
<dd>Ensuring exclusive guest access to disks with
<a href="locking-lockd.html">virtlockd</a> or
<a href="locking-sanlock.html">Sanlock</a></dd>
<dt><a href="cgroups.html">CGroups</a></dt>
<dd>Control groups integration</dd>
<dt><a href="html/index.html">API reference</a></dt>
<dd>Reference manual for the C public API, split in
<a href="html/libvirt-libvirt-common.html">common</a>,
<a href="html/libvirt-libvirt-domain.html">domain</a>,
<a href="html/libvirt-libvirt-domain-snapshot.html">domain snapshot</a>,
<a href="html/libvirt-virterror.html">error</a>,
<a href="html/libvirt-libvirt-event.html">event</a>,
<a href="html/libvirt-libvirt-host.html">host</a>,
<a href="html/libvirt-libvirt-interface.html">interface</a>,
<a href="html/libvirt-libvirt-network.html">network</a>,
<a href="html/libvirt-libvirt-nodedev.html">node device</a>,
<a href="html/libvirt-libvirt-nwfilter.html">network filter</a>,
<a href="html/libvirt-libvirt-secret.html">secret</a>,
<a href="html/libvirt-libvirt-storage.html">storage</a>,
<a href="html/libvirt-libvirt-stream.html">stream</a>
</dd>
<dt><a href="drivers.html">Drivers</a></dt>
<dd>Hypervisor specific driver information</dd>
<dt><a href="hvsupport.html">Driver support</a></dt>
<dd>matrix of API support per hypervisor per release</dd>
<dt><a href="secureusage.html">Secure usage</a></dt>
<dd>Secure usage of the libvirt APIs</dd>
</dl>
</div>
<div class="panel">
<h2>Project development</h2>
<dl>
<dt><a href="hacking.html">Contributor guidelines</a></dt>
<dd>General hacking guidelines for contributors</dd>
<dt><a href="bugs.html">Bug reports</a></dt>
<dd>How and where to report bugs and request features</dd>
<dt><a href="compiling.html">Compiling</a></dt>
<dd>How to compile libvirt</dd>
<dt><a href="goals.html">Goals</a></dt>
<dd>Terminology and goals of libvirt API</dd>
<dt><a href="api.html">API concepts</a></dt>
<dd>The libvirt API concepts</dd>
<dt><a href="api_extension.html">API extensions</a></dt>
<dd>Adding new public libvirt APIs</dd>
<dt><a href="internals/eventloop.html">Event loop and worker pool</a></dt>
<dd>Libvirt's event loop and worker pool mode</dd>
<dt><a href="internals/command.html">Spawning commands</a></dt>
<dd>Spawning commands from libvirt driver code</dd>
<dt><a href="internals/rpc.html">RPC protocol &amp; APIs</a></dt>
<dd>RPC protocol information and API / dispatch guide</dd>
<dt><a href="internals/locking.html">Lock managers</a></dt>
<dd>Use lock managers to protect disk content</dd>
<dt><a href="internals/oomtesting.html">Out of memory testing</a></dt>
<dd>Simulating OOM conditions in the test suite</dd>
<dt><a href="testsuites.html">Functional testing</a></dt>
<dd>Testing libvirt with <a href="testtck.html">TCK test suite</a> and
<a href="testapi.html">Libvirt-test-API</a></dd>
</dl>
</div>
<br class="clear"/>
<body>
<h1>Documentation</h1>
</body>
</html>

View File

@@ -6,417 +6,15 @@
<ul id="toc"></ul>
<h2><a name="releases">Project modules</a></h2>
<h2><a name="releases">Official Releases</a></h2>
<p>
The libvirt project maintains a number of inter-related modules beyond
the core C library/daemon.
</p>
<table class="top_table downloads">
<thead>
<tr>
<th>Module</th>
<th>Releases</th>
<th>GIT Repo</th>
<th>GIT Mirrors</th>
<th>Resources</th>
</tr>
</thead>
<tbody>
<tr>
<td>libvirt</td>
<td>
<a href="ftp://libvirt.org/libvirt/">ftp</a>
<a href="http://libvirt.org/sources/">http</a>
<a href="https://libvirt.org/sources/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt">gitlab</a>
<a href="https://github.com/libvirt/libvirt">github</a>
</td>
<td>
<a href="html/index.html">api ref</a>
<a href="news.html">changes</a>
</td>
</tr>
<tr>
<th colspan="7">Language bindings</th>
</tr>
<tr>
<td>C#</td>
<td>
<a href="ftp://libvirt.org/libvirt/csharp/">ftp</a>
<a href="http://libvirt.org/sources/csharp/">http</a>
<a href="https://libvirt.org/sources/csharp/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-csharp.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-csharp">gitlab</a>
<a href="https://github.com/libvirt/libvirt-csharp">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Go</td>
<td>
<a href="ftp://libvirt.org/libvirt/go/">ftp</a>
<a href="http://libvirt.org/sources/go/">http</a>
<a href="https://libvirt.org/sources/go/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-go.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-go">gitlab</a>
<a href="https://github.com/libvirt/libvirt-go">github</a>
</td>
<td>
<a href="https://godoc.org/github.com/libvirt/libvirt-go">api ref</a>
</td>
</tr>
<tr>
<td>Java</td>
<td>
<a href="ftp://libvirt.org/libvirt/java/">ftp</a>
<a href="http://libvirt.org/sources/java/">http</a>
<a href="https://libvirt.org/sources/java/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-java.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-java">gitlab</a>
<a href="https://github.com/libvirt/libvirt-java">github</a>
</td>
<td></td>
</tr>
<tr>
<td>OCaml</td>
<td>
<a href="ftp://libvirt.org/libvirt/ocaml/">ftp</a>
<a href="http://libvirt.org/sources/ocaml/">http</a>
<a href="https://libvirt.org/sources/ocaml/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-ocaml.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-ocaml">gitlab</a>
<a href="https://github.com/libvirt/libvirt-ocaml">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Perl (Sys::Virt)</td>
<td>
<a href="http://search.cpan.org/dist/Sys-Virt/">cpan</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-perl.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-perl">gitlab</a>
<a href="https://github.com/libvirt/libvirt-perl">github</a>
</td>
<td>
<a href="http://search.cpan.org/dist/Sys-Virt/">api ref</a>
<a href="http://libvirt.org/git/?p=libvirt-perl.git;a=blob;f=Changes;hb=HEAD">changes</a>
</td>
</tr>
<tr>
<td>PHP</td>
<td>
<a href="ftp://libvirt.org/libvirt/php/">ftp</a>
<a href="http://libvirt.org/sources/php/">http</a>
<a href="https://libvirt.org/sources/php/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-php.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-php">gitlab</a>
<a href="https://github.com/libvirt/libvirt-php">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Python</td>
<td>
<a href="ftp://libvirt.org/libvirt/python/">ftp</a>
<a href="http://libvirt.org/sources/python/">http</a>
<a href="https://libvirt.org/sources/python/">https</a>
<a href="https://pypi.python.org/pypi/libvirt-python">pypi</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-python.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-python">gitlab</a>
<a href="https://github.com/libvirt/libvirt-python">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Ruby</td>
<td>
<a href="ftp://libvirt.org/libvirt/ruby/">ftp</a>
<a href="http://libvirt.org/sources/ruby/">http</a>
<a href="https://libvirt.org/sources/ruby/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=ruby-libvirt.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/ruby-libvirt">gitlab</a>
<a href="https://github.com/libvirt/ruby-libvirt">github</a>
</td>
<td></td>
</tr>
<tr>
<th colspan="7">Integration modules</th>
</tr>
<tr>
<td>GLib / GConfig / GObject</td>
<td>
<a href="ftp://libvirt.org/libvirt/glib/">ftp</a>
<a href="http://libvirt.org/sources/glib/">http</a>
<a href="https://libvirt.org/sources/glib/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-glib.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-glib">gitlab</a>
<a href="https://github.com/libvirt/libvirt-glib">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Go XML</td>
<td>
<a href="ftp://libvirt.org/libvirt/go/">ftp</a>
<a href="http://libvirt.org/sources/go/">http</a>
<a href="https://libvirt.org/sources/go/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-go-xml.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-go-xml">gitlab</a>
<a href="https://github.com/libvirt/libvirt-go-xml">github</a>
</td>
<td>
<a href="https://godoc.org/github.com/libvirt/libvirt-go-xml">api ref</a>
</td>
</tr>
<tr>
<td>Console Proxy</td>
<td>
<a href="ftp://libvirt.org/libvirt/consoleproxy/">ftp</a>
<a href="http://libvirt.org/sources/consoleproxy/">http</a>
<a href="https://libvirt.org/sources/consoleproxy/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-console-proxy.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-console-proxy">gitlab</a>
<a href="https://github.com/libvirt/libvirt-console-proxy">github</a>
</td>
<td></td>
</tr>
<tr>
<td>CIM provider</td>
<td>
<a href="ftp://libvirt.org/libvirt/CIM/">ftp</a>
<a href="http://libvirt.org/sources/CIM/">http</a>
<a href="https://libvirt.org/sources/CIM/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-cim.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-cim">gitlab</a>
<a href="https://github.com/libvirt/libvirt-cim">github</a>
</td>
<td></td>
</tr>
<tr>
<td>CIM utils</td>
<td>
<a href="ftp://libvirt.org/libvirt/CIM/">ftp</a>
<a href="http://libvirt.org/sources/CIM/">http</a>
<a href="https://libvirt.org/sources/CIM/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libcmpiutil.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libcmpiutil">gitlab</a>
<a href="https://github.com/libvirt/libcmpiutil">github</a>
</td>
<td></td>
</tr>
<tr>
<td>SNMP</td>
<td>
<a href="ftp://libvirt.org/libvirt/snmp/">ftp</a>
<a href="http://libvirt.org/sources/snmp/">http</a>
<a href="https://libvirt.org/sources/snmp/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-snmp.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-snmp">gitlab</a>
<a href="https://github.com/libvirt/libvirt-snmp">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Application Sandbox</td>
<td>
<a href="ftp://libvirt.org/libvirt/sandbox/">ftp</a>
<a href="http://libvirt.org/sources/sandbox/">http</a>
<a href="https://libvirt.org/sources/sandbox/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-sandbox.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-sandbox">gitlab</a>
<a href="https://github.com/libvirt/libvirt-sandbox">github</a>
</td>
<td></td>
</tr>
<tr>
<th colspan="7">Testing</th>
</tr>
<tr>
<td>TCK</td>
<td>
<a href="ftp://libvirt.org/libvirt/tck/">ftp</a>
<a href="http://libvirt.org/sources/tck/">http</a>
<a href="https://libvirt.org/sources/tck/">https</a>
</td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-tck.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-tck">gitlab</a>
<a href="https://github.com/libvirt/libvirt-tck">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Test API</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-test-API.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-test-API">gitlab</a>
<a href="https://github.com/libvirt/libvirt-test-API">github</a>
</td>
<td></td>
</tr>
<tr>
<td>Jenkins Config</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-jenkins-ci.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-jenkins-ci">gitlab</a>
<a href="https://github.com/libvirt/libvirt-jenkins-ci">github</a>
</td>
<td></td>
</tr>
<tr>
<td>CIM Test</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=cimtest.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/cimtest">gitlab</a>
<a href="https://github.com/libvirt/cimtest">github</a>
</td>
<td></td>
</tr>
<tr>
<th colspan="7">Documentation</th>
</tr>
<tr>
<td>Publican Brand</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-publican.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-publican">gitlab</a>
<a href="https://github.com/libvirt/libvirt-publican">github</a>
</td>
<td></td>
</tr>
<tr>
<td>App Development Guide</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-appdev-guide">gitlab</a>
<a href="https://github.com/libvirt/libvirt-appdev-guide">github</a>
</td>
<td></td>
</tr>
<tr>
<td>App Development Guide Python</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-appdev-guide-python.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-appdev-guide-python">gitlab</a>
<a href="https://github.com/libvirt/libvirt-appdev-guide-python">github</a>
</td>
<td></td>
</tr>
<tr>
<td>virsh Command Reference</td>
<td></td>
<td>
<a href="http://libvirt.org/git/?p=libvirt-virshcmdref.git;a=summary">libvirt</a>
</td>
<td>
<a href="https://gitlab.com/libvirt/libvirt-virshcmdref">gitlab</a>
<a href="https://github.com/libvirt/libvirt-virshcmdref">github</a>
</td>
<td></td>
</tr>
</tbody>
</table>
<h2>Primary download site</h2>
<p>
Most modules have releases made available for download on the project
site, via FTP, HTTP or HTTPS. Some modules are instead made available
at alternative locations, for example, the Perl binding is made
available only on CPAN.
The latest versions of the libvirt C library can be downloaded from:
</p>
<ul>
<li><a href="ftp://libvirt.org/libvirt/">libvirt.org FTP server</a></li>
<li><a href="http://libvirt.org/sources/">libvirt.org HTTP server</a></li>
<li><a href="https://libvirt.org/sources/">libvirt.org HTTPS server</a></li>
</ul>
<h2><a name="hourly">Hourly development snapshots</a></h2>
@@ -430,77 +28,24 @@
</p>
<ul>
<li><a href="ftp://libvirt.org/libvirt/libvirt-git-snapshot.tar.xz">libvirt.org FTP server</a></li>
<li><a href="http://libvirt.org/sources/libvirt-git-snapshot.tar.xz">libvirt.org HTTP server</a></li>
<li><a href="ftp://libvirt.org/libvirt/libvirt-git-snapshot.tar.gz">libvirt.org FTP server</a></li>
<li><a href="http://libvirt.org/sources/libvirt-git-snapshot.tar.gz">libvirt.org HTTP server</a></li>
</ul>
<h2><a name="schedule">Primary release schedule</a></h2>
<p>
The core libvirt module follows a time based plan, with releases made
once a month on the 1st of each month give or take a few days. The only
exception is at the start of the year where there are two 6 weeks gaps
(first release in the middle of Jan, then skip the Feb release), giving
a total of 11 releases a year. The Python and Perl modules will aim to
release at the same time as the core libvirt module. Other modules have
independant ad-hoc releases with no fixed time schedle.
</p>
<h2><a name="numbering">Release numbering</a></h2>
<p>
Since libvirt 2.0.0, a time based version numbering rule
is applied to the core library releases. As such, the changes
in version number have do not have any implications with respect
to the scope of features or bugfixes included, the stability of
the code, or the API / ABI compatibility (libvirt API / ABI is
guaranteed stable forever). The rules applied for changing the
libvirt version number are:
</p>
<dl>
<dt><code>major</code></dt>
<dd>incremented by 1 for the first release of the year (the
Jan 15th release)</dd>
<dt><code>minor</code></dt>
<dd>reset to 0 with every major increment, otherwise incremented by 1
for each monthly release from git master</dd>
<dt><code>micro</code></dt>
<dd>always 0 for releases from git master, incremented by 1
for each stable maintenance release</dd>
</dl>
<p>
Prior to 2.0.0, the major/minor numbers were incremented
fairly arbitrarily, and maintenance releases appended a
fourth digit. The language bindings will aim to use the
same version number as the most recent core library API
they support. The other modules have their own distinct
release numbering sequence, though they generally aim
to follow the above rules for incrementing major/minor/micro
digits.
</p>
<h2><a name="maintenance">Maintenance releases</a></h2>
<p>
In the git repository are several stable maintenance branches
for the core library, matching the
pattern <code>v<i>major</i>.<i>minor</i>-maint</code>;
In the git repository are several stable maintenance branches,
matching the
pattern <code>v<i>major</i>.<i>minor</i>.<i>micro</i>-maint</code>;
these branches are forked off the corresponding
<code>v<i>major</i>.<i>minor</i>.0</code> formal
<code>v<i>major</i>.<i>minor</i>.<i>micro</i></code> formal
release, and may have further releases of the
form <code>v<i>major</i>.<i>minor</i>.<i>micro</i></code>.
form <code>v<i>major</i>.<i>minor</i>.<i>micro</i>.<i>rel</i></code>.
These maintenance branches should only contain bug fixes, and no
new features, backported from the master branch, and are
supported as long as at least one downstream distribution
expresses interest in a given branch. These maintenance
branches are considered during CVE analysis. In contrast
to the primary releases which are made once a month, there
is no formal schedule for the maintenance releases, which
are made whenever there is a need to make available key
bugfixes to downstream consumers. The language bindings
and other modules generally do not provide stable branch
releases.
branches are considered during CVE analysis.
</p>
<p>
@@ -512,16 +57,22 @@
<h2><a name="git">GIT source repository</a></h2>
<p>
All modules maintained by the libvirt project have their primary
source available in the <a href="http://libvirt.org/git/">project GIT server</a>.
Each module can be cloned anonymously using:
Libvirt code source is now maintained in a <a href="http://git-scm.com/">git</a>
repository available on <a href="http://libvirt.org/git/">libvirt.org</a>:
</p>
<pre>
git clone git://libvirt.org/[module name].git</pre>
git clone git://libvirt.org/libvirt.git</pre>
<p>
In addition to this primary repository, there are the following read-only git
It can also be browsed at:
</p>
<pre>
<a href="http://libvirt.org/git/?p=libvirt.git;a=summary">http://libvirt.org/git/?p=libvirt.git;a=summary</a></pre>
<p>
In addition to this repository, there are the following read-only git
repositories which mirror the master one. Note that we currently do not
use the full set of features on these mirrors (e.g. pull requests on
GitHub, so please don't use them). All patch review and discussion only
@@ -530,8 +81,58 @@ git clone git://libvirt.org/[module name].git</pre>
</p>
<pre>
<a href="https://github.com/libvirt/">https://github.com/libvirt/</a>
<a href="https://gitlab.com/libvirt/libvirt">https://gitlab.com/libvirt/</a></pre>
<a href="https://github.com/libvirt/libvirt">https://github.com/libvirt/libvirt</a>
<a href="http://repo.or.cz/w/libvirt.git">http://repo.or.cz/w/libvirt.git</a>
<a href="https://gitlab.com/libvirt/libvirt">https://gitlab.com/libvirt/libvirt</a></pre>
<br />
<h1>libvirt Application Development Guide</h1>
<p>
The guide is both a learning tool for developing with libvirt and an
API reference document. It is a work in progress, composed by a
professional author from contributions written by members of the
libvirt team.
</p>
<p>
Contributions to the guide are <b>VERY</b> welcome. If you'd like to get
your name on this and demonstrate your virtualisation prowess, a solid
contribution to the content here will do it. :)
</p>
<h2><a name="appdevpdf">Application Development Guide PDF</a></h2>
<p>
PDF download is available here:
</p>
<ul>
<li><a href="http://libvirt.org/guide/pdf/Application_Development_Guide.pdf">libvirt App Dev Guide</a> (PDF)</li>
</ul>
<h2><a name="appdevgit">Application Development Guide source GIT repository</a></h2>
<p>
The source is also in a git repository:
</p>
<pre>
git clone git://libvirt.org/libvirt-appdev-guide.git</pre>
<p>
Browsable at:
</p>
<pre>
<a href="http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary">http://libvirt.org/git/?p=libvirt-appdev-guide.git;a=summary</a></pre>
<br />
<p>
Once you've have obtained the libvirt source code, you can compile it
using the <a href="compiling.html">instructions here</a>.
</p>
</body>
</html>

View File

@@ -4,11 +4,7 @@
<body>
<h1>Internal drivers</h1>
<ul>
<li><a href="#hypervisor">Hypervisor drivers</a></li>
<li><a href="#storage">Storage drivers</a></li>
<li><a href="drvnodedev.html">Node device driver</a></li>
</ul>
<ul id="toc"></ul>
<p>
The libvirt public API delegates its implementation to one or

View File

@@ -13,20 +13,9 @@ of bhyve are supported.
In order to enable bhyve on your FreeBSD host, you'll need to load the <code>vmm</code>
kernel module. Additionally, <code>if_tap</code> and <code>if_bridge</code> modules
should be loaded for networking support. Also, <span class="since">since 3.2.0</span> the
<code>virt-host-validate(1)</code> supports the bhyve host validation and could be
used like this:
should be loaded for networking support.
</p>
<pre>
$ virt-host-validate bhyve
BHYVE: Checking for vmm module : PASS
BHYVE: Checking for if_tap module : PASS
BHYVE: Checking for if_bridge module : PASS
BHYVE: Checking for nmdm module : PASS
$
</pre>
<p>
Additional information on bhyve could be obtained on <a href="http://bhyve.org/">bhyve.org</a>.
</p>
@@ -155,57 +144,6 @@ Note the addition of &lt;bootloader&gt;.
&lt;/domain&gt;
</pre>
<h3>Example config (Linux UEFI guest, VNC, tablet)</h3>
<p>This is an example to boot into Fedora 25 installation:</p>
<pre>
&lt;domain type='bhyve'&gt;
&lt;name&gt;fedora_uefi_vnc_tablet&lt;/name&gt;
&lt;memory unit='G'&gt;4&lt;/memory&gt;
&lt;vcpu&gt;2&lt;/vcpu&gt;
&lt;os&gt;
&lt;type&gt;hvm&lt;/type&gt;
<b>&lt;loader readonly=&quot;yes&quot; type=&quot;pflash&quot;&gt;/usr/local/share/uefi-firmware/BHYVE_UEFI.fd&lt;/loader&gt;</b>
&lt;/os&gt;
&lt;features&gt;
&lt;apic/&gt;
&lt;acpi/&gt;
&lt;/features&gt;
&lt;clock offset='utc'/&gt;
&lt;on_poweroff&gt;destroy&lt;/on_poweroff&gt;
&lt;on_reboot&gt;restart&lt;/on_reboot&gt;
&lt;on_crash&gt;destroy&lt;/on_crash&gt;
&lt;devices&gt;
&lt;disk type='file' device='cdrom'&gt;
&lt;driver name='file' type='raw'/&gt;
&lt;source file='/path/to/Fedora-Workstation-Live-x86_64-25-1.3.iso'/&gt;
&lt;target dev='hdc' bus='sata'/&gt;
&lt;readonly/&gt;
&lt;/disk&gt;
&lt;disk type='file' device='disk'&gt;
&lt;driver name='file' type='raw'/&gt;
&lt;source file='/path/to/linux_uefi.img'/&gt;
&lt;target dev='hda' bus='sata'/&gt;
&lt;/disk&gt;
&lt;interface type='bridge'&gt;
&lt;model type='virtio'/&gt;
&lt;source bridge=&quot;virbr0&quot;/&gt;
&lt;/interface&gt;
&lt;serial type=&quot;nmdm&quot;&gt;
&lt;source master=&quot;/dev/nmdm0A&quot; slave=&quot;/dev/nmdm0B&quot;/&gt;
&lt;/serial&gt;
<b>&lt;graphics type='vnc' port='5904'&gt;
&lt;listen type='address' address='127.0.0.1'/&gt;
&lt;/graphics&gt;
&lt;controller type='usb' model='nec-xhci'/&gt;
&lt;input type='tablet' bus='usb'/&gt;</b>
&lt;/devices&gt;
&lt;/domain&gt;
</pre>
<p>Please refer to the <a href="#uefi">UEFI</a> section for a more detailed explanation.</p>
<h2><a name="usage">Guest usage / management</a></h2>
<h3><a name="console">Connecting to a guest console</a></h3>
@@ -216,13 +154,13 @@ the following to the domain XML (<span class="since">Since 1.2.4</span>):
</p>
<pre>
...
&lt;devices&gt;
&lt;serial type="nmdm"&gt;
&lt;source master="/dev/nmdm0A" slave="/dev/nmdm0B"/&gt;
&lt;/serial&gt;
&lt;/devices&gt;
...</pre>
...
&lt;devices&gt;
&lt;serial type="nmdm"&gt;
&lt;source master="/dev/nmdm0A" slave="/dev/nmdm0B"/&gt;
&lt;/serial&gt;
&lt;/devices&gt;
...</pre>
<p>Make sure to load the <code>nmdm</code> kernel module if you plan to use that.</p>
@@ -281,12 +219,12 @@ tweak them.</p>
An example of domain XML device entry for that will look like:</p>
<pre>
...
&lt;disk type='volume' device='disk'&gt;
&lt;source pool='zfspool' volume='vol1'/&gt;
&lt;target dev='vdb' bus='virtio'/&gt;
&lt;/disk&gt;
...</pre>
...
&lt;disk type='volume' device='disk'&gt;
&lt;source pool='zfspool' volume='vol1'/&gt;
&lt;target dev='vdb' bus='virtio'/&gt;
&lt;/disk&gt;
...</pre>
<p>Please refer to the <a href="storage.html">Storage documentation</a> for more details on storage
management.</p>
@@ -303,58 +241,15 @@ the first disk in the domain (either <code>cdrom</code>- or
attempt to boot from the first partition in the disk image.</p>
<pre>
...
&lt;bootloader&gt;/usr/local/sbin/grub-bhyve&lt;/bootloader&gt;
&lt;bootloader_args&gt;...&lt;/bootloader_args&gt;
...
...
&lt;bootloader&gt;/usr/local/sbin/grub-bhyve&lt;/bootloader&gt;
&lt;bootloader_args&gt;...&lt;/bootloader_args&gt;
...
</pre>
<p>Caveat: <code>bootloader_args</code> does not support any quoting.
Filenames, etc, must not have spaces or they will be tokenized incorrectly.</p>
<h3><a name="uefi">Using UEFI bootrom, VNC, and USB tablet</a></h3>
<p><span class="since">Since 3.2.0</span>, in addition to <a href="#grubbhyve">grub-bhyve</a>,
non-FreeBSD guests could be also booted using an UEFI boot ROM, provided both guest OS and
installed <code>bhyve(1)</code> version support UEFI. To use that, <code>loader</code>
should be specified in the <code>os</code> section:</p>
<pre>
&lt;domain type='bhyve'&gt;
...
&lt;os&gt;
&lt;type&gt;hvm&lt;/type&gt;
&lt;loader readonly="yes" type="pflash"&gt;/usr/local/share/uefi-firmware/BHYVE_UEFI.fd&lt;/loader&gt;
&lt;/os&gt;
...
</pre>
<p>This uses the UEFI firmware provided by
the <a href="https://www.freshports.org/sysutils/bhyve-firmware/">sysutils/bhyve-firmware</a>
FreeBSD port.</p>
<p>VNC and the tablet input device could be configured this way:</p>
<pre>
&lt;domain type='bhyve'&gt;
&lt;devices&gt;
...
&lt;graphics type='vnc' port='5904'&gt;
&lt;listen type='address' address='127.0.0.1'/&gt;
&lt;/graphics&gt;
&lt;controller type='usb' model='nec-xhci'/&gt;
&lt;input type='tablet' bus='usb'/&gt;
&lt;/devices&gt;
...
&lt;/domain&gt;
</pre>
<p>This way, VNC will be accessible on <code>127.0.0.1:5904</code>.</p>
<p>Please note that the tablet device requires to have an USB controller
of the <code>nec-xhci</code> model. Currently, only a single controller of this
type and a single tablet are supported per domain.</p>
<h3><a name="clockconfig">Clock configuration</a></h3>
<p>Originally bhyve supported only localtime for RTC. Support for UTC time was introduced in
@@ -381,21 +276,6 @@ you'll need to explicitly specify 'localtime' in this case:</p>
&lt;clock offset='localtime'/&gt;
...
&lt;/domain&gt;
</pre>
<h3><a name="e1000">e1000 NIC</a></h3>
<p>As of <a href="https://svnweb.freebsd.org/changeset/base/302504">r302504</a> bhyve
supports Intel e1000 network adapter emulation. It's supported in libvirt
<span class="since">since 3.1.0</span> and could be used as follows:</p>
<pre>
...
&lt;interface type='bridge'&gt;
&lt;source bridge='virbr0'/&gt;
&lt;model type='<b>e1000</b>'/&gt;
&lt;/interface&gt;
...
</pre>
</body>

View File

@@ -467,14 +467,14 @@ ethernet0.checkMACAddress = "false"
Here a domain XML snippet:
</p>
<pre>
...
&lt;disk type='file' device='disk'&gt;
&lt;source file='[local-storage] Fedora11/Fedora11.vmdk'/&gt;
&lt;target dev='sda' bus='scsi'/&gt;
&lt;address type='drive' controller='0' bus='0' unit='0'/&gt;
&lt;/disk&gt;
&lt;controller type='scsi' index='0' model='<strong>lsilogic</strong>'/&gt;
...
...
&lt;disk type='file' device='disk'&gt;
&lt;source file='[local-storage] Fedora11/Fedora11.vmdk'/&gt;
&lt;target dev='sda' bus='scsi'/&gt;
&lt;address type='drive' controller='0' bus='0' unit='0'/&gt;
&lt;/disk&gt;
&lt;controller type='scsi' index='0' model='<strong>lsilogic</strong>'/&gt;
...
</pre>
<p>
The controller element is supported <span class="since">since 0.8.2</span>.
@@ -482,13 +482,13 @@ ethernet0.checkMACAddress = "false"
specify the SCSI controller model. This attribute usage is deprecated now.
</p>
<pre>
...
&lt;disk type='file' device='disk'&gt;
&lt;driver name='<strong>lsilogic</strong>'/&gt;
&lt;source file='[local-storage] Fedora11/Fedora11.vmdk'/&gt;
&lt;target dev='sda' bus='scsi'/&gt;
&lt;/disk&gt;
...
...
&lt;disk type='file' device='disk'&gt;
&lt;driver name='<strong>lsilogic</strong>'/&gt;
&lt;source file='[local-storage] Fedora11/Fedora11.vmdk'/&gt;
&lt;target dev='sda' bus='scsi'/&gt;
&lt;/disk&gt;
...
</pre>
@@ -513,13 +513,13 @@ ethernet0.checkMACAddress = "false"
Here a domain XML snippet:
</p>
<pre>
...
&lt;interface type='bridge'&gt;
&lt;mac address='00:50:56:25:48:c7'/&gt;
&lt;source bridge='VM Network'/&gt;
&lt;model type='<strong>e1000</strong>'/&gt;
&lt;/interface&gt;
...
...
&lt;interface type='bridge'&gt;
&lt;mac address='00:50:56:25:48:c7'/&gt;
&lt;source bridge='VM Network'/&gt;
&lt;model type='<strong>e1000</strong>'/&gt;
&lt;/interface&gt;
...
</pre>

View File

@@ -5,7 +5,7 @@
<h1>Microsoft Hyper-V hypervisor driver</h1>
<ul id="toc"></ul>
<p>
The libvirt Microsoft Hyper-V driver can manage Hyper-V 2008 R2 and newer.
The libvirt Microsoft Hyper-V driver can manage Hyper-V 2008 R2.
</p>

View File

@@ -62,12 +62,12 @@ would use the following XML
</p>
<pre>
&lt;os&gt;
&lt;type arch='x86_64'&gt;exe&lt;/type&gt;
&lt;init&gt;/bin/systemd&lt;/init&gt;
&lt;initarg&gt;--unit&lt;/initarg&gt;
&lt;initarg&gt;emergency.service&lt;/initarg&gt;
&lt;/os&gt;
&lt;os&gt;
&lt;type arch='x86_64'&gt;exe&lt;/type&gt;
&lt;init&gt;/bin/systemd&lt;/init&gt;
&lt;initarg&gt;--unit&lt;/initarg&gt;
&lt;initarg&gt;emergency.service&lt;/initarg&gt;
&lt;/os&gt;
</pre>
<h3><a name="envvars">Environment variables</a></h3>
@@ -80,15 +80,15 @@ to be provided by all container technologies on Linux.
</p>
<dl>
<dt><code>container</code></dt>
<dt>container</dt>
<dd>The fixed string <code>libvirt-lxc</code> to identify libvirt as the creator</dd>
<dt><code>container_uuid</code></dt>
<dt>container_uuid</dt>
<dd>The UUID assigned to the container by libvirt</dd>
<dt><code>PATH</code></dt>
<dt>PATH</dt>
<dd>The fixed string <code>/bin:/usr/bin</code></dd>
<dt><code>TERM</code></dt>
<dt>TERM</dt>
<dd>The fixed string <code>linux</code></dd>
<dt><code>HOME</code></dt>
<dt>HOME</dt>
<dd>The fixed string <code>/</code></dd>
</dl>
@@ -98,11 +98,11 @@ environment variables are also provided
</p>
<dl>
<dt><code>LIBVIRT_LXC_NAME</code></dt>
<dt>LIBVIRT_LXC_NAME</dt>
<dd>The name assigned to the container by libvirt</dd>
<dt><code>LIBVIRT_LXC_UUID</code></dt>
<dt>LIBVIRT_LXC_UUID</dt>
<dd>The UUID assigned to the container by libvirt</dd>
<dt><code>LIBVIRT_LXC_CMDLINE</code></dt>
<dt>LIBVIRT_LXC_CMDLINE</dt>
<dd>The unparsed command line arguments specified in the container configuration.
Use of this is discouraged, in favour of passing arguments directly to the
container init process via the <code>initarg</code> config element.</dd>
@@ -611,10 +611,6 @@ ignored.
&lt;/domain&gt;
</pre>
<p>
The use of namespace passthrough requires libvirt >= 1.2.19
</p>
<h2><a name="usage">Container usage / management</a></h2>
<p>

View File

@@ -1,189 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Host device management</h1>
<p>
Libvirt provides management of both physical and virtual host devices
(historically also referred to as node devices) like USB, PCI, SCSI, and
network devices. This also includes various virtualization capabilities
which the aforementioned devices provide for utilization, for example
SR-IOV, NPIV, DRM, etc.
</p>
<p>
The node device driver provides means to list and show details about host
devices (<code>virsh nodedev-list</code>,
<code>virsh nodedev-dumpxml</code>), which are generic and can be used
with all devices. It also provides means to create and destroy devices
(<code>virsh nodedev-create</code>, <code>virsh nodedev-destroy</code>)
which are meant to be used to create virtual devices, currently only
supported by NPIV
(<a href="http://wiki.libvirt.org/page/NPIV_in_libvirt">more info about NPIV)</a>).
Devices on the host system are arranged in a tree-like hierarchy, with
the root node being called <code>computer</code>. The node device driver
supports two backends to manage the devices, HAL and udev, with the former
being deprecated in favour of the latter.
</p>
<p>
The generic format of a host device XML can be seen below.
To identify a device both within the host and the device tree hierarchy,
the following elements are used:
</p>
<dl>
<dt><code>name</code></dt>
<dd>
The device's name will be generated by libvirt using the subsystem,
like pci and the device's sysfs basename.
</dd>
<dt><code>path</code></dt>
<dd>
Fully qualified sysfs path to the device.
</dd>
<dt><code>parent</code></dt>
<dd>
This element identifies the parent node in the device hierarchy. The
value of the element will correspond with the device parent's
<code>name</code> element or <code>computer</code> if the device does
not have any parent.
</dd>
<dt><code>driver</code></dt>
<dd>
This elements reports the driver in use for this device. The presence
of this element in the output XML depends on whether the underlying
device manager (most likely udev) exposes information about the
driver.
</dd>
<dt><code>capability</code></dt>
<dd>
Describes the device in terms of feature support. The element has one
mandatory attribute <code>type</code> the value of which determines
the type of the device. Currently recognized values for the attribute
are:
<code>system</code>,
<code>pci</code>,
<code>usb</code>,
<code>usb_device</code>,
<code>net</code>,
<code>scsi</code>,
<code>scsi_host</code> (<span class="since">Since 0.4.7</span>),
<code>fc_host</code>,
<code>vports</code>,
<code>scsi_target</code> (<span class="since">Since 0.7.3</span>),
<code>storage</code> (<span class="since">Since 1.0.4</span>),
<code>scsi_generic</code> (<span class="since">Since 1.0.7</span>),
<code>drm</code> (<span class="since">Since 3.1.0</span>), and
This element can be nested in which case it further specifies a
device's capability. Refer to specific device types to see more values
for the <code>type</code> attribute which are exclusive.
</dd>
</dl>
<h2>Basic structure of a node device</h2>
<pre>
&lt;device&gt;
&lt;name&gt;pci_0000_00_17_0&lt;/name&gt;
&lt;path&gt;/sys/devices/pci0000:00/0000:00:17.0&lt;/path&gt;
&lt;parent&gt;computer&lt;/parent&gt;
&lt;driver&gt;
&lt;name&gt;ahci&lt;/name&gt;
&lt;/driver&gt;
&lt;capability type='pci'&gt;
...
&lt;/capability&gt;
&lt;/device&gt;</pre>
<ul id="toc"/>
<h2><a name="PCI">PCI host devices</a></h2>
<dl>
<dt><code>capability</code></dt>
<dd>
When used as top level element, the supported values for the
<code>type</code> attribute are <code>pci</code> and
<code>phys_function</code> (see <a href="#SRIOVCap">SR-IOV below</a>).
</dd>
</dl>
<pre>
&lt;device&gt;
&lt;name&gt;pci_0000_04_00_1&lt;/name&gt;
&lt;path&gt;/sys/devices/pci0000:00/0000:00:06.0/0000:04:00.1&lt;/path&gt;
&lt;parent&gt;pci_0000_00_06_0&lt;/parent&gt;
&lt;driver&gt;
&lt;name&gt;igb&lt;/name&gt;
&lt;/driver&gt;
&lt;capability type='pci'&gt;
&lt;domain&gt;0&lt;/domain&gt;
&lt;bus&gt;4&lt;/bus&gt;
&lt;slot&gt;0&lt;/slot&gt;
&lt;function&gt;1&lt;/function&gt;
&lt;product id='0x10c9'&gt;82576 Gigabit Network Connection&lt;/product&gt;
&lt;vendor id='0x8086'&gt;Intel Corporation&lt;/vendor&gt;
&lt;iommuGroup number='15'&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x00' function='0x1'/&gt;
&lt;/iommuGroup&gt;
&lt;numa node='0'/&gt;
&lt;pci-express&gt;
&lt;link validity='cap' port='1' speed='2.5' width='2'/&gt;
&lt;link validity='sta' speed='2.5' width='2'/&gt;
&lt;/pci-express&gt;
&lt;/capability&gt;
&lt;/device&gt;</pre>
<p>
The XML format for a PCI device stays the same for any further
capabilities it supports, a single nested <code>&lt;capability&gt;</code>
element will be included for each capability the device supports.
</p>
<h3><a name="SRIOVCap">SR-IOV capability</a></h3>
<p>
Single root input/output virtualization (SR-IOV) allows sharing of the
PCIe resources by multiple virtual environments. That is achieved by
slicing up a single full-featured physical resource called physical
function (PF) into multiple devices called virtual functions (VFs) sharing
their configuration with the underlying PF. Despite the SR-IOV
specification, the amount of VFs that can be created on a PF varies among
manufacturers.
</p>
<p>
Suppose the NIC <a href="#PCI">above</a> was also SR-IOV capable, it would
also include a nested
<code>&lt;capability&gt;</code> element enumerating all virtual
functions available on the physical device (physical port) like in the
example below.
</p>
<pre>
&lt;capability type='pci'&gt;
...
&lt;capability type='virt_functions' maxCount='7'&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x10' function='0x1'/&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x10' function='0x3'/&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x10' function='0x5'/&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x10' function='0x7'/&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x11' function='0x1'/&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x11' function='0x3'/&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x11' function='0x5'/&gt;
&lt;/capability&gt;
...
&lt;/capability&gt;</pre>
<p>
A SR-IOV child device on the other hand, would then report its top level
capability type as a <code>phys_function</code> instead:
</p>
<pre>
&lt;device&gt;
...
&lt;capability type='phys_function'&gt;
&lt;address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/&gt;
&lt;/capability&gt;
...
&lt;device&gt;</pre>
</body>
</html>

BIN
docs/et.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -1,90 +0,0 @@
## License
Copyright (C) 2015 Red Hat, Inc.,
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
#### SIL OPEN FONT LICENSE
Version 1.1 - 26 February 2007
---
#### PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development
of collaborative font projects, to support the font creation efforts of
academic and linguistic communities, and to provide a free and open framework
in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The fonts,
including any derivative works, can be bundled, embedded, redistributed and/or
sold with any software provided that any reserved names are not used by
derivative works. The fonts and derivatives, however, cannot be released under
any other type of license. The requirement for fonts to remain under this
license does not apply to any document created using the fonts or their
derivatives.
#### DEFINITIONS
“Font Software” refers to the set of files released by the Copyright Holder(s)
under this license and clearly marked as such. This may include source files,
build scripts and documentation.
“Reserved Font Name” refers to any names specified as such after the copyright
statement(s).
“Original Version” refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
“Modified Version” refers to any derivative made by adding to, deleting, or
substituting—in part or in whole—any of the components of the Original Version,
by changing formats or by porting the Font Software to a new environment.
“Author” refers to any designer, engineer, programmer, technical writer or
other person who contributed to the Font Software.
#### PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of
the Font Software, to use, study, copy, merge, embed, modify, redistribute, and
sell modified and unmodified copies of the Font Software, subject to the
following conditions:
1) Neither the Font Software nor any of its individual components, in Original
or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy contains
the above copyright notice and this license. These can be included either as
stand-alone text files, human-readable headers or in the appropriate machine-
readable metadata fields within text or binary files as long as those fields
can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s)
unless explicit written permission is granted by the corresponding Copyright
Holder. This restriction only applies to the primary font name as presented to
the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software
shall not be used to promote, endorse or advertise any Modified Version, except
to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s)
or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be
distributed entirely under this license, and must not be distributed under any
other license. The requirement for fonts to remain under this license does not
apply to any document created using the Font Software.
#### TERMINATION
This license becomes null and void if any of the above conditions are not met.
#### DISCLAIMER
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL,
INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE
THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,62 +0,0 @@
@font-face {
font-family: 'LibvirtOverpass';
src: url('overpass-regular.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'LibvirtOverpass';
src: url('overpass-italic.woff') format('woff');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'LibvirtOverpass';
src: url('overpass-bold.woff') format('woff');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'LibvirtOverpass';
src: url('overpass-bold-italic.woff') format('woff');
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: 'LibvirtOverpassLight';
src: url('overpass-light.woff') format('woff');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'LibvirtOverpassLight';
src: url('overpass-light-italic.woff') format('woff');
font-weight: 300;
font-style: italic;
}
@font-face {
font-family: 'LibvirtOverpassMono';
src: url('overpass-mono-regular.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'LibvirtOverpassMono';
src: url('overpass-mono-bold.woff') format('woff');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'LibvirtOverpassMonoLight';
src: url('overpass-mono-light.woff') format('woff');
font-weight: 300;
font-style: normal;
}

BIN
docs/footer_corner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
docs/footer_pattern.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

View File

@@ -2,43 +2,9 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>XML Format</h1>
<h1 >XML Format</h1>
<p>
Objects in the libvirt API are configured using XML documents to allow
for ease of extension in future releases. Each XML document has an
associated Relax-NG schema that can be used to validate documents
prior to usage.
</p>
<ul>
<li><a href="formatdomain.html" shape="rect">Domains</a></li>
<li><a href="formatnetwork.html" shape="rect">Networks</a></li>
<li><a href="formatnwfilter.html" shape="rect">Network filtering</a></li>
<li><a href="formatstorage.html" shape="rect">Storage</a></li>
<li><a href="formatstorageencryption.html" shape="rect">Storage encryption</a></li>
<li><a href="formatcaps.html" shape="rect">Capabilities</a></li>
<li><a href="formatdomaincaps.html" shape="rect">Domain capabilities</a></li>
<li><a href="formatnode.html" shape="rect">Node devices</a></li>
<li><a href="formatsecret.html" shape="rect">Secrets</a></li>
<li><a href="formatsnapshot.html" shape="rect">Snapshots</a></li>
</ul>
<h2>Command line validation</h2>
<p>
The <code>virt-xml-validate</code> tool provides a simple command line
for validating XML documents prior to giving them to libvirt. It uses
the locally instaled RNG schema documents. It will auto-detect which
schema to use for validation based on the name of the top level element
in the input document. Thus it merely requires the XML document filename
to be passed on the command line
</p>
<pre>
$ virt-xml-validate /path/to/XML/file</pre>
</body>
</html>

View File

@@ -13,7 +13,7 @@
interface has been added in 0.2.1 allowing to list the set of supported
virtualization capabilities on the host:</p>
<pre>char * virConnectGetCapabilities (virConnectPtr conn);</pre>
<pre> char * virConnectGetCapabilities (virConnectPtr conn);</pre>
<p>The value returned is an XML document listing the virtualization
capabilities of the host and virtualization engine to which
@@ -21,7 +21,7 @@
command line tool command '<code>capabilities</code>', it dumps the XML
associated to the current connection. </p>
<p>As can be seen in the <a href="#elementExamples">example</a>, the
<p>As can be seen seen in the <a href="#elementExamples">example</a>, the
capabilities XML consists of the <code>capabilities</code> element which
have exactly one <code>host</code> child element to report information on
host capabilities, and zero or more <code>guest</code> element to express
@@ -73,19 +73,19 @@
<dd>This expresses what kind of operating system the hypervisor
is able to run. Possible values are:
<dl>
<dt><code>xen</code></dt>
<dt>xen</dt>
<dd>for XEN</dd>
<dt><code>linux</code></dt>
<dt>linux</dt>
<dd>legacy alias for <code>xen</code></dd>
<dt><code>hvm</code></dt>
<dt>hvm</dt>
<dd>Unmodified operating system</dd>
<dt><code>exe</code></dt>
<dt>exe</dt>
<dd>Container based virtualization</dd>
<dt><code>uml</code></dt>
<dt>uml</dt>
<dd>User Mode Linux</dd>
</dl>
</dd>
@@ -97,37 +97,37 @@
<dd>This optional element encases possible features that can be used
with a guest of described type. Possible subelements are:
<dl>
<dt><code>pae</code></dt><dd>If present, 32-bit guests can use PAE
<dt>pae</dt><dd>If present, 32-bit guests can use PAE
address space extensions, <span class="since">since
0.4.1</span></dd>
<dt><code>nonpae</code></dt><dd>If present, 32-bit guests can be run
<dt>nonpae</dt><dd>If present, 32-bit guests can be run
without requiring PAE, <span class="since">since
0.4.1</span></dd>
<dt><code>ia64_be</code></dt><dd>If present, IA64 guests can be run in
<dt>ia64_be</dt><dd>If present, IA64 guests can be run in
big-endian mode, <span class="since">since 0.4.1</span></dd>
<dt><code>acpi</code></dt><dd>If this element is present,
<dt>acpi</dt><dd>If this element is present,
the <code>default</code> attribute describes whether the
hypervisor exposes ACPI to the guest by default, and
the <code>toggle</code> attribute describes whether the
user can override this
default. <span class="since">Since 0.4.1</span></dd>
<dt><code>apic</code></dt><dd>If this element is present,
<dt>apic</dt><dd>If this element is present,
the <code>default</code> attribute describes whether the
hypervisor exposes APIC to the guest by default, and
the <code>toggle</code> attribute describes whether the
user can override this
default. <span class="since">Since 0.4.1</span></dd>
<dt><code>cpuselection</code></dt><dd>If this element is present, the
<dt>cpuselection</dt><dd>If this element is present, the
hypervisor supports the <code>&lt;cpu&gt;</code> element
within a domain definition for fine-grained control over
the CPU presented to the
guest. <span class="since">Since 0.7.5</span></dd>
<dt><code>deviceboot</code></dt><dd>If this element is present,
<dt>deviceboot</dt><dd>If this element is present,
the <code>&lt;boot order='...'/&gt;</code> element can
be used inside devices, rather than the older boot
specification by category. <span class="since">Since
0.8.8</span></dd>
<dt><code>disksnapshot</code></dt><dd>If this element is present,
<dt>disksnapshot</dt><dd>If this element is present,
the <code>default</code> attribute describes whether
external disk snapshots are supported. If absent,
external snapshots may still be supported, but it

File diff suppressed because it is too large Load Diff

View File

@@ -61,19 +61,18 @@
&lt;/domainCapabilities&gt;
</pre>
<dl>
<dt><code>path</code></dt>
<dt>path</dt>
<dd>The full path to the emulator binary.</dd>
<dt><code>domain</code></dt>
<dt>domain</dt>
<dd>Describes the <a href="formatdomain.html#elements">virtualization
type</a> (or so called domain type).</dd>
<dt><code>machine</code></dt>
<dt>machine</dt>
<dd>The domain's <a href="formatdomain.html#elementsOSBIOS">machine
type</a>. Since not every hypervisor has a sense of machine types
this element might be omitted in such drivers.</dd>
type</a>.</dd>
<dt><code>arch</code></dt>
<dt>arch</dt>
<dd>The domain's <a href="formatdomain.html#elementsOSBIOS">
architecture</a>.</dd>
@@ -93,7 +92,7 @@
</pre>
<dl>
<dt><code>vcpu</code></dt>
<dt>vcpu</dt>
<dd>The maximum number of supported virtual CPUs</dd>
</dl>
@@ -127,91 +126,26 @@
<p>For the <code>loader</code> element, the following can occur:</p>
<dl>
<dt><code>value</code></dt>
<dt>value</dt>
<dd>List of known loader paths. Currently this is only used
to advertise known locations of OVMF binaries for qemu. Binaries
will only be listed if they actually exist on disk.</dd>
<dt><code>type</code></dt>
<dt>type</dt>
<dd>Whether loader is a typical BIOS (<code>rom</code>) or
an UEFI binary (<code>pflash</code>). This refers to
<code>type</code> attribute of the &lt;loader/&gt;
element.</dd>
<dt><code>readonly</code></dt>
<dt>readonly</dt>
<dd>Options for the <code>readonly</code> attribute of the
&lt;loader/&gt; element.</dd>
</dl>
<h3><a name="elementsCPU">CPU configuration</a></h3>
<p>
The <code>cpu</code> element exposes options usable for configuring
<a href="formatdomain.html#elementsCPU">guest CPUs</a>.
</p>
<pre>
&lt;domainCapabilities&gt;
...
&lt;cpu&gt;
&lt;mode name='host-passthrough' supported='yes'/&gt;
&lt;mode name='host-model' supported='yes'&gt;
&lt;model fallback='allow'&gt;Broadwell&lt;/model&gt;
&lt;vendor&gt;Intel&lt;/vendor&gt;
&lt;feature policy='disable' name='aes'/&gt;
&lt;feature policy='require' name='vmx'/&gt;
&lt;/mode&gt;
&lt;mode name='custom' supported='yes'&gt;
&lt;model usable='no'&gt;Broadwell&lt;/model&gt;
&lt;model usable='yes'&gt;Broadwell-noTSX&lt;/model&gt;
&lt;model usable='no'&gt;Haswell&lt;/model&gt;
...
&lt;/mode&gt;
&lt;/cpu&gt;
...
&lt;domainCapabilities&gt;
</pre>
<p>
Each CPU mode understood by libvirt is described with a
<code>mode</code> element which tells whether the particular mode
is supported and provides (when applicable) more details about it:
</p>
<dl>
<dt><code>host-passthrough</code></dt>
<dd>No mode specific details are provided.</dd>
<dt><code>host-model</code></dt>
<dd>
If <code>host-model</code> is supported by the hypervisor, the
<code>mode</code> describes the guest CPU which will be used when
starting a domain with <code>host-model</code> CPU. The hypervisor
specifics (such as unsupported CPU models or features, machine type,
etc.) may be accounted for in this guest CPU specification and thus
the CPU can be different from the one shown in host capabilities XML.
This is indicated by the <code>fallback</code> attribute of the
<code>model</code> sub element: <code>allow</code> means not all
specifics were accounted for and thus the CPU a guest will see may
be different; <code>forbid</code> indicates that the CPU a guest will
see should match this CPU definition.
</dd>
<dt><code>custom</code></dt>
<dd>
The <code>mode</code> element contains a list of supported CPU
models, each described by a dedicated <code>model</code> element.
The <code>usable</code> attribute specifies whether the model can
be used on the host. A special value <code>unknown</code> indicates
libvirt does not have enough information to provide the usability
data.
</dd>
</dl>
<h3><a name="elementsDevices">Devices</a></h3>
<p>
Another set of XML elements describe the supported devices and their
The final set of XML elements describe the supported devices and their
capabilities. All devices occur as children of the main
<code>devices</code> element.
</p>
@@ -241,7 +175,7 @@
<code>floppy</code>, or <code>lun</code>.</p>
<h4><a name="elementsDisks">Hard drives, floppy disks, CDROMs</a></h4>
<p>Disk capabilities are exposed under the <code>disk</code> element. For
<p>Disk capabilities are exposed under <code>disk</code> element. For
instance:</p>
<pre>
@@ -273,72 +207,15 @@
</pre>
<dl>
<dt><code>diskDevice</code></dt>
<dt>diskDevice</dt>
<dd>Options for the <code>device</code> attribute of the &lt;disk/&gt;
element.</dd>
<dt><code>bus</code></dt>
<dt>bus</dt>
<dd>Options for the <code>bus</code> attribute of the &lt;target/&gt;
element for a &lt;disk/&gt;.</dd>
</dl>
<h4><a name="elementsGraphics">Graphical framebuffers</a></h4>
<p>Graphics device capabilities are exposed under the
<code>graphics</code> element. For instance:</p>
<pre>
&lt;domainCapabilities&gt;
...
&lt;devices&gt;
&lt;graphics supported='yes'&gt;
&lt;enum name='type'&gt;
&lt;value&gt;sdl&lt;/value&gt;
&lt;value&gt;vnc&lt;/value&gt;
&lt;value&gt;spice&lt;/value&gt;
&lt;/enum&gt;
&lt;/graphics&gt;
...
&lt;/devices&gt;
&lt;/domainCapabilities&gt;
</pre>
<dl>
<dt><code>type</code></dt>
<dd>Options for the <code>type</code> attribute of the &lt;graphics/&gt;
element.</dd>
</dl>
<h4><a name="elementsVideo">Video device</a></h4>
<p>Video device capabilities are exposed under the
<code>video</code> element. For instance:</p>
<pre>
&lt;domainCapabilities&gt;
...
&lt;devices&gt;
&lt;video supported='yes'&gt;
&lt;enum name='modelType'&gt;
&lt;value&gt;vga&lt;/value&gt;
&lt;value&gt;cirrus&lt;/value&gt;
&lt;value&gt;vmvga&lt;/value&gt;
&lt;value&gt;qxl&lt;/value&gt;
&lt;value&gt;virtio&lt;/value&gt;
&lt;/enum&gt;
&lt;/video&gt;
...
&lt;/devices&gt;
&lt;/domainCapabilities&gt;
</pre>
<dl>
<dt><code>modelType</code></dt>
<dd>Options for the <code>type</code> attribute of the
&lt;video&gt;&lt;model&gt; element.</dd>
</dl>
<h4><a name="elementsHostDev">Host device assignment</a></h4>
<p>Some host devices can be passed through to a guest (e.g. USB, PCI and
SCSI). Well, only if the following is enabled:</p>
@@ -380,66 +257,25 @@
</pre>
<dl>
<dt><code>mode</code></dt>
<dt>mode</dt>
<dd>Options for the <code>mode</code> attribute of the &lt;hostdev/&gt;
element.</dd>
<dt><code>startupPolicy</code></dt>
<dt>startupPolicy</dt>
<dd>Options for the <code>startupPolicy</code> attribute of the
&lt;hostdev/&gt; element.</dd>
<dt><code>subsysType</code></dt>
<dt>subsysType</dt>
<dd>Options for the <code>type</code> attribute of the &lt;hostdev/&gt;
element in case of <code>mode="subsystem"</code>.</dd>
<dt><code>capsType</code></dt>
<dt>capsType</dt>
<dd>Options for the <code>type</code> attribute of the &lt;hostdev/&gt;
element in case of <code>mode="capabilities"</code>.</dd>
<dt><code>pciBackend</code></dt>
<dt>pciBackend</dt>
<dd>Options for the <code>name</code> attribute of the &lt;driver/&gt;
element.</dd>
</dl>
<h3><a name="elementsFeatures">Features</a></h3>
<p>One more set of XML elements describe the supported features and
their capabilities. All features occur as children of the main
<code>features</code> element.</p>
<pre>
&lt;domainCapabilities&gt;
...
&lt;features&gt;
&lt;gic supported='yes'&gt;
&lt;enum name='version'&gt;
&lt;value&gt;2&lt;/value&gt;
&lt;value&gt;3&lt;/value&gt;
&lt;/enum&gt;
&lt;/gic&gt;
&lt;/features&gt;
&lt;/domainCapabilities&gt;
</pre>
<p>Reported capabilities are expressed as an enumerated list of
possible values for each of the elements or attributes. For example, the
<code>gic</code> element has an attribute <code>version</code> which can
support the values <code>2</code> or <code>3</code>.</p>
<p>For information about the purpose of each feature, see the
<a href="formatdomain.html#elementsFeatures">relevant section</a> in
the domain XML documentation.
</p>
<h4><a name="elementsGIC">GIC capabilities</a></h4>
<p>GIC capabilities are exposed under the <code>gic</code> element.</p>
<dl>
<dt><code>version</code></dt>
<dd>Options for the <code>version</code> attribute of the
<code>gic</code> element.</dd>
</dl>
</body>
</html>

View File

@@ -35,14 +35,10 @@
</p>
<pre>
&lt;network ipv6='yes' trustGuestRxFilters='no'&gt;
&lt;name&gt;default&lt;/name&gt;
&lt;uuid&gt;3e3fce45-4f53-4fa7-bb32-11f34168b82b&lt;/uuid&gt;
&lt;metadata&gt;
&lt;app1:foo xmlns:app1="http://app1.org/app1/"&gt;..&lt;/app1:foo&gt;
&lt;app2:bar xmlns:app2="http://app1.org/app2/"&gt;..&lt;/app2:bar&gt;
&lt;/metadata&gt;
...</pre>
&lt;network ipv6='yes' trustGuestRxFilters='no'&gt;
&lt;name&gt;default&lt;/name&gt;
&lt;uuid&gt;3e3fce45-4f53-4fa7-bb32-11f34168b82b&lt;/uuid&gt;
...</pre>
<dl>
<dt><code>name</code></dt>
@@ -58,25 +54,18 @@
The format must be RFC 4122 compliant, eg <code>3e3fce45-4f53-4fa7-bb32-11f34168b82b</code>.
If omitted when defining/creating a new network, a random
UUID is generated. <span class="since">Since 0.3.0</span></dd>
<dd>The <code>metadata</code> node can be used by applications to
store custom metadata in the form of XML nodes/trees. Applications
must use custom namespaces on their XML nodes/trees, with only
one top-level element per namespace (if the application needs
structure, they should have sub-elements to their namespace
element). <span class="since">Since 2.1.0</span></dd>
<dt><code>ipv6</code></dt>
<dd>When set to <code>yes</code>, the optional parameter
<code>ipv6</code> enables
<dt><code>ipv6='yes'</code></dt>
<dd>The new, optional parameter <code>ipv6='yes'</code> enables
a network definition with no IPv6 gateway addresses specified
to have guest-to-guest communications. For further information,
see the example below for the example with no gateway addresses.
<span class="since">Since 1.0.1</span></dd>
<dt><code>trustGuestRxFilters</code></dt>
<dt><code>trustGuestRxFilters='yes'</code></dt>
<dd>The optional parameter <code>trustGuestRxFilters</code> can
be used to set that attribute of the same name for each domain
interface connected to this network (<span class="since">since
1.2.10</span>). See
the <a href="formatdomain.html#elementsNICS">Network
the <a href="formatdomain.html#elementSNICS">Network
interfaces</a> section of the domain XML documentation for
more details. Note that an explicit setting of this attribute
in a portgroup or the individual domain interface will
@@ -91,12 +80,11 @@
</p>
<pre>
...
&lt;bridge name="virbr0" stp="on" delay="5" macTableManager="libvirt"/&gt;
&lt;mtu size="9000"/&gt;
&lt;domain name="example.com" localOnly="no"/&gt;
&lt;forward mode="nat" dev="eth0"/&gt;
...</pre>
...
&lt;bridge name="virbr0" stp="on" delay="5" macTableManager="libvirt"/&gt;
&lt;domain name="example.com" localOnly="no"/&gt;
&lt;forward mode="nat" dev="eth0"/&gt;
...</pre>
<dl>
<dt><code>bridge</code></dt>
@@ -152,25 +140,9 @@
<span class="since">Since 1.2.11, requires kernel 3.17 or
newer</span>
</p>
</dd>
<dt><code>mtu</code></dt>
<dd>
The <code>size</code> attribute of the <code>mtu></code>
element specifies the Maximum Transmission Unit (MTU) for the
network. <span class="since">Since 3.1.0</span>. In the case
of a libvirt-managed network (one with forward mode
of <code>nat</code>, <code>route</code>, <code>open</code>, or
no <code>forward</code> element (i.e. an isolated network),
this will be the MTU assigned to the bridge device when
libvirt creates it, and thereafter also assigned to all tap
devices created to connect guest interfaces. Network types not
specifically mentioned here don't support having an MTU set in
the libvirt network config. If mtu size is unspecified, the
default setting for the type of device being used is assumed
(usually 1500).
</dd>
</dd>
<dt><code>domain</code></dt>
<dd>
The <code>name</code> attribute on the <code>domain</code>
@@ -277,28 +249,6 @@
<span class="since">Since 0.4.2</span>
</dd>
<dt><code>open</code></dt>
<dd>
As with mode='route', guest network traffic will be
forwarded to the physical network via the host's IP
routing stack, but there will be no firewall rules added
to either enable or prevent any of this traffic. When
forward='open' is set, the <code>dev</code> attribute
cannot be set (because the forward dev is enforced with
firewall rules, and the purpose of forward='open' is to
have a forwarding mode where libvirt doesn't add any
firewall rules). This mode presumes that the local LAN
router has suitable routing table entries to return
traffic to this host, and that some other management
system has been used to put in place any necessary
firewall rules. Although no firewall rules will be added
for the network, it is of course still possible to add
restrictions for specific guests using
<a href="formatnwfilter.html">nwfilter rules</a> on the
guests' interfaces.)
<span class="since">Since 2.2.0</span>
</dd>
<dt><code>bridge</code></dt>
<dd>
This network describes either 1) an existing host bridge
@@ -657,47 +607,31 @@
</pre>
<p>
If (and only if) the network connection used by the guest
supports VLAN tagging transparent to the guest, an
optional <code>&lt;vlan&gt;</code> element can specify one or
more VLAN tags to apply to the guest's network
traffic <span class="since">Since 0.10.0</span>. Network
connections that support guest-transparent VLAN tagging include
1) type='bridge' interfaces connected to an Open vSwitch bridge
<span class="since">Since 0.10.0</span>, 2) SRIOV Virtual
Functions (VF) used via type='hostdev' (direct device
assignment) <span class="since">Since 0.10.0</span>, and 3)
SRIOV VFs used via type='direct' with mode='passthrough'
(macvtap "passthru" mode) <span class="since">Since
1.3.5</span>. All other connection types, including standard
If (and only if) the network type supports vlan tagging
transparent to the guest, an optional <code>&lt;vlan&gt;</code>
element can specify one or more vlan tags to apply to the
traffic of all guests using this
network <span class="since">Since 0.10.0</span>. (openvswitch
and type='hostdev' SR-IOV networks do support transparent vlan
tagging of guest traffic; everything else, including standard
linux bridges and libvirt's own virtual networks, <b>do not</b>
support it. 802.1Qbh (vn-link) and 802.1Qbg (VEPA) switches
provide their own way (outside of libvirt) to tag guest traffic
onto a specific VLAN. Each tag is given in a
separate <code>&lt;tag&gt;</code> subelement
of <code>&lt;vlan&gt;</code> (for example: <code>&lt;tag
id='42'/&gt;</code>). For VLAN trunking of multiple tags (which
is supported only on Open vSwitch connections),
multiple <code>&lt;tag&gt;</code> subelements can be specified,
which implies that the user wants to do VLAN trunking on the
interface for all the specified tags. In the case that VLAN
trunking of a single tag is desired, the optional
attribute <code>trunk='yes'</code> can be added to the toplevel
<code>&lt;vlan&gt;</code> element to differentiate trunking of a
single tag from normal tagging.
onto specific vlans.) As expected, the <code>tag</code>
attribute specifies which vlan tag to use. If a network has more
than one <code>&lt;vlan&gt;</code> element defined, it is
assumed that the user wants to do VLAN trunking using all the
specified tags. In the case that vlan trunking with a single tag
is desired, the optional attribute <code>trunk='yes'</code> can
be added to the vlan element.
</p>
<p>
For network connections using Open vSwitch it is also possible
to configure 'native-tagged' and 'native-untagged' VLAN modes
<span class="since">Since 1.1.0.</span> This is done with the
optional <code>nativeMode</code> attribute on
the <code>&lt;tag&gt;</code> subelement: <code>nativeMode</code>
may be set to 'tagged' or 'untagged'. The <code>id</code>
attribute of the <code>&lt;tag&gt;</code> subelement
containing <code>nativeMode</code> sets which VLAN is considered
to be the "native" VLAN for this interface, and
the <code>nativeMode</code> attribute determines whether or not
traffic for that VLAN will be tagged.
For network connections using openvswitch it is possible to
configure the 'native-tagged' and 'native-untagged' vlan modes
<span class="since">Since 1.1.0</span>. This uses the optional
<code>nativeMode</code> attribute on the <code>&lt;tag&gt;</code>
element: <code>nativeMode</code> may be set to 'tagged' or
'untagged'. The id attribute of the element sets the native vlan.
</p>
<p>
<code>&lt;vlan&gt;</code> elements can also be specified in
@@ -782,7 +716,7 @@
set that attribute of the same name for each domain interface
using this portgroup (<span class="since">since
1.2.10</span>). See
the <a href="formatdomain.html#elementsNICS">Network
the <a href="formatdomain.html#elementSNICS">Network
interfaces</a> section of the domain XML documentation for more
details. Note that an explicit setting of this attribute in the
portgroup overrides the network-wide setting, and an explicit
@@ -832,17 +766,18 @@
</p>
<pre>
...
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.128" end="192.168.122.254"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;route address="192.168.222.0" prefix="24" gateway="192.168.122.2"/&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/&gt;
&lt;route family="ipv6" address="2001:db8:ca2:3::" prefix="64" gateway="2001:db8:ca2:2::2"/&gt;
&lt;route family="ipv6" address="2001:db9:4:1::" prefix="64" gateway="2001:db8:ca2:2::3" metric='2'/&gt;
...
...
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.128" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;route address="192.168.222.0" prefix="24" gateway="192.168.122.2" /&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;route family="ipv6" address="2001:db8:ca2:3::" prefix="64" gateway="2001:db8:ca2:2::2"/&gt;
&lt;route family="ipv6" address="2001:db9:4:1::" prefix="64" gateway="2001:db8:ca2:2::3" metric='2'&gt;
&lt;/route&gt;
...
</pre>
<h3><a name="elementsAddress">Addressing</a></h3>
@@ -857,31 +792,29 @@
</p>
<pre>
...
&lt;mac address='00:16:3E:5D:C7:9E'/&gt;
&lt;domain name="example.com"/&gt;
&lt;dns&gt;
&lt;txt name="example" value="example value"/&gt;
&lt;forwarder addr="8.8.8.8"/&gt;
&lt;forwarder domain='example.com' addr="8.8.4.4"/&gt;
&lt;forwarder domain='www.example.com'/&gt;
&lt;srv service='name' protocol='tcp' domain='test-domain-name' target='.'
port='1024' priority='10' weight='10'/&gt;
&lt;host ip='192.168.122.2'&gt;
&lt;hostname&gt;myhost&lt;/hostname&gt;
&lt;hostname&gt;myhostalias&lt;/hostname&gt;
&lt;/host&gt;
&lt;/dns&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0" localPtr="yes"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.100" end="192.168.122.254"/&gt;
&lt;host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10"/&gt;
&lt;host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" localPtr="yes"/&gt;
&lt;route family="ipv6" address="2001:db9:ca1:1::" prefix="64" gateway="2001:db8:ca2:2::2"/&gt;
</pre>
...
&lt;mac address='00:16:3E:5D:C7:9E'/&gt;
&lt;domain name="example.com"/&gt;
&lt;dns&gt;
&lt;txt name="example" value="example value" /&gt;
&lt;forwarder addr="8.8.8.8"/&gt;
&lt;forwarder addr="8.8.4.4"/&gt;
&lt;srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/&gt;
&lt;host ip='192.168.122.2'&gt;
&lt;hostname&gt;myhost&lt;/hostname&gt;
&lt;hostname&gt;myhostalias&lt;/hostname&gt;
&lt;/host&gt;
&lt;/dns&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.100" end="192.168.122.254" /&gt;
&lt;host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10" /&gt;
&lt;host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;route family="ipv6" address="2001:db9:ca1:1::" prefix="64" gateway="2001:db8:ca2:2::2" /&gt;
&lt;/network&gt;</pre>
<dl>
<dt><code>mac</code></dt>
@@ -903,18 +836,6 @@
information for the virtual network's DNS
server <span class="since">Since 0.9.3</span>.
<p>
The dns element can have an optional <code>enable</code>
attribute <span class="since">Since 2.2.0</span>.
If <code>enable</code> is "no", then no DNS server will be
setup by libvirt for this network (and any other
configuration in <code>&lt;dns&gt;</code> will be ignored).
If <code>enable</code> is "yes" or unspecified (including
the complete absence of any <code>&lt;dns&gt;</code>
element) then a DNS server will be setup by libvirt to
listen on all IP addresses specified in the network's
configuration.
</p>
<p>
The dns element
can have an optional <code>forwardPlainNames</code>
@@ -933,25 +854,12 @@
Currently supported sub-elements of <code>&lt;dns&gt;</code> are:
<dl>
<dt><code>forwarder</code></dt>
<dd>The dns element can have 0 or
more <code>&lt;forwarder&gt;</code> elements. Each
forwarder element defines an alternate DNS server to use
for some, or all, DNS requests sent to this network's DNS
server. There are two attributes - <code>domain</code>,
and <code>addr</code>; at least one of these must be
specified in any <code>&lt;forwarder&gt;</code>
element. If both <code>domain</code> and <code>addr</code>
are specified, then all requests that match the given
domain will be forwarded to the DNS server at addr. If
only <code>domain</code> is specified, then all matching
domains will be resolved locally (or via the host's
standard DNS forwarding if they can't be resolved
locally). If an <code>addr</code> is specified by itself,
then all DNS requests to the network's DNS server will be
forwarded to the DNS server at that address with no
exceptions. <code>addr</code> <span class="since">Since
1.1.3</span>, <code>domain</code> <span class="since">Since
2.2.0</span>.
<dd>A <code>dns</code> element can have 0 or
more <code>forwarder</code> elements. Each forwarder
element defines an IP address to be used as forwarder in
DNS server configuration. The addr attribute is required
and defines the IP address of every
forwarder. <span class="since">Since 1.1.3</span>
</dd>
<dt><code>txt</code></dt>
<dd>A <code>dns</code> element can have 0 or more <code>txt</code> elements.
@@ -975,61 +883,58 @@
<dd>The <code>dns</code> element can have also 0 or more <code>srv</code>
record elements. Each <code>srv</code> record element defines a DNS SRV record
and has 2 mandatory and 5 optional attributes. The mandatory attributes
are service <code>name</code> and <code>protocol</code> (tcp, udp)
and the optional attributes are <code>target</code>,
<code>port</code>, <code>priority</code>, <code>weight</code> and
<code>domain</code> as defined in DNS server SRV RFC (RFC 2782).
are service name and protocol (tcp, udp) and the optional attributes are
target, port, priority, weight and domain as defined in DNS server SRV
RFC (RFC 2782).
<span class="since">Since 0.9.9</span>
</dd>
</dl>
</dd>
<dt><code>ip</code></dt>
<dd>The <code>address</code> attribute defines an IPv4 address in
dotted-decimal format, or an IPv6 address in standard colon-separated
hexadecimal format, that will be configured on the bridge device
associated with the virtual network. To the guests this IPv4 address
will be their IPv4 default route. For IPv6, the default route is
established via Router Advertisement. For IPv4 addresses, the
<code>netmask</code> attribute defines the significant bits of the
network address, again specified in dotted-decimal format. For IPv6
addresses, and as an alternate method for IPv4 addresses, the
significant bits of the network address can be specified with the
<code>prefix</code> attribute, which is an integer (for example,
<code>netmask='255.255.255.0'</code> could also be given as
<code>prefix='24'</code>). The <code>family</code> attribute is used
to specify the type of address &mdash; <code>ipv4</code> or
<code>ipv6</code>; if no <code>family</code> is given,
<code>ipv4</code> is assumed. More than one address of each family can
be defined for a network. The optional <code>localPtr</code> attribute
(<span class="since">since 3.0.0</span>) configures the DNS server to
not forward any reverse DNS requests for IP addresses from the network
configured by the <code>address</code> and
<code>netmask</code>/<code>prefix</code> attributes. For some unusual
network prefixes (not divisible by 8 for IPv4 or not divisible by 4 for
IPv6) libvirt may be unable to compute the PTR domain automatically.
The <code>ip</code> element is supported <span class="since">since
0.3.0</span>. IPv6, multiple addresses on a single network,
<code>family</code>, and <code>prefix</code> are supported
<span class="since">since 0.8.7</span>. The <code>ip</code> element may
contain the following elements:
dotted-decimal format, or an IPv6 address in standard
colon-separated hexadecimal format, that will be configured on
the bridge
device associated with the virtual network. To the guests this IPv4
address will be their IPv4 default route. For IPv6, the default route is
established via Router Advertisement.
For IPv4 addresses, the <code>netmask</code>
attribute defines the significant bits of the network address,
again specified in dotted-decimal format. For IPv6 addresses,
and as an alternate method for IPv4 addresses, you can specify
the significant bits of the network address with the <code>prefix</code>
attribute, which is an integer (for example, <code>netmask='255.255.255.0'</code>
could also be given as <code>prefix='24'</code>. The <code>family</code>
attribute is used to specify the type of address - 'ipv4' or 'ipv6'; if no
<code>family</code> is given, 'ipv4' is assumed. A network can have more than
one of each family of address defined, but only a single IPv4 address can have a
<code>dhcp</code> or <code>tftp</code> element. <span class="since">Since 0.3.0 </span>
IPv6, multiple addresses on a single network, <code>family</code>, and
<code>prefix</code> are support <span class="since">Since 0.8.7</span>.
Similar to IPv4, one IPv6 address per network can also have
a <code>dhcp</code> definition. <span class="since">Since 1.0.1</span>
<dl>
<dt><code>tftp</code></dt>
<dd>The optional <code>tftp</code> element and its mandatory
<code>root</code> attribute enable TFTP services. The attribute
specifies the path to the root directory served via TFTP. The
<code>tftp</code> element is not supported for IPv6 addresses,
and can only be specified on a single IPv4 address per network.
<dd>Immediately within
the <code>ip</code> element there is an optional <code>tftp</code>
element. The presence of this element and of its attribute
<code>root</code> enables TFTP services. The attribute specifies
the path to the root directory served via TFTP. <code>tftp</code> is not
supported for IPv6 addresses, and can only be specified on a single IPv4 address
per network.
<span class="since">Since 0.7.1</span>
</dd>
<dt><code>dhcp</code></dt>
<dd>The presence of this element enables DHCP services on the
virtual network. The <code>dhcp</code> element is supported for
both IPv4 (<span class="since">since 0.3.0</span>) and IPv6
(<span class="since">since 1.0.1</span>), but only for one IP
address of each type per network. The following sub-elements are
supported:
<dd>Also within the <code>ip</code> element there is an
optional <code>dhcp</code> element. The presence of this element
enables DHCP services on the virtual network. It will further
contain one or more <code>range</code> elements. The
<code>dhcp</code> element supported for both
IPv4 <span class="since">Since 0.3.0</span>
and IPv6 <span class="since">Since 1.0.1</span>, but
only for one IP address of each type per network.
<dl>
<dt><code>range</code></dt>
<dd>The <code>start</code> and <code>end</code> attributes on the
@@ -1039,39 +944,39 @@
<code>ip</code> element. There may be zero or more
<code>range</code> elements specified.
<span class="since">Since 0.3.0</span>
<code>range</code> can be specified for one IPv4 address,
one IPv6 address, or both. <span class="since">Since 1.0.1</span>
</dd>
<dt><code>host</code></dt>
<dd>Within the <code>dhcp</code> element there may be zero or
more <code>host</code> elements. These specify hosts which will
be given names and predefined IP addresses by the built-in DHCP
server. Any IPv4 <code>host</code> element must specify the MAC
address of the host to be assigned a given name (via the
<code>mac</code> attribute), the IP to be assigned to that host
(via the <code>ip</code> attribute), and the name itself (the
<code>name</code> attribute). The IPv6 <code>host</code>
element differs slightly from that for IPv4: there is no
<code>mac</code> attribute since a MAC address has no defined
meaning in IPv6. Instead, the <code>name</code> attribute is
used to identify the host to be assigned the IPv6 address. For
DHCPv6, the name is the plain name of the client host sent by the
client to the server. Note that this method of assigning a
specific IP address can also be used for IPv4 instead of the
<code>mac</code> attribute.
<span class="since">Since 0.4.5</span>
<dd>Within the <code>dhcp</code> element there may be zero or more
<code>host</code> elements. These specify hosts which will be given
names and predefined IP addresses by the built-in DHCP server. Any
IPv4 <code>host</code> element must specify the MAC address of the host to be assigned
a given name (via the <code>mac</code> attribute), the IP to be
assigned to that host (via the <code>ip</code> attribute), and the
name to be given that host by the DHCP server (via the
<code>name</code> attribute). <span class="since">Since 0.4.5</span>
An IPv6 <code>host</code> element differs slightly from that for IPv4:
there is no <code>mac</code> attribute since a MAC address has no
defined meaning in IPv6. Instead, the <code>name</code> attribute is
used to identify the host to be assigned the IPv6 address. For DHCPv6,
the name is the plain name of the client host sent by the
client to the server. Note that this method of assigning a
specific IP address can also be used instead of the <code>mac</code>
attribute for IPv4. <span class="since">Since 1.0.1</span>
</dd>
<dt><code>bootp</code></dt>
<dd>The optional <code>bootp</code> element specifies BOOTP
options to be provided by the DHCP server for IPv4 only. Two
attributes are supported: <code>file</code> is mandatory and
gives the file to be used for the boot image;
<code>server</code> is optional and gives the address of the
TFTP server from which the boot image will be fetched.
<code>server</code> defaults to the same host that runs the
DHCP server, as is the case when the <code>tftp</code> element
is used. The BOOTP options currently have to be the same for
all address ranges and statically assigned addresses. <span
class="since">Since 0.7.1</span> (<code>server</code>
<span class="since">since 0.7.3</span>)
<dd>The optional <code>bootp</code>
element specifies BOOTP options to be provided by the DHCP
server for IPv4 only.
Two attributes are supported: <code>file</code> is mandatory and
gives the file to be used for the boot image; <code>server</code> is
optional and gives the address of the TFTP server from which the boot
image will be fetched. <code>server</code> defaults to the same host
that runs the DHCP server, as is the case when the <code>tftp</code>
element is used. The BOOTP options currently have to be the same
for all address ranges and statically assigned addresses.<span
class="since">Since 0.7.1 (<code>server</code> since 0.7.3).</span>
</dd>
</dl>
</dd>
@@ -1094,17 +999,17 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;default&lt;/name&gt;
&lt;bridge name="virbr0"/&gt;
&lt;forward mode="nat"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;default&lt;/name&gt;
&lt;bridge name="virbr0" /&gt;
&lt;forward mode="nat"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;/network&gt;</pre>
<p>
@@ -1113,21 +1018,21 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;default6&lt;/name&gt;
&lt;bridge name="virbr0"/&gt;
&lt;forward mode="nat"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"&gt;
&lt;dhcp&gt;
&lt;range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;default6&lt;/name&gt;
&lt;bridge name="virbr0" /&gt;
&lt;forward mode="nat"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesRoute">Routed network config</a></h3>
@@ -1141,17 +1046,17 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;local&lt;/name&gt;
&lt;bridge name="virbr1"/&gt;
&lt;forward mode="route" dev="eth1"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"/&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;local&lt;/name&gt;
&lt;bridge name="virbr1" /&gt;
&lt;forward mode="route" dev="eth1"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;/network&gt;</pre>
<p>
Below is another IPv6 variation. Instead of a dhcp range being
@@ -1164,25 +1069,24 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;local6&lt;/name&gt;
&lt;bridge name="virbr1"/&gt;
&lt;forward mode="route" dev="eth1"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64"&gt;
&lt;dhcp&gt;
&lt;host name="paul" ip="2001:db8:ca2:2:3::1"/&gt;
&lt;host id="0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66" ip="2001:db8:ca2:2:3::2"/&gt;
&lt;host id="0:3:0:1:0:16:3e:11:22:33" name="ralph" ip="2001:db8:ca2:2:3::3"/&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63"
name="badbob" ip="2001:db8:ca2:2:3::4"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;local6&lt;/name&gt;
&lt;bridge name="virbr1" /&gt;
&lt;forward mode="route" dev="eth1"/&gt;
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.2" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;host name="paul" ip="2001:db8:ca2:2:3::1" /&gt;
&lt;host id="0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66" ip="2001:db8:ca2:2:3::2" /&gt;
&lt;host id="0:3:0:1:0:16:3e:11:22:33" name="ralph" ip="2001:db8:ca2:2:3::3" /&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63" name="badbob" ip="2001:db8:ca2:2:3::4" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
<p>
Below is yet another IPv6 variation. This variation has only
@@ -1197,19 +1101,19 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;net7&lt;/name&gt;
&lt;bridge name="virbr7"/&gt;
&lt;forward mode="route"/&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:7::1" prefix="64"&gt;
&lt;dhcp&gt;
&lt;range start="2001:db8:ca2:7::100" end="2001:db8:ca2::1ff"/&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63"
name="lucas" ip="2001:db8:ca2:2:3::4"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;route family="ipv6" address="2001:db8:ca2:8::" prefix="64" gateway="2001:db8:ca2:7::4"/&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;net7&lt;/name&gt;
&lt;bridge name="virbr7" /&gt;
&lt;forward mode="route"/&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:7::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;range start="2001:db8:ca2:7::100" end="2001:db8:ca2::1ff" /&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63" name="lucas" ip="2001:db8:ca2:2:3::4" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;route family="ipv6" address="2001:db8:ca2:8::" prefix="64" gateway="2001:db8:ca2:7::4" &gt;
&lt;/route&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesPrivate">Isolated network config</a></h3>
@@ -1222,16 +1126,16 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;private&lt;/name&gt;
&lt;bridge name="virbr2"/&gt;
&lt;ip address="192.168.152.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.152.2" end="192.168.152.254"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64"/&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;private&lt;/name&gt;
&lt;bridge name="virbr2" /&gt;
&lt;ip address="192.168.152.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.152.2" end="192.168.152.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64" /&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesPrivate6">Isolated IPv6 network config</a></h3>
@@ -1245,19 +1149,18 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;sixnet&lt;/name&gt;
&lt;bridge name="virbr6"/&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:6::1" prefix="64"&gt;
&lt;dhcp&gt;
&lt;host name="peter" ip="2001:db8:ca2:6:6::1"/&gt;
&lt;host id="0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66" ip="2001:db8:ca2:6:6::2"/&gt;
&lt;host id="0:3:0:1:0:16:3e:11:22:33" name="dariusz" ip="2001:db8:ca2:6:6::3"/&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63"
name="anita" ip="2001:db8:ca2:6:6::4"/&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;sixnet&lt;/name&gt;
&lt;bridge name="virbr6" /&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:6::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;host name="peter" ip="2001:db8:ca2:6:6::1" /&gt;
&lt;host id="0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66" ip="2001:db8:ca2:6:6::2" /&gt;
&lt;host id="0:3:0:1:0:16:3e:11:22:33" name="dariusz" ip="2001:db8:ca2:6:6::3" /&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63" name="anita" ip="2001:db8:ca2:6:6::4" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesBridge">Using an existing host bridge</a></h3>
@@ -1271,11 +1174,11 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;host-bridge&lt;/name&gt;
&lt;forward mode="bridge"/&gt;
&lt;bridge name="br0"/&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;host-bridge&lt;/name&gt;
&lt;forward mode="bridge"/&gt;
&lt;bridge name="br0"/&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesDirect">Using a macvtap "direct" connection</a></h3>
@@ -1301,16 +1204,16 @@
</p>
<pre>
&lt;network&gt;
&lt;name&gt;direct-macvtap&lt;/name&gt;
&lt;forward mode="bridge"&gt;
&lt;interface dev="eth20"/&gt;
&lt;interface dev="eth21"/&gt;
&lt;interface dev="eth22"/&gt;
&lt;interface dev="eth23"/&gt;
&lt;interface dev="eth24"/&gt;
&lt;/forward&gt;
&lt;/network&gt;</pre>
&lt;network&gt;
&lt;name&gt;direct-macvtap&lt;/name&gt;
&lt;forward mode="bridge"&gt;
&lt;interface dev="eth20"/&gt;
&lt;interface dev="eth21"/&gt;
&lt;interface dev="eth22"/&gt;
&lt;interface dev="eth23"/&gt;
&lt;interface dev="eth24"/&gt;
&lt;/forward&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesNoGateway">Network config with no gateway addresses</a></h3>
@@ -1325,12 +1228,12 @@
</p>
<pre>
&lt;network ipv6='yes'&gt;
&lt;name&gt;nogw&lt;/name&gt;
&lt;uuid&gt;7a3b7497-1ec7-8aef-6d5c-38dff9109e93&lt;/uuid&gt;
&lt;bridge name="virbr2" stp="on" delay="0"/&gt;
&lt;mac address='00:16:3E:5D:C7:9E'/&gt;
&lt;/network&gt;</pre>
&lt;network ipv6='yes'&gt;
&lt;name&gt;nogw&lt;/name&gt;
&lt;uuid&gt;7a3b7497-1ec7-8aef-6d5c-38dff9109e93&lt;/uuid&gt;
&lt;bridge name="virbr2" stp="on" delay="0" /&gt;
&lt;mac address='00:16:3E:5D:C7:9E'/&gt;
&lt;/network&gt;</pre>
</body>
</html>

View File

@@ -37,12 +37,6 @@
<dd>If this element is present, it names the parent device (that
is, a controller to which this node belongs).
</dd>
<dt><code>devnode</code></dt>
<dd>This node appears for each associated <code>/dev</code>
special file. A mandatory attribute <code>type</code> specify
the kind of file path, which may be either <code>dev</code> for
the main name, or <code>link</code> for additional symlinks.
</dd>
<dt><code>capability</code></dt>
<dd>This node appears for each capability that libvirt
associates with a node. A mandatory
@@ -103,38 +97,27 @@
<dd>
This optional element can occur multiple times. If it
exists, it has a mandatory <code>type</code> attribute
which will be set to:
<dl>
<dt><code>physical_function</code></dt>
<dd>
That means there will be a single <code>address</code>
subelement which contains the PCI address of the SRIOV
Physical Function (PF) that is the parent of this device
(and this device is, by implication, an SRIOV Virtual
Function (VF)).
</dd>
<dt><code>virtual_function</code></dt>
<dd>
In this case this device is an SRIOV PF, and the capability
element will have a list of <code>address</code>
subelements, one for each VF on this PF. If the host system
supports reporting it (via the "sriov_maxvfs" file in the
device's sysfs directory) the capability element will also
have an attribute named <code>maxCount</code> which is the
maximum number of SRIOV VFs supported by this device, which
could be higher than the number of VFs that are curently
active <span class="since">since 1.3.0</span>; in this case,
even if there are currently no active VFs the
virtual_functions capabililty will still be shown.
</dd>
<dt><code>pci-bridge</code> or <code>cardbus-bridge</code></dt>
<dd>
This shows merely that the lower 7 bits of PCI header type
have either value of 1 or 2 respectively. Usually this
means such device cannot be used for PCI passthrough.
<span class="since">Since 1.3.3</span>
</dd>
</dl>
which will be set to
either <code>physical_function</code>
or <code>virtual_functions</code>. If the type
is <code>physical_function</code>, there will be a
single <code>address</code> subelement which contains
the PCI address of the SRIOV Physical Function (PF)
that is the parent of this device (and this device is,
by implication, an SRIOV Virtual Function (VF)). If
the type is <code>virtual_functions</code>, then this
device is an SRIOV PF, and the capability element will
have a list of <code>address</code> subelements, one
for each VF on this PF. If the host system supports
reporting it (via the "sriov_maxvfs" file in the
device's sysfs directory) the capability element will
also have an attribute named <code>maxCount</code>
which is the maximum number of SRIOV VFs supported by
this device, which could be higher than the number of
VFs that are curently active <span class="since">since
1.3.0</span>; in this case, even if there are
currently no active VFs the virtual_functions
capabililty will still be shown.
</dd>
<dt><code>numa</code></dt>
<dd>
@@ -260,7 +243,7 @@
number of vport in use. <code>max_vports</code> shows the
maximum vports the HBA supports. "fc_host" implies following
sub-elements: <code>wwnn</code>, <code>wwpn</code>, and
optionally <code>fabric_wwn</code>.
<code>fabric_wwn</code>.
</dd>
</dl>
</dd>
@@ -314,16 +297,6 @@
and <code>media_label</code>.</dd>
</dl>
</dd>
<dt><code>drm</code></dt>
<dd>Describes a Direct Rendering Manager (DRM) device.
Sub-elements include:
<dl>
<dt><code>type</code></dt>
<dd>The type of DRM device. Could be
<code>primary</code>, <code>control</code> or
<code>render</code>.</dd>
</dl>
</dd>
</dl>
</dd>
</dl>

View File

@@ -40,7 +40,7 @@
of all running virtual machines that reference this filter are updated.
<br/><br/>
Network filtering support is available <span class="since">since 0.8.1
(QEMU, KVM)</span>
(Qemu, KVM)</span>
</p>
<h2><a name="nwfconcepts">Concepts</a></h2>
@@ -61,14 +61,14 @@
the filter <code>clean-traffic</code>.
</p>
<pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:16:3e:5d:c7:9e'/&gt;
&lt;filterref filter='clean-traffic'/&gt;
&lt;/interface&gt;
&lt;/devices&gt;
...</pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:16:3e:5d:c7:9e'/&gt;
&lt;filterref filter='clean-traffic'/&gt;
&lt;/interface&gt;
&lt;/devices&gt;
...</pre>
<p>
Network filters are written in XML and may either contain references
@@ -91,16 +91,16 @@
the parameter <code>IP</code> and a dotted IP address as value.
</p>
<pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:16:3e:5d:c7:9e'/&gt;
&lt;filterref filter='clean-traffic'&gt;
&lt;parameter name='IP' value='10.0.0.1'/&gt;
&lt;/filterref&gt;
&lt;/interface&gt;
&lt;/devices&gt;
...</pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:16:3e:5d:c7:9e'/&gt;
&lt;filterref filter='clean-traffic'&gt;
&lt;parameter name='IP' value='10.0.0.1'/&gt;
&lt;/filterref&gt;
&lt;/interface&gt;
&lt;/devices&gt;
...</pre>
<p>
In this particular example, the <code>clean-traffic</code> network
@@ -285,18 +285,18 @@
providing multiple elements for the IP variable is:
</p>
<pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:16:3e:5d:c7:9e'/&gt;
&lt;filterref filter='clean-traffic'&gt;
&lt;parameter name='IP' value='10.0.0.1'/&gt;
&lt;parameter name='IP' value='10.0.0.2'/&gt;
&lt;parameter name='IP' value='10.0.0.3'/&gt;
&lt;/filterref&gt;
&lt;/interface&gt;
&lt;/devices&gt;
...</pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:16:3e:5d:c7:9e'/&gt;
&lt;filterref filter='clean-traffic'&gt;
&lt;parameter name='IP' value='10.0.0.1'/&gt;
&lt;parameter name='IP' value='10.0.0.2'/&gt;
&lt;parameter name='IP' value='10.0.0.3'/&gt;
&lt;/filterref&gt;
&lt;/interface&gt;
&lt;/devices&gt;
...</pre>
<p>
This then allows filters to enable multiple IP addresses
per interface. Therefore, with the list
@@ -304,11 +304,11 @@
individual filtering rules, one for each IP address.
</p>
<pre>
...
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;tcp srpipaddr='$IP'/&gt;
&lt;/rule&gt;
...
...
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;tcp srpipaddr='$IP'/&gt;
&lt;/rule&gt;
...
</pre>
<p>
<span class="since">Since 0.9.10</span> it is possible to access
@@ -317,11 +317,11 @@
of the variable DSTPORTS.
</p>
<pre>
...
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;udp dstportstart='$DSTPORTS[1]'/&gt;
&lt;/rule&gt;
...
...
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;udp dstportstart='$DSTPORTS[1]'/&gt;
&lt;/rule&gt;
...
</pre>
<p>
<span class="since">Since 0.9.10</span> it is possible to create
@@ -336,29 +336,29 @@
iterators to access their elements.
</p>
<pre>
...
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;ip srcipaddr='$SRCIPADDRESSES[@1]' dstportstart='$DSTPORTS[@2]'/&gt;
&lt;/rule&gt;
...
...
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;ip srcipaddr='$SRCIPADDRESSES[@1]' dstportstart='$DSTPORTS[@2]'/&gt;
&lt;/rule&gt;
...
</pre>
<p>
In an example we assign concrete values to SRCIPADDRESSES and DSTPORTS
</p>
<pre>
SRCIPADDRESSES = [ 10.0.0.1, 11.1.2.3 ]
DSTPORTS = [ 80, 8080 ]
SRCIPADDRESSES = [ 10.0.0.1, 11.1.2.3 ]
DSTPORTS = [ 80, 8080 ]
</pre>
<p>
Accessing the variables using $SRCIPADDRESSES[@1] and $DSTPORTS[@2] would
then result in all combinations of addresses and ports being created:
</p>
<pre>
10.0.0.1, 80
10.0.0.1, 8080
11.1.2.3, 80
11.1.2.3, 8080
10.0.0.1, 80
10.0.0.1, 8080
11.1.2.3, 80
11.1.2.3, 8080
</pre>
<p>
Accessing the same variables using a single iterator, for example by using
@@ -366,8 +366,8 @@ DSTPORTS = [ 80, 8080 ]
parallel access to both lists and result in the following combinations:
</p>
<pre>
10.0.0.1, 80
11.1.2.3, 8080
10.0.0.1, 80
11.1.2.3, 8080
</pre>
<p>
Further, the notation of $VARIABLE is short-hand for $VARIABLE[@0]. The
@@ -440,12 +440,12 @@ DSTPORTS = [ 80, 8080 ]
using the DHCP snooping method:
</p>
<pre>
&lt;interface type='bridge'&gt;
&lt;source bridge='virbr0'/&gt;
&lt;filterref filter='clean-traffic'&gt;
&lt;parameter name='CTRL_IP_LEARNING' value='dhcp'/&gt;
&lt;/filterref&gt;
&lt;/interface&gt;
&lt;interface type='bridge'&gt;
&lt;source bridge='virbr0'/&gt;
&lt;filterref filter='clean-traffic'&gt;
&lt;parameter name='CTRL_IP_LEARNING' value='dhcp'/&gt;
&lt;/filterref&gt;
&lt;/interface&gt;
</pre>
<h3><a name="nwfelemsReservedVars">Reserved Variables</a></h3>
@@ -658,10 +658,10 @@ DSTPORTS = [ 80, 8080 ]
</p>
<pre>
[...]
&lt;rule action='drop' direction='in'&gt;
&lt;protocol match='no' attribute1='value1' attribute2='value2'/&gt;
&lt;protocol attribute3='value3'/&gt;
&lt;/rule&gt;
&lt;rule action='drop' direction='in'&gt;
&lt;protocol match='no' attribute1='value1' attribute2='value2'/&gt;
&lt;protocol attribute3='value3'/&gt;
&lt;/rule&gt;
[...]
</pre>
<p>
@@ -1779,9 +1779,9 @@ DSTPORTS = [ 80, 8080 ]
<br/><br/>
</p>
<h5><a name="nwfelemsRulesProtoMiscv6">ESP, AH, UDPLITE, 'ALL' over IPv6</a></h5>
<h5><a name="nwfelemsRulesProtoMiscv6">IGMP, ESP, AH, UDPLITE, 'ALL' over IPv6</a></h5>
<p>
Protocol ID: <code>esp-ipv6</code>, <code>ah-ipv6</code>, <code>udplite-ipv6</code>, <code>all-ipv6</code>
Protocol ID: <code>igmp-ipv6</code>, <code>esp-ipv6</code>, <code>ah-ipv6</code>, <code>udplite-ipv6</code>, <code>all-ipv6</code>
<br/>
Note: The chain parameter is ignored for this type of traffic
and should either be omitted or set to <code>root</code>.
@@ -1896,11 +1896,11 @@ DSTPORTS = [ 80, 8080 ]
turned off for incoming connections to TCP port 12345.
</p>
<pre>
[...]
&lt;rule direction='in' action='accept' statematch='false'&gt;
&lt;tcp dstportstart='12345'/&gt;
&lt;/rule&gt;
[...]
[...]
&lt;rule direction='in' action='accept' statematch='false'&gt;
&lt;tcp dstportstart='12345'/&gt;
&lt;/rule&gt;
[...]
</pre>
<p>
This now allows incoming traffic to TCP port 12345, but would also
@@ -1918,26 +1918,26 @@ DSTPORTS = [ 80, 8080 ]
time, the following XML fragment can be used to achieve this.
</p>
<pre>
[...]
&lt;rule action='drop' direction='in' priority='400'&gt;
&lt;tcp connlimit-above='1'/&gt;
&lt;/rule&gt;
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;tcp dstportstart='22'/&gt;
&lt;/rule&gt;
&lt;rule action='drop' direction='out' priority='400'&gt;
&lt;icmp connlimit-above='1'/&gt;
&lt;/rule&gt;
&lt;rule action='accept' direction='out' priority='500'&gt;
&lt;icmp/&gt;
&lt;/rule&gt;
&lt;rule action='accept' direction='out' priority='500'&gt;
&lt;udp dstportstart='53'/&gt;
&lt;/rule&gt;
&lt;rule action='drop' direction='inout' priority='1000'&gt;
&lt;all/&gt;
&lt;/rule&gt;
[...]
[...]
&lt;rule action='drop' direction='in' priority='400'&gt;
&lt;tcp connlimit-above='1'/&gt;
&lt;/rule&gt;
&lt;rule action='accept' direction='in' priority='500'&gt;
&lt;tcp dstportstart='22'/&gt;
&lt;/rule&gt;
&lt;rule action='drop' direction='out' priority='400'&gt;
&lt;icmp connlimit-above='1'/&gt;
&lt;/rule&gt;
&lt;rule action='accept' direction='out' priority='500'&gt;
&lt;icmp/&gt;
&lt;/rule&gt;
&lt;rule action='accept' direction='out' priority='500'&gt;
&lt;udp dstportstart='53'/&gt;
&lt;/rule&gt;
&lt;rule action='drop' direction='inout' priority='1000'&gt;
&lt;all/&gt;
&lt;/rule&gt;
[...]
</pre>
<p>
Note that the rule for the limit has to logically appear
@@ -1958,7 +1958,7 @@ DSTPORTS = [ 80, 8080 ]
</p>
<pre>
echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
</pre>
<p>
sets the ICMP connection tracking timeout to 3 seconds. The
@@ -2064,7 +2064,7 @@ echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
traffic you want to allow does pass.
<br/><br/>
The network filtering subsystem is currently only available on
Linux hosts and only works for QEMU and KVM type of virtual machines.
Linux hosts and only works for Qemu and KVM type of virtual machines.
On Linux
it builds upon the support for <code>ebtables</code>, <code>iptables
</code> and <code>ip6tables</code> and makes use of their features.
@@ -2201,12 +2201,12 @@ echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
the domain XML of the <code>test</code> VM could then look like this:
</p>
<pre>
[...]
&lt;interface type='bridge'&gt;
&lt;source bridge='mybridge'/&gt;
&lt;filterref filter='test-eth0'/&gt;
&lt;/interface&gt;
[...]
[...]
&lt;interface type='bridge'&gt;
&lt;source bridge='mybridge'/&gt;
&lt;filterref filter='test-eth0'/&gt;
&lt;/interface&gt;
[...]
</pre>
<p>
@@ -2216,15 +2216,15 @@ echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
<code>ICMP</code> rule can be replaced with the following two rules:
</p>
<pre>
&lt;!-- enable outgoing ICMP echo requests--&gt;
&lt;rule action='accept' direction='out'&gt;
&lt;icmp type='8'/&gt;
&lt;/rule&gt;
&lt;!-- enable outgoing ICMP echo requests--&gt;
&lt;rule action='accept' direction='out'&gt;
&lt;icmp type='8'/&gt;
&lt;/rule&gt;
&lt;!-- enable incoming ICMP echo replies--&gt;
&lt;rule action='accept' direction='in'&gt;
&lt;icmp type='0'/&gt;
&lt;/rule&gt;
&lt;!-- enable incoming ICMP echo replies--&gt;
&lt;rule action='accept' direction='in'&gt;
&lt;icmp type='0'/&gt;
&lt;/rule&gt;
</pre>
<h3><a name="nwfwriteexample2nd">Second example custom filter</a></h3>
@@ -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, UML))</span>:
<span class="since">(since 0.8.5 (Qemu, KVM, UML))</span>:
</p>
<pre>
&lt;filter name='test-eth0'&gt;
@@ -2326,9 +2326,9 @@ echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
the ftp connection with the VM is established.
</p>
<pre>
modprobe nf_conntrack_ftp # where available or
modprobe nf_conntrack_ftp # where available or
modprobe ip_conntrack_ftp # if above is not available
modprobe ip_conntrack_ftp # if above is not available
</pre>
<p>
If other protocols than ftp are to be used in conjunction with the

View File

@@ -41,83 +41,53 @@
<dd>
Specifies what this secret is used for. A mandatory
<code>type</code> attribute specifies the usage category, currently
only <code>volume</code>, <code>ceph</code>, <code>iscsi</code>,
and <code>tls</code> are defined. Specific usage categories
are described below.
only <code>volume</code>, <code>ceph</code> and <code>iscsi</code>
are defined. Specific usage categories are described below.
</dd>
</dl>
<h3><a name="VolumeUsageType">Usage type "volume"</a></h3>
<p>
This secret is associated with a volume, whether the format is either
for a "qcow" or a "luks" encrypted volume. Each volume will have a
unique secret associated with it and it is safe to delete the
secret after the volume is deleted. The
<code>&lt;usage type='volume'&gt;</code> element must contain a
single <code>volume</code> element that specifies the path of the volume
This secret is associated with a volume, and it is safe to delete the
secret after the volume is deleted. The <code>&lt;usage
type='volume'&gt;</code> element must contain a
single <code>volume</code> element that specifies the key of the volume
this secret is associated with. For example, create a volume-secret.xml
file as follows:
</p>
<pre>
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;Super secret name of my first puppy&lt;/description&gt;
&lt;uuid&gt;0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f&lt;/uuid&gt;
&lt;usage type='volume'&gt;
&lt;volume&gt;/var/lib/libvirt/images/puppyname.img&lt;/volume&gt;
&lt;/usage&gt;
&lt;/secret&gt;
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;Super secret name of my first puppy&lt;/description&gt;
&lt;uuid&gt;0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f&lt;/uuid&gt;
&lt;usage type='volume'&gt;
&lt;volume&gt;/var/lib/libvirt/images/puppyname.img&lt;/volume&gt;
&lt;/usage&gt;
&lt;/secret&gt;
</pre>
<p>
Define the secret and set the passphrase as follows:
Define the secret and set the pass phrase as follows:
</p>
<pre>
# virsh secret-define volume-secret.xml
Secret 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f created
#
# MYSECRET=`printf %s "open sesame" | base64`
# virsh secret-set-value 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f $MYSECRET
Secret value set
#
# virsh secret-define volume-secret.xml
Secret 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f created
#
# MYSECRET=`printf %s "open sesame" | base64`
# virsh secret-set-value 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f $MYSECRET
Secret value set
#
</pre>
<p>
The volume type secret can be supplied in domain XML for a qcow storage
volume <a href="formatstorageencryption.html">encryption</a> as follows:
The volume type secret can then be used in the XML for a storage volume
<a href="formatstorageencryption.html">encryption</a> as follows:
</p>
<pre>
&lt;encryption format='qcow'&gt;
&lt;secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/&gt;
&lt;/encryption&gt;
</pre>
<p>
The volume type secret can be supplied either in volume XML during
creation of a <a href="formatstorage.html#StorageVol">storage volume</a>
in order to provide the passphrase to encrypt the volume or in
domain XML <a href="formatdomain.html#elementsDisks">disk device</a>
in order to provide the passphrase to decrypt the volume,
<span class="since">since 2.1.0</span>. An example follows:
</p>
<pre>
# cat luks-secret.xml
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;LUKS Sample Secret&lt;/description&gt;
&lt;uuid&gt;f52a81b2-424e-490c-823d-6bd4235bc57&lt;/uuid&gt;
&lt;usage type='volume'&gt;
&lt;volume&gt;/var/lib/libvirt/images/luks-sample.img&lt;/volume&gt;
&lt;/usage&gt;
&lt;/secret&gt;
# virsh secret-define luks-secret.xml
Secret f52a81b2-424e-490c-823d-6bd4235bc57 created
#
# MYSECRET=`printf %s "letmein" | base64`
# virsh secret-set-value f52a81b2-424e-490c-823d-6bd4235bc57 $MYSECRET
Secret value set
#
&lt;encryption format='qcow'&gt;
&lt;secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/&gt;
&lt;/encryption&gt;
</pre>
<h3><a name="CephUsageType">Usage type "ceph"</a></h3>
@@ -134,12 +104,12 @@ Secret value set
</p>
<pre>
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;CEPH passphrase example&lt;/description&gt;
&lt;usage type='ceph'&gt;
&lt;name&gt;ceph_example&lt;/name&gt;
&lt;/usage&gt;
&lt;/secret&gt;
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;CEPH passphrase example&lt;/description&gt;
&lt;usage type='ceph'&gt;
&lt;name&gt;ceph_example&lt;/name&gt;
&lt;/usage&gt;
&lt;/secret&gt;
</pre>
<p>
@@ -149,19 +119,19 @@ Secret value set
chosen secret pass phrase.
</p>
<pre>
# virsh secret-define ceph-secret.xml
Secret 1b40a534-8301-45d5-b1aa-11894ebb1735 created
#
# virsh secret-list
UUID Usage
-----------------------------------------------------------
1b40a534-8301-45d5-b1aa-11894ebb1735 cephx ceph_example
#
# CEPHPHRASE=`printf %s "pass phrase" | base64`
# virsh secret-set-value 1b40a534-8301-45d5-b1aa-11894ebb1735 $CEPHPHRASE
Secret value set
# virsh secret-define ceph-secret.xml
Secret 1b40a534-8301-45d5-b1aa-11894ebb1735 created
#
# virsh secret-list
UUID Usage
-----------------------------------------------------------
1b40a534-8301-45d5-b1aa-11894ebb1735 cephx ceph_example
#
# CEPHPHRASE=`printf %s "pass phrase" | base64`
# virsh secret-set-value 1b40a534-8301-45d5-b1aa-11894ebb1735 $CEPHPHRASE
Secret value set
#
#
</pre>
<p>
@@ -171,9 +141,9 @@ Secret value set
element as follows:
</p>
<pre>
&lt;auth username='myname'&gt;
&lt;secret type='ceph' usage='ceph_example'/&gt;
&lt;/auth&gt;
&lt;auth username='myname'&gt;
&lt;secret type='ceph' usage='ceph_example'/&gt;
&lt;/auth&gt;
</pre>
<p>
@@ -182,9 +152,9 @@ Secret value set
<code>&lt;source&gt;</code> element as follows:
</p>
<pre>
&lt;auth type='ceph' username='myname'&gt;
&lt;secret usage='ceph_example'/&gt;
&lt;/auth&gt;
&lt;auth type='ceph' username='myname'&gt;
&lt;secret usage='ceph_example'/&gt;
&lt;/auth&gt;
</pre>
<h3><a name="iSCSIUsageType">Usage type "iscsi"</a></h3>
@@ -203,11 +173,11 @@ Secret value set
authentication file:
</p>
<pre>
&lt;target iqn.2013-07.com.example:iscsi-pool&gt;
backing-store /home/tgtd/iscsi-pool/disk1
backing-store /home/tgtd/iscsi-pool/disk2
incominguser myname mysecret
&lt;/target&gt;
&lt;target iqn.2013-07.com.example:iscsi-pool&gt;
backing-store /home/tgtd/iscsi-pool/disk1
backing-store /home/tgtd/iscsi-pool/disk2
incominguser myname mysecret
&lt;/target&gt;
</pre>
<p>
Define an iscsi-secret.xml file to describe the secret. Use the
@@ -219,12 +189,12 @@ incominguser myname mysecret
or disk XML description.
</p>
<pre>
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;Passphrase for the iSCSI example.com server&lt;/description&gt;
&lt;usage type='iscsi'&gt;
&lt;target&gt;libvirtiscsi&lt;/target&gt;
&lt;/usage&gt;
&lt;/secret&gt;
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;Passphrase for the iSCSI example.com server&lt;/description&gt;
&lt;usage type='iscsi'&gt;
&lt;target&gt;libvirtiscsi&lt;/target&gt;
&lt;/usage&gt;
&lt;/secret&gt;
</pre>
<p>
@@ -235,18 +205,18 @@ incominguser myname mysecret
used in the iSCSI authentication configuration file.
</p>
<pre>
# virsh secret-define secret.xml
Secret c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 created
# virsh secret-define secret.xml
Secret c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 created
# virsh secret-list
UUID Usage
-----------------------------------------------------------
c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 iscsi libvirtiscsi
# virsh secret-list
UUID Usage
-----------------------------------------------------------
c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 iscsi libvirtiscsi
# MYSECRET=`printf %s "mysecret" | base64`
# virsh secret-set-value c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 $MYSECRET
Secret value set
#
# MYSECRET=`printf %s "mysecret" | base64`
# virsh secret-set-value c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 $MYSECRET
Secret value set
#
</pre>
<p>
@@ -256,9 +226,9 @@ Secret value set
element as follows:
</p>
<pre>
&lt;auth username='myname'&gt;
&lt;secret type='iscsi' usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
&lt;auth username='myname'&gt;
&lt;secret type='iscsi' usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
</pre>
<p>
@@ -267,64 +237,9 @@ Secret value set
<code>&lt;source&gt;</code> element as follows:
</p>
<pre>
&lt;auth type='chap' username='myname'&gt;
&lt;secret usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
&lt;auth type='chap' username='myname'&gt;
&lt;secret usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
</pre>
<h3><a name="tlsUsageType">Usage type "tls"</a></h3>
<p>
This secret may be used in order to provide the passphrase for the
private key used to provide TLS credentials.
The <code>&lt;usage type='tls'&gt;</code> element must contain a
single <code>name</code> element that specifies a usage name
for the secret.
<span class="since">Since 2.3.0</span>.
The following is an example of the expected XML and processing to
define the secret:
</p>
<pre>
# cat tls-secret.xml
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;sample tls secret&lt;/description&gt;
&lt;usage type='tls'&gt;
&lt;name&gt;TLS_example&lt;/name&gt;
&lt;/usage&gt;
&lt;/secret&gt;
# virsh secret-define tls-secret.xml
Secret 718c71bd-67b5-4a2b-87ec-a24e8ca200dc created
# virsh secret-list
UUID Usage
-----------------------------------------------------------
718c71bd-67b5-4a2b-87ec-a24e8ca200dc tls TLS_example
#
</pre>
<p>
A secret may also be defined via the
<a href="html/libvirt-libvirt-secret.html#virSecretDefineXML">
<code>virSecretDefineXML</code></a> API.
Once the secret is defined, a secret value will need to be set. The
secret would be the passphrase used to access the TLS credentials.
The following is a simple example of using
<code>virsh secret-set-value</code> to set the secret value. The
<a href="html/libvirt-libvirt-secret.html#virSecretSetValue">
<code>virSecretSetValue</code></a> API may also be used to set
a more secure secret without using printable/readable characters.
</p>
<pre>
# MYSECRET=`printf %s "letmein" | base64`
# virsh secret-set-value 718c71bd-67b5-4a2b-87ec-a24e8ca200dc $MYSECRET
Secret value set
</pre>
</body>
</html>

View File

@@ -24,21 +24,20 @@
(<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
1.2.0</span>) or <code>zfs</code> (<span class="since">since
1.2.8</span>). This corresponds to the
storage backend drivers listed further along in this document.
</p>
<h3><a name="StoragePoolFirst">General metadata</a></h3>
<pre>
&lt;pool type="iscsi"&gt;
&lt;name&gt;virtimages&lt;/name&gt;
&lt;uuid&gt;3e3fce45-4f53-4fa7-bb32-11f34168b82b&lt;/uuid&gt;
&lt;allocation&gt;10000000&lt;/allocation&gt;
&lt;capacity&gt;50000000&lt;/capacity&gt;
&lt;available&gt;40000000&lt;/available&gt;
...</pre>
&lt;pool type="iscsi"&gt;
&lt;name&gt;virtimages&lt;/name&gt;
&lt;uuid&gt;3e3fce45-4f53-4fa7-bb32-11f34168b82b&lt;/uuid&gt;
&lt;allocation&gt;10000000&lt;/allocation&gt;
&lt;capacity&gt;50000000&lt;/capacity&gt;
&lt;available&gt;40000000&lt;/available&gt;
...</pre>
<dl>
<dt><code>name</code></dt>
@@ -76,74 +75,53 @@
</p>
<pre>
...
&lt;source&gt;
&lt;host name="iscsi.example.com"/&gt;
&lt;device path="iqn.2013-06.com.example:iscsi-pool"/&gt;
&lt;auth type='chap' username='myname'&gt;
&lt;secret usage='mycluster_myname'/&gt;
&lt;/auth&gt;
&lt;vendor name="Acme"/&gt;
&lt;product name="model"/&gt;
&lt;/source&gt;
...</pre>
...
&lt;source&gt;
&lt;host name="iscsi.example.com"/&gt;
&lt;device path="iqn.2013-06.com.example:iscsi-pool"/&gt;
&lt;auth type='chap' username='myname'&gt;
&lt;secret usage='mycluster_myname'/&gt;
&lt;/auth&gt;
&lt;vendor name="Acme"/&gt;
&lt;product name="model"/&gt;
&lt;/source&gt;
...</pre>
<pre>
...
&lt;source&gt;
&lt;device path='/dev/mapper/mpatha' part_separator='no'/&gt;
&lt;format type='gpt'/&gt;
&lt;/source&gt;
...</pre>
...
&lt;source&gt;
&lt;adapter type='scsi_host' name='scsi_host1'/&gt;
&lt;/source&gt;
...</pre>
<pre>
...
&lt;source&gt;
&lt;adapter type='scsi_host' name='scsi_host1'/&gt;
&lt;/source&gt;
...</pre>
...
&lt;source&gt;
&lt;adapter type='scsi_host'&gt;
&lt;parentaddr unique_id='1'&gt;
&lt;address domain='0x0000' bus='0x00' slot='0x1f' addr='0x2'/&gt;
&lt;/parentaddr&gt;
&lt;/adapter&gt;
&lt;/source&gt;
...</pre>
<pre>
...
&lt;source&gt;
&lt;adapter type='scsi_host'&gt;
&lt;parentaddr unique_id='1'&gt;
&lt;address domain='0x0000' bus='0x00' slot='0x1f' addr='0x2'/&gt;
&lt;/parentaddr&gt;
&lt;/adapter&gt;
&lt;/source&gt;
...</pre>
<pre>
...
&lt;source&gt;
&lt;adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/&gt;
&lt;/source&gt;
...</pre>
...
&lt;source&gt;
&lt;adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/&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>zfs</code>, <code>vstorage</code>).
<code>iscsi</code>, <code>zfs</code>).
May be repeated multiple times depending on backend driver. Contains
a required attribute <code>path</code> which is either the fully
a single attribute <code>path</code> which is either the fully
qualified path to the block device node or for <code>iscsi</code>
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
may be either "yes" or "no". This attribute is to be used for a
<code>disk</code> pool type using a <code>path</code> to a
device mapper multipath device. Setting the attribute to "yes"
causes libvirt to attempt to generate and find target volume path's
using a "p" separator. The default algorithm used by device mapper
is to add the "p" separator only when the source device path ends
with a number; however, it's possible to configure the devmapper
device to not use 'user_friendly_names' thus creating partitions
with the "p" separator even when the device source path does not
end with a number.
<span class="since">Since 1.3.1</span></p></dd>
<span class="since">Since 0.4.1</span></dd>
<dt><code>dir</code></dt>
<dd>Provides the source for pools backed by directories (pool
types <code>dir</code>, <code>netfs</code>, <code>gluster</code>),
@@ -241,23 +219,6 @@
the scsi_hostN of some existing storage pool.
<span class="since">Since 1.0.4</span>
</dd>
<dt><code>parent_wwnn</code> and <code>parent_wwpn</code></dt>
<dd>Instead of the <code>parent</code> to specify which scsi_host
to use by name, it's possible to provide the wwnn and wwpn of
the parent to be used for the vHBA in order to ensure that
between reboots or after a hardware configuration change that
the scsi_host parent name doesn't change. Both the parent_wwnn
and parent_wwpn must be provided.
<span class="since">Since 3.0.0</span>
</dd>
<dt><code>parent_fabric_wwn</code></dt>
<dd>Instead of the <code>parent</code> to specify which scsi_host
to use by name, it's possible to provide the fabric_wwn on which
the scsi_host exists. This provides flexibility for choosing
a scsi_host that may be available on the fabric rather than
requiring a specific parent by wwnn or wwpn to be available.
<span class="since">Since 3.0.0</span>
</dd>
<dt><code>managed</code></dt>
<dd>An optional attribute to instruct the SCSI storage backend to
manage destroying the vHBA when the pool is destroyed. For
@@ -401,24 +362,32 @@
<code>pool</code> element for some types of pools (pool
types <code>dir</code>, <code>fs</code>, <code>netfs</code>,
<code>logical</code>, <code>disk</code>, <code>iscsi</code>,
<code>scsi</code>, <code>mpath</code>, <code>zfs</code>).
This tag is used to describe the mapping of
<code>scsi</code>, <code>mpath</code>). This tag is used to
describe the mapping of
the storage pool into the host filesystem. It can contain the following
child elements:
</p>
<pre>
...
&lt;target&gt;
&lt;path&gt;/dev/disk/by-path&lt;/path&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
...
&lt;target&gt;
&lt;path&gt;/dev/disk/by-path&lt;/path&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;timestamps&gt;
&lt;atime&gt;1341933637.273190990&lt;/atime&gt;
&lt;mtime&gt;1341930622.047245868&lt;/mtime&gt;
&lt;ctime&gt;1341930622.047245868&lt;/ctime&gt;
&lt;/timestamps&gt;
&lt;encryption type='...'&gt;
...
&lt;/encryption&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
<dl>
<dt><code>path</code></dt>
@@ -432,8 +401,6 @@
guaranteed stable across reboots, since they are allocated on
demand. It is preferable to use a stable location such as one
of the <code>/dev/disk/by-{path|id|uuid|label}</code> locations.
For <code>logical</code> and <code>zfs</code> pool types, a
provided value is ignored and a default path generated.
For a Multipath pool (type <code>mpath</code>), the provided
value is ignored and the default value of "/dev/mapper" is used.
<span class="since">Since 0.4.1</span>
@@ -456,6 +423,24 @@
will be filled with the values used by the existing directory.
<span class="since">Since 1.2.16</span>
</dd>
<dt><code>timestamps</code></dt>
<dd>Provides timing information about the volume. Up to four
sub-elements are present,
where <code>atime</code>, <code>btime</code>, <code>ctime</code>
and <code>mtime</code> hold the access, birth, change and
modification time of the volume, where known. The used time
format is &lt;seconds&gt;.&lt;nanoseconds&gt; since the
beginning of the epoch (1 Jan 1970). If nanosecond resolution
is 0 or otherwise unsupported by the host OS or filesystem,
then the nanoseconds part is omitted. This is a readonly
attribute and is ignored when creating a volume.
<span class="since">Since 0.10.0</span>
</dd>
<dt><code>encryption</code></dt>
<dd>If present, specifies how the volume is encrypted. See
the <a href="formatstorageencryption.html">Storage Encryption</a> page
for more information.
</dd>
</dl>
<h3><a name="StoragePoolExtents">Device extents</a></h3>
@@ -483,7 +468,7 @@
A storage volume will generally be either a file or a device
node; <span class="since">since 1.2.0</span>, an optional
output-only attribute <code>type</code> lists the actual type
(file, block, dir, network, netdir or ploop), which is also available
(file, block, dir, network, or netdir), which is also available
from <code>virStorageVolGetInfo()</code>. The storage volume
XML format is available <span class="since">since 0.4.1</span>
</p>
@@ -491,12 +476,12 @@
<h3><a name="StorageVolFirst">General metadata</a></h3>
<pre>
&lt;volume type='file'&gt;
&lt;name&gt;sparse.img&lt;/name&gt;
&lt;key&gt;/var/lib/xen/images/sparse.img&lt;/key&gt;
&lt;allocation&gt;0&lt;/allocation&gt;
&lt;capacity unit="T"&gt;1&lt;/capacity&gt;
...</pre>
&lt;volume type='file'&gt;
&lt;name&gt;sparse.img&lt;/name&gt;
&lt;key&gt;/var/lib/xen/images/sparse.img&lt;/key&gt;
&lt;allocation&gt;0&lt;/allocation&gt;
&lt;capacity unit="T"&gt;1&lt;/capacity&gt;
...</pre>
<dl>
<dt><code>name</code></dt>
@@ -553,11 +538,6 @@
specified with the same semantics as for <code>allocation</code>
This is compulsory when creating a volume.
<span class="since">Since 0.4.1</span></dd>
<dt><code>physical</code></dt>
<dd>This output only element provides the host physical size of
the target storage volume. The default output <code>unit</code>
will be in bytes.
<span class="since">Since 3.0.0</span></dd>
<dt><code>source</code></dt>
<dd>Provides information about the underlying storage allocation
of the volume. This may not be available for some pool types.
@@ -577,30 +557,22 @@
</p>
<pre>
...
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images/sparse.img&lt;/path&gt;
&lt;format type='qcow2'/&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;timestamps&gt;
&lt;atime&gt;1341933637.273190990&lt;/atime&gt;
&lt;mtime&gt;1341930622.047245868&lt;/mtime&gt;
&lt;ctime&gt;1341930622.047245868&lt;/ctime&gt;
&lt;/timestamps&gt;
&lt;encryption type='...'&gt;
...
&lt;/encryption&gt;
&lt;compat&gt;1.1&lt;/compat&gt;
&lt;nocow/&gt;
&lt;features&gt;
&lt;lazy_refcounts/&gt;
&lt;/features&gt;
&lt;/target&gt;</pre>
...
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images/sparse.img&lt;/path&gt;
&lt;format type='qcow2'/&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;compat&gt;1.1&lt;/compat&gt;
&lt;nocow/&gt;
&lt;features&gt;
&lt;lazy_refcounts/&gt;
&lt;/features&gt;
&lt;/target&gt;</pre>
<dl>
<dt><code>path</code></dt>
@@ -640,24 +612,6 @@
will be filled with the values used by the existing file.
<span class="since">Since 0.4.1</span>
</dd>
<dt><code>timestamps</code></dt>
<dd>Provides timing information about the volume. Up to four
sub-elements are present,
where <code>atime</code>, <code>btime</code>, <code>ctime</code>
and <code>mtime</code> hold the access, birth, change and
modification time of the volume, where known. The used time
format is &lt;seconds&gt;.&lt;nanoseconds&gt; since the
beginning of the epoch (1 Jan 1970). If nanosecond resolution
is 0 or otherwise unsupported by the host OS or filesystem,
then the nanoseconds part is omitted. This is a readonly
attribute and is ignored when creating a volume.
<span class="since">Since 0.10.0</span>
</dd>
<dt><code>encryption</code></dt>
<dd>If present, specifies how the volume is encrypted. See
the <a href="formatstorageencryption.html">Storage Encryption</a> page
for more information.
</dd>
<dt><code>compat</code></dt>
<dd>Specify compatibility level. So far, this is only used for
<code>type='qcow2'</code> volumes. Valid values are <code>0.10</code>
@@ -693,18 +647,18 @@
</p>
<pre>
...
&lt;backingStore&gt;
&lt;path&gt;/var/lib/virt/images/master.img&lt;/path&gt;
&lt;format type='raw'/&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;/backingStore&gt;
&lt;/volume&gt;</pre>
...
&lt;backingStore&gt;
&lt;path&gt;/var/lib/virt/images/master.img&lt;/path&gt;
&lt;format type='raw'/&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;/backingStore&gt;
&lt;/volume&gt;</pre>
<dl>
<dt><code>path</code></dt>
@@ -739,62 +693,46 @@
<h3><a name="exampleFile">File based storage pool</a></h3>
<pre>
&lt;pool type="dir"&gt;
&lt;name&gt;virtimages&lt;/name&gt;
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images&lt;/path&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
&lt;pool type="dir"&gt;
&lt;name&gt;virtimages&lt;/name&gt;
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images&lt;/path&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
<h3><a name="exampleISCSI">iSCSI based storage pool</a></h3>
<pre>
&lt;pool type="iscsi"&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;auth type='chap' username='myuser'&gt;
&lt;secret usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
&lt;/source&gt;
&lt;target&gt;
&lt;path&gt;/dev/disk/by-path&lt;/path&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
&lt;pool type="iscsi"&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;auth type='chap' username='myuser'&gt;
&lt;secret usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
&lt;/source&gt;
&lt;target&gt;
&lt;path&gt;/dev/disk/by-path&lt;/path&gt;
&lt;/target&gt;
&lt;/pool&gt;</pre>
<h3><a name="exampleVol">Storage volume</a></h3>
<pre>
&lt;volume&gt;
&lt;name&gt;sparse.img&lt;/name&gt;
&lt;allocation&gt;0&lt;/allocation&gt;
&lt;capacity unit="T"&gt;1&lt;/capacity&gt;
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images/sparse.img&lt;/path&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;/target&gt;
&lt;/volume&gt;</pre>
<h3><a name="exampleLuks">Storage volume using LUKS</a></h3>
<pre>
&lt;volume&gt;
&lt;name&gt;MyLuks.img&lt;/name&gt;
&lt;capacity unit="G"&gt;5&lt;/capacity&gt;
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images/MyLuks.img&lt;/path&gt;
&lt;format type='raw'/&gt;
&lt;encryption format='luks'&gt;
&lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
&lt;/encryption&gt;
&lt;/target&gt;
&lt;/volume&gt;
</pre>
&lt;volume&gt;
&lt;name&gt;sparse.img&lt;/name&gt;
&lt;allocation&gt;0&lt;/allocation&gt;
&lt;capacity unit="T"&gt;1&lt;/capacity&gt;
&lt;target&gt;
&lt;path&gt;/var/lib/virt/images/sparse.img&lt;/path&gt;
&lt;permissions&gt;
&lt;owner&gt;107&lt;/owner&gt;
&lt;group&gt;107&lt;/group&gt;
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;/target&gt;
&lt;/volume&gt;</pre>
</body>
</html>

View File

@@ -25,14 +25,10 @@
<p>
The <code>encryption</code> tag can currently contain a sequence of
<code>secret</code> tags, each with mandatory attributes <code>type</code>
and either <code>uuid</code> or <code>usage</code>
(<span class="since">since 2.1.0</span>). The only currently defined
value of <code>type</code> is <code>volume</code>. The
<code>uuid</code> is "uuid" of the <code>secret</code> while
<code>usage</code> is the "usage" subelement field.
A secret value can be set in libvirt by the
<a href="html/libvirt-libvirt-secret.html#virSecretSetValue">
<code>virSecretSetValue</code></a> API. Alternatively, if supported
and <code>uuid</code>. The only currently defined value of
<code>type</code> is <code>passphrase</code>. <code>uuid</code>
refers to a secret known to libvirt. libvirt can use a secret value
previously set using <code>virSecretSetValue()</code>, or, if supported
by the particular volume format and driver, automatically generate a
secret value at the time of volume creation, and store it using the
specified <code>uuid</code>.
@@ -40,7 +36,7 @@
<h3><a name="StorageEncryptionDefault">"default" format</a></h3>
<p>
<code>&lt;encryption format="default"/&gt;</code> can be specified only
when creating a qcow volume. If the volume is successfully created, the
when creating a volume. If the volume is successfully created, the
encryption formats, parameters and secrets will be auto-generated by
libvirt and the attached <code>encryption</code> tag will be updated.
The unmodified contents of the <code>encryption</code> tag can be used
@@ -56,112 +52,16 @@
the <code>secret</code> element is not present during volume creation,
a secret is automatically generated and attached to the volume.
</p>
<h3><a name="StorageEncryptionLuks">"luks" format</a></h3>
<p>
The <code>luks</code> format is specific to a luks encrypted volume
and the secret is used in order to either encrypt during volume creation
or decrypt the volume for usage by the domain. A single
<code>&lt;secret type='passphrase'...&gt;</code> element is expected.
<span class="since">Since 2.1.0</span>.
</p>
<p>
For volume creation, it is possible to specify the encryption
algorithm used to encrypt the luks volume. The following two
optional elements may be provided for that purpose. It is hypervisor
dependent as to which algorithms are supported. The default algorithm
used by the storage driver backend when using qemu-img to create
the volume is 'aes-256-cbc' using 'essiv' for initialization vector
generation and 'sha256' hash algorithm for both the cipher and the
initialization vector generation.
</p>
<dl>
<dt><code>cipher</code></dt>
<dd>This element describes the cipher algorithm to be used to either
encrypt or decrypt the luks volume. This element has the following
attributes:
<dl>
<dt><code>name</code></dt>
<dd>The name of the cipher algorithm used for data encryption,
such as 'aes', 'des', 'cast5', 'serpent', 'twofish', etc.
Support of the specific algorithm is storage driver
implementation dependent.</dd>
<dt><code>size</code></dt>
<dd>The size of the cipher in bits, such as '256', '192', '128',
etc. Support of the specific size for a specific cipher is
hypervisor dependent.</dd>
<dt><code>mode</code></dt>
<dd>An optional cipher algorithm mode such as 'cbc', 'xts',
'ecb', etc. Support of the specific cipher mode is
hypervisor dependent.</dd>
<dt><code>hash</code></dt>
<dd>An optional master key hash algorithm such as 'md5', 'sha1',
'sha256', etc. Support of the specific hash algorithm is
hypervisor dependent.</dd>
</dl>
</dd>
<dt><code>ivgen</code></dt>
<dd>This optional element describes the initialization vector
generation algorithm used in conjunction with the
<code>cipher</code>. If the <code>cipher</code> is not provided,
then an error will be generated by the parser.
<dl>
<dt><code>name</code></dt>
<dd>The name of the algorithm, such as 'plain', 'plain64',
'essiv', etc. Support of the specific algorithm is hypervisor
dependent.</dd>
<dt><code>hash</code></dt>
<dd>An optional hash algorithm such as 'md5', 'sha1', 'sha256',
etc. Support of the specific ivgen hash algorithm is hypervisor
dependent.</dd>
</dl>
</dd>
</dl>
<h2><a name="example">Examples</a></h2>
<h2><a name="example">Example</a></h2>
<p>
Here is a simple example, specifying use of the <code>qcow</code> format:
</p>
<pre>
&lt;encryption format='qcow'&gt;
&lt;secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' /&gt;
&lt;/encryption&gt;</pre>
<p>
Assuming a <a href="formatsecret.html#VolumeUsageType">
<code>luks volume type secret</code></a> is already defined,
a simple example specifying use of the <code>luks</code> format
for either volume creation without a specific cipher being defined or
as part of a domain volume definition:
</p>
<pre>
&lt;encryption format='luks'&gt;
&lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
&lt;/encryption&gt;
</pre>
<p>
Here is an example specifying use of the <code>luks</code> format for
a specific cipher algorithm for volume creation:
</p>
<pre>
&lt;volume&gt;
&lt;name&gt;twofish.luks&lt;/name&gt;
&lt;capacity unit='G'&gt;5&lt;/capacity&gt;
&lt;target&gt;
&lt;path&gt;/var/lib/libvirt/images/demo.luks&lt;/path&gt;
&lt;format type='raw'/&gt;
&lt;encryption format='luks'&gt;
&lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
&lt;cipher name='twofish' size='256' mode='cbc' hash='sha256'/&gt;
&lt;ivgen name='plain64' hash='sha256'/&gt;
&lt;/encryption&gt;
&lt;/target&gt;
&lt;/volume&gt;
</pre>
&lt;encryption format='qcow'&gt;
&lt;secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' /&gt;
&lt;/encryption&gt;</pre>
</body>
</html>

View File

@@ -2,8 +2,9 @@ body {
margin: 0em;
padding: 0px;
color: rgb(0,0,0);
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: smaller;
background: #ffffff;
font-family: LibvirtOverpass;
}
p, ul, ol, dl {
@@ -11,75 +12,61 @@ p, ul, ol, dl {
margin: 0px;
}
p {
ol,ul {
margin-left: 3em;
}
ol,ul,dl,p {
margin-top: 1em;
margin-bottom: 1em;
}
ul, ol {
margin-left: 2em;
p:first-line {
margin-right: 1em;
}
dt {
div.body p:first-letter {
font-size: 1.2em;
font-weight: bold;
}
h1,h2,h3,h4,h5,h6 {
font-weight: bold;
margin: 0px;
padding: 0px;
margin-top: 0.5em;
}
div.footer {
margin-top: 1em;
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.6em;
}
h3 {
font-size: 1.4em;
}
h4 {
font-size: 1.2em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: 0.8em;
}
dl dt {
margin-left: 1em;
margin-right: 2em;
}
dt code {
font-weight: bold;
}
dl dd {
margin-left: 2em;
margin-right: 2em;
margin-bottom: 0.5em;
}
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
margin: 0px;
padding: 0px;
margin-bottom: 0.25em;
}
h1 {
margin-top: 0em;
font-size: 1.6em;
}
h2 {
margin-top: 1.0em;
font-size: 1.4em;
}
h3 {
margin-top: 1.0em;
font-size: 1.2em;
}
h4 {
margin-top: 1.0em;
font-size: 1.1em;
}
h5 {
margin-top: 0.75em;
font-size: 1em;
}
h6 {
margin-top: 0.75em;
font-size: 0.8em;
}
code, pre {
font-family: LibvirtOverpassMono;
}
dd code, p code {
background-color: #eeeeee;
}
pre {
font-size: 90%;
}

View File

@@ -8,31 +8,35 @@
<h2><a name="patches">General tips for contributing patches</a></h2>
<ol>
<li>
<p>Discuss any large changes on the mailing list first. Post patches
early and listen to feedback.</p>
</li>
<li>Discuss any large changes on the mailing list first. Post patches
early and listen to feedback.</li>
<li>
<p>Official upstream repository is kept in git
<li>Official upstream repository is kept in git
(<code>git://libvirt.org/libvirt.git</code>) and is browsable
along with other libvirt-related repositories
(e.g. libvirt-python) <a href="http://libvirt.org/git/">online</a>.</p>
</li>
(e.g. libvirt-python) <a href="http://libvirt.org/git/">online</a>.</li>
<li>
<p>Patches to translations are maintained via
<li>Patches to translations are maintained via
the <a href="https://fedora.zanata.org/">zanata project</a>.
If you want to fix a translation in a .po file, join the
appropriate language team. The libvirt release process
automatically pulls the latest version of each translation
file from zanata.</p>
</li>
file from zanata.</li>
<li><p>Post patches using "git send-email", with git rename
<li><p>Post patches in unified diff format, with git rename
detection enabled. You need a one-time setup of:</p>
<pre>
git config diff.renames true
</pre>
<p>After that, a command similar to this should work:</p>
<pre>
diff -urp libvirt.orig/ libvirt.modified/ &gt; libvirt-myfeature.patch
</pre>
<p>
or:
</p>
<pre>
git diff &gt; libvirt-myfeature.patch
</pre>
<p>Also, for code motion patches, you may find that <code>git
diff --patience</code> provides an easier-to-read patch.
@@ -104,11 +108,8 @@
of <code>git bisect</code>, among other things).</p>
</li>
<li>
<p>Make sure your patches apply against libvirt GIT. Developers
only follow GIT and don't care much about released versions.</p>
</li>
<li>Make sure your patches apply against libvirt GIT. Developers
only follow GIT and don't care much about released versions.</li>
<li><p>Run the automated tests on your code before submitting any changes.
In particular, configure with compile warnings set to
-Werror. This is done automatically for a git checkout; from a
@@ -188,19 +189,6 @@
under gdb or Valgrind.
</p>
<p>When running our test suite it may happen that the test result is
nondeterministic because of the test suite relying on a particular file
in the system being accessible or having some specific value. To catch
this kind of errors, the test suite has a module for that prints any
path touched that fulfils constraints described above
into a file. To enable it just set
<code>VIR_TEST_FILE_ACCESS</code> environment variable.
Then <code>VIR_TEST_FILE_ACCESS_OUTPUT</code> environment
variable can alter location where the file is stored.</p>
<pre>
VIR_TEST_FILE_ACCESS=1 VIR_TEST_FILE_ACCESS_OUTPUT="/tmp/file_access.txt" ./qemuxml2argvtest
</pre>
</li>
<li><p>The Valgrind test should produce similar output to
<code>make check</code>. If the output has traces within libvirt
@@ -289,22 +277,8 @@
}
</pre>
</li>
<li>
<p>Update tests and/or documentation, particularly if you are adding
a new feature or changing the output of a program.</p>
</li>
<li>
<p>Don't forget to update the <a href="news.html">release notes</a>
by changing <code>docs/news.xml</code> if your changes are
significant. All user-visible changes, such as adding new XML elements
or fixing all but the most obscure bugs, must be (briefly) described
in a release notes entry; changes that are only relevant to other
libvirt developers, such as code refactoring, don't belong in the
release notes. Note that <code>docs/news.xml</code> should be updated
in its own commit not to get in the way of backports.</p>
</li>
<li>Update tests and/or documentation, particularly if you are adding
a new feature or changing the output of a program.</li>
</ol>
<p>
@@ -314,99 +288,6 @@
Richard Jones' guide to working with open source projects</a>.
</p>
<h2><a name="naming">Naming conventions</a></h2>
<p>
When reading libvirt code, a number of different naming conventions will
be evident due to various changes in thinking over the course of the
project's lifetime. The conventions documented below should be followed
when creating any entirely new files in libvirt. When working on existing
files, while it is desirable to apply these conventions, keeping a
consistent style with existing code in that particular file is generally
more important. The overall guiding principal is that every file, enum,
struct, function, macro and typedef name must have a 'vir' or 'VIR' prefix.
All local scope variable names are exempt, and global variables are exempt,
unless exported in a header file.
</p>
<dl>
<dt>File names</dt>
<dd>
<p>
File naming varies depending on the subdirectory. The preferred
style is to have a 'vir' prefix, followed by a name which matches
the name of the functions / objects inside the file. For example,
a file containing an object 'virHashtable' is stored in files
'virhashtable.c' and 'virhashtable.h'. Sometimes, methods which
would otherwise be declared 'static' need to be exported for use
by a test suite. For this purpose a second header file should be
added with a suffix of 'priv', e.g. 'virhashtablepriv.h'. Use of
underscores in file names is discouraged when using the 'vir'
prefix style. The 'vir' prefix naming applies to src/util,
src/rpc and tests/ directories. Most other directories do not
follow this convention.
</p>
</dd>
<dt>Enum type &amp; field names</dt>
<dd>
<p>
All enums should have a 'vir' prefix in their typedef name,
and each following word should have its first letter in
uppercase. The enum name should match the typedef name with
a leading underscore. The enum member names should be in all
uppercase, and use an underscore to separate each word. The
enum member name prefix should match the enum typedef name.
</p>
<pre>
typedef enum _virSocketType virSocketType;
enum _virSocketType {
VIR_SOCKET_TYPE_IPV4,
VIR_SOCKET_TYPE_IPV6,
};</pre>
</dd>
<dt>Struct type names</dt>
<dd>
<p>
All structs should have a 'vir' prefix in their typedef name,
and each following word should have its first letter in
uppercase. The struct name should be the same as the typedef
name with a leading underscore. A second typedef should be
given for a pointer to the struct with a 'Ptr' suffix.
</p>
<pre>
typedef struct _virHashTable virHashTable;
typedef virHashTable *virHashTablePtr;
struct _virHashTable {
...
};</pre>
</dd>
<dt>Function names</dt>
<dd>
<p>
All functions should have a 'vir' prefix in their name,
followed by one or more words with first letter of each
word capitalized. Underscores should not be used in function
names. If the function is operating on an object, then the
function name prefix should match the object typedef name,
otherwise it should match the filename. Following this
comes the verb / action name, and finally an optional
subject name. For example, given an object 'virHashTable',
all functions should have a name 'virHashTable$VERB' or
'virHashTable$VERB$SUBJECT", e.g. 'virHashTableLookup'
or 'virHashTableGetValue'.
</p>
</dd>
<dt>Macro names</dt>
<dd>
<p>
All macros should have a "VIR" prefix in their name, followed
by one or more uppercase words separated by underscores. The
macro argument names should be in lowercase. Aside from having
a "VIR" prefix there are no common practices for the rest of
the macro name.
</p>
</dd>
</dl>
<h2><a name="indent">Code indentation</a></h2>
<p>

View File

@@ -37,8 +37,6 @@ from docs/hacking.html.in!
<xsl:value-of select="normalize-space(.)"/>
<xsl:text>
</xsl:text>======================
</xsl:template>
@@ -95,13 +93,20 @@ from docs/hacking.html.in!
<xsl:template match="html:p">
<xsl:template match="html:ol|html:ul|html:p">
<xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="html:ol/html:li">(<xsl:value-of select="position()"/>) <xsl:apply-templates/>
<xsl:template match="html:ol/html:li">
<xsl:choose>
<xsl:when test=".//node()[position()=last()]/self::pre">(<xsl:value-of select="position()"/>) <xsl:apply-templates/>
</xsl:when>
<!-- only append two newlines when the last element isn't a pre element -->
<xsl:otherwise>(<xsl:value-of select="position()"/>) <xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -114,10 +119,6 @@ from docs/hacking.html.in!
<xsl:template match="html:li/html:ul/html:li">-- <xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="html:dl/html:dt">*<xsl:apply-templates/>*<xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="html:dl/html:dd"><xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<!-- add newline before nested <ul> -->

View File

@@ -17,10 +17,8 @@
(<span class="since">since 0.8.0</span>)<br/><br/></li>
<li>A QEMU guest is started or stopped
(<span class="since">since 0.8.0</span>)<br/><br/></li>
<li>An LXC guest is started or stopped
<li>An LXC guest is started or stopped
(<span class="since">since 0.8.0</span>)<br/><br/></li>
<li>A libxl-handled Xen guest is started or stopped
(<span class="since">since 2.1.0</span>)<br/><br/></li>
<li>A network is started or stopped or an interface is
plugged/unplugged to/from the network
(<span class="since">since 1.2.2</span>)<br/><br/></li>
@@ -43,7 +41,7 @@
<br/>
<h2><a name="names">Script names</a></h2>
<p>At present, there are five hook scripts that can be called:</p>
<p>At present, there are three hook scripts that can be called:</p>
<ul>
<li><code>/etc/libvirt/hooks/daemon</code><br/><br/>
Executed when the libvirt daemon is started, stopped, or reloads
@@ -52,9 +50,6 @@
Executed when a QEMU guest is started, stopped, or migrated<br/><br/></li>
<li><code>/etc/libvirt/hooks/lxc</code><br /><br/>
Executed when an LXC guest is started or stopped</li>
<li><code>/etc/libvirt/hooks/libxl</code><br/><br/>
Executed when a libxl-handled Xen guest is started, stopped, or
migrated<br/><br/></li>
<li><code>/etc/libvirt/hooks/network</code><br/><br/>
Executed when a network is started or stopped or an
interface is plugged/unplugged to/from the network</li>
@@ -240,50 +235,6 @@
</li>
</ul>
<h5><a name="libxl">/etc/libvirt/hooks/libxl</a></h5>
<ul>
<li>Before a Xen guest is started using libxl driver, the libxl hook
script is called in three locations; if any location fails, the guest
is not started. The first location, <span class="since">since
2.1.0</span>, is before libvirt performs any resource
labeling, and the hook can allocate resources not managed by
libvirt. This is called as:<br/>
<pre>/etc/libvirt/hooks/libxl guest_name prepare begin -</pre>
The second location, available <span class="since">Since
2.1.0</span>, occurs after libvirt has finished labeling
all resources, but has not yet started the guest, called as:<br/>
<pre>/etc/libvirt/hooks/libxl guest_name start begin -</pre>
The third location, <span class="since">2.1.0</span>,
occurs after the domain has successfully started up:<br/>
<pre>/etc/libvirt/hooks/libxl guest_name started begin -</pre>
</li>
<li>When a libxl-handled Xen guest is stopped, the libxl hook script
is called in two locations, to match the startup.
First, <span class="since">since 2.1.0</span>, the hook is
called before libvirt restores any labels:<br/>
<pre>/etc/libvirt/hooks/libxl guest_name stopped end -</pre>
Then, after libvirt has released all resources, the hook is
called again, <span class="since">since 2.1.0</span>, to allow
any additional resource cleanup:<br/>
<pre>/etc/libvirt/hooks/libxl guest_name release end -</pre></li>
<li><span class="since">Since 2.1.0</span>, the libxl hook script
is also called at the beginning of incoming migration. It is called
as: <pre>/etc/libvirt/hooks/libxl guest_name migrate begin -</pre>
with domain XML sent to standard input of the script. In this case,
the script acts as a filter and is supposed to modify the domain
XML and print it out on its standard output. Empty output is
identical to copying the input XML without changing it. In case the
script returns failure or the output XML is not valid, incoming
migration will be canceled. This hook may be used, e.g., to change
location of disk images for incoming domains.</li>
<li><span class="since">Since 2.1.0</span>, the libxl hook script
is also called when the libvirtd daemon restarts and reconnects
to previously running Xen domains. If the script fails, the
existing Xen domains will be killed off. It is called as:
<pre>/etc/libvirt/hooks/libxl guest_name reconnect begin -</pre>
</li>
</ul>
<h5><a name="network">/etc/libvirt/hooks/network</a></h5>
<ul>
<li><span class="since">Since 1.2.2</span>, before a network is started,
@@ -299,8 +250,6 @@
<pre>/etc/libvirt/hooks/network network_name plugged begin -</pre>
Please note, that in this case, the script is passed both network and
domain XMLs on its stdin.</li>
<li>When network is updated, the hook script is called as:<br/>
<pre>/etc/libvirt/hooks/network network_name updated begin -</pre></li>
<li>When the domain from previous case is shutting down, the interface
is unplugged. This leads to another script invocation:<br/>
<pre>/etc/libvirt/hooks/network network_name unplugged begin -</pre>

View File

@@ -4,6 +4,8 @@ use strict;
use warnings;
use File::Find;
use XML::XPath;
use XML::XPath::XMLParser;
die "syntax: $0 SRCDIR\n" unless int(@ARGV) == 1;
@@ -42,91 +44,136 @@ find({
push @srcs, $_ if $_ !~ /vbox_driver\.c/;
}
}, no_chdir => 1}, $srcdir);
my $line;
# Map API functions to the header and documentation files they're in
# so that we can generate proper hyperlinks to their documentation.
#
# The function names are grep'd from the XML output of apibuild.py.
sub getAPIFilenames {
my $filename = shift;
my %files;
my $line;
open FILE, "<", $filename or die "cannot read $filename: $!";
while (defined($line = <FILE>)) {
if ($line =~ /function name='([^']+)' file='([^']+)'/) {
$files{$1} = $2;
}
}
close FILE;
if (keys %files == 0) {
die "No functions found in $filename. Has the apibuild.py output changed?";
}
return \%files;
}
sub parseSymsFile {
my $apisref = shift;
my $prefix = shift;
my $filename = shift;
my $xmlfilename = shift;
my $line;
my $vers;
my $prevvers;
my $filenames = getAPIFilenames($xmlfilename);
open FILE, "<$filename"
or die "cannot read $filename: $!";
while (defined($line = <FILE>)) {
chomp $line;
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
next if $line =~ /^\s*(global|local):/;
if ($line =~ /^\s*${prefix}_(\d+\.\d+\.\d+)\s*{\s*$/) {
if (defined $vers) {
die "malformed syms file";
}
$vers = $1;
} elsif ($line =~ /\s*}\s*;\s*$/) {
if (defined $prevvers) {
die "malformed syms file";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*}\s*${prefix}_(\d+\.\d+\.\d+)\s*;\s*$/) {
if ($1 ne $prevvers) {
die "malformed syms file $1 != $vers";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*(\w+)\s*;\s*$/) {
$$apisref{$1} = {};
$$apisref{$1}->{vers} = $vers;
$$apisref{$1}->{file} = $$filenames{$1};
} else {
die "unexpected data $line\n";
}
}
close FILE;
}
# Get the list of all public APIs and their corresponding version
my %apis;
# Get the list of all public APIs and their corresponding version
parseSymsFile(\%apis, "LIBVIRT", $symslibvirt, "$srcdir/../docs/libvirt-api.xml");
open FILE, "<$symslibvirt"
or die "cannot read $symslibvirt: $!";
my $vers;
my $prevvers;
my $apixpath = XML::XPath->new(filename => "$srcdir/../docs/libvirt-api.xml");
while (defined($line = <FILE>)) {
chomp $line;
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
next if $line =~ /^\s*(global|local):/;
if ($line =~ /^\s*LIBVIRT_(\d+\.\d+\.\d+)\s*{\s*$/) {
if (defined $vers) {
die "malformed syms file";
}
$vers = $1;
} elsif ($line =~ /\s*}\s*;\s*$/) {
if (defined $prevvers) {
die "malformed syms file";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*}\s*LIBVIRT_(\d+\.\d+\.\d+)\s*;\s*$/) {
if ($1 ne $prevvers) {
die "malformed syms file $1 != $vers";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*(\w+)\s*;\s*$/) {
my $file = $apixpath->find("/api/symbols/function[\@name='$1']/\@file");
$apis{$1} = {};
$apis{$1}->{vers} = $vers;
$apis{$1}->{file} = $file;
} else {
die "unexpected data $line\n";
}
}
close FILE;
# And the same for the QEMU specific APIs
parseSymsFile(\%apis, "LIBVIRT_QEMU", $symsqemu, "$srcdir/../docs/libvirt-qemu-api.xml");
open FILE, "<$symsqemu"
or die "cannot read $symsqemu: $!";
$prevvers = undef;
$vers = undef;
$apixpath = XML::XPath->new(filename => "$srcdir/../docs/libvirt-qemu-api.xml");
while (defined($line = <FILE>)) {
chomp $line;
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
next if $line =~ /^\s*(global|local):/;
if ($line =~ /^\s*LIBVIRT_QEMU_(\d+\.\d+\.\d+)\s*{\s*$/) {
if (defined $vers) {
die "malformed syms file";
}
$vers = $1;
} elsif ($line =~ /\s*}\s*;\s*$/) {
if (defined $prevvers) {
die "malformed syms file";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*}\s*LIBVIRT_QEMU_(\d+\.\d+\.\d+)\s*;\s*$/) {
if ($1 ne $prevvers) {
die "malformed syms file $1 != $vers";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*(\w+)\s*;\s*$/) {
my $file = $apixpath->find("/api/symbols/function[\@name='$1']/\@file");
$apis{$1} = {};
$apis{$1}->{vers} = $vers;
$apis{$1}->{file} = $file;
} else {
die "unexpected data $line\n";
}
}
close FILE;
# And the same for the LXC specific APIs
parseSymsFile(\%apis, "LIBVIRT_LXC", $symslxc, "$srcdir/../docs/libvirt-lxc-api.xml");
open FILE, "<$symslxc"
or die "cannot read $symslxc: $!";
$prevvers = undef;
$vers = undef;
$apixpath = XML::XPath->new(filename => "$srcdir/../docs/libvirt-lxc-api.xml");
while (defined($line = <FILE>)) {
chomp $line;
next if $line =~ /^\s*#/;
next if $line =~ /^\s*$/;
next if $line =~ /^\s*(global|local):/;
if ($line =~ /^\s*LIBVIRT_LXC_(\d+\.\d+\.\d+)\s*{\s*$/) {
if (defined $vers) {
die "malformed syms file";
}
$vers = $1;
} elsif ($line =~ /\s*}\s*;\s*$/) {
if (defined $prevvers) {
die "malformed syms file";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*}\s*LIBVIRT_LXC_(\d+\.\d+\.\d+)\s*;\s*$/) {
if ($1 ne $prevvers) {
die "malformed syms file $1 != $vers";
}
$prevvers = $vers;
$vers = undef;
} elsif ($line =~ /\s*(\w+)\s*;\s*$/) {
my $file = $apixpath->find("/api/symbols/function[\@name='$1']/\@file");
$apis{$1} = {};
$apis{$1}->{vers} = $vers;
$apis{$1}->{file} = $file;
} else {
die "unexpected data $line\n";
}
}
close FILE;
# Some special things which aren't public APIs,
@@ -159,8 +206,6 @@ $apis{virDomainMigrateConfirm3Params}->{vers} = "1.1.0";
# and driver struct fields. This lets us later match
# update the driver impls with the public APis.
my $line;
# Group name -> hash of APIs { fields -> api name }
my %groups;
my $ingrp;
@@ -207,30 +252,28 @@ foreach my $src (@srcs) {
open FILE, "<$src" or
die "cannot read $src: $!";
my $groups_regex = join("|", keys %groups);
$ingrp = undef;
my $impl;
while (defined($line = <FILE>)) {
if (!$ingrp) {
# skip non-matching lines early to save time
next if not $line =~ /$groups_regex/;
foreach my $grp (keys %groups) {
if ($line =~ /^\s*(?:static\s+)?$grp\s+(\w+)\s*=\s*{/ ||
$line =~ /^\s*(?:static\s+)?$grp\s+NAME\(\w+\)\s*=\s*{/) {
$ingrp = $grp;
$impl = $src;
if ($line =~ /^\s*(?:static\s+)?($groups_regex)\s+(\w+)\s*=\s*{/ ||
$line =~ /^\s*(?:static\s+)?($groups_regex)\s+NAME\(\w+\)\s*=\s*{/) {
$ingrp = $1;
$impl = $src;
if ($impl =~ m,.*/node_device_(\w+)\.c,) {
$impl = $1;
} else {
$impl =~ s,.*/(\w+?)_((\w+)_)?(\w+)\.c,$1,;
}
if ($impl =~ m,.*/node_device_(\w+)\.c,) {
$impl = $1;
} else {
$impl =~ s,.*/(\w+?)_((\w+)_)?(\w+)\.c,$1,;
if ($groups{$ingrp}->{drivers}->{$impl}) {
die "Group $ingrp already contains $impl";
}
$groups{$ingrp}->{drivers}->{$impl} = {};
}
if ($groups{$ingrp}->{drivers}->{$impl}) {
die "Group $ingrp already contains $impl";
}
$groups{$ingrp}->{drivers}->{$impl} = {};
}
} else {
@@ -334,7 +377,10 @@ print <<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body class="hvsupport">
<head>
<title>libvirt API support matrix</title>
</head>
<body>
<h1>libvirt API support matrix</h1>
<ul id="toc"></ul>

View File

@@ -1,90 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="js/moment.min.js"></script>
<script type="text/javascript" src="js/jquery.rss.min.js"></script>
<script type="text/javascript">
<!--
jQuery(function($) {
$("#planet").rss("http://planet.virt-tools.org/atom.xml", {
ssl: true,
layoutTemplate: '<dl>{entries}</dl>',
entryTemplate: '<dt><a href="{url}">{title}</a></dt><dd>by {author} on {date}</li>',
dateFormat: 'DD MMM YYYY'
})
})
// -->
</script>
</head>
<body class="index">
<body>
<h1>The virtualization API</h1>
<div class="panel">
<h2>Introduction</h2>
<p>
The libvirt project:
</p>
<ul>
<li>is a toolkit to manage virtualization hosts</li>
<li>is accessible from C, Python, Perl, Java and more</li>
<li>is licensed under open source licenses</li>
<li>supports <a href="drvqemu.html">KVM</a>,
<a href="drvqemu.html">QEMU</a>, <a href="drvxen.html">Xen</a>,
<a href="drvvirtuozzo.html">Virtuozzo</a>,
<a href="drvesx.html">VMWare ESX</a>,
<a href="drvlxc.html">LXC</a>,
<a href="drvbhyve.html">BHyve</a> and
<a href="drivers.html">more</a></li>
<li>targets Linux, FreeBSD, <a href="windows.html">Windows</a> and OS-X</li>
<li>is used by many <a href="apps.html">applications</a></li>
</ul>
<p>Recent / forthcoming <a href="news.html">release changes</a></p>
</div>
<h2>libvirt is:</h2>
<div class="panel">
<h2>Quick Links</h2>
<ul>
<li>
A toolkit to interact with the virtualization capabilities
of recent versions of Linux (and other OSes), see our
<a href="goals.html">project goals</a> for details.
</li>
<li>
Free software available under the
<a href="http://www.opensource.org/licenses/lgpl-license.html">GNU
Lesser General Public License</a>.
</li>
<dl>
<dt><a href="contribute.html">New contributors</a></dt>
<dd>Get involved in the libvirt community &amp; student outreach programs</dd>
<li>
A long term stable C API
</li>
<li>
A set of bindings for common languages
</li>
<li>
A <a href="CIM/">CIM provider</a> for the DMTF virtualization schema
</li>
<li>
A <a href="/qpid/">QMF agent</a> for the AMQP/QPid messaging system
</li>
<li>
A <a href="governance.html">technical meritocracy</a>, in which
participants gain influence over a project through recognition
of their contributions.
</li>
</ul>
<dt><a href="securityprocess.html">Security vulnerabilities</a></dt>
<dd>Report vulnerabilities to the libvirt security response team</dd>
<h2>libvirt supports:</h2>
<dt><a href="bugs.html">Bug reporting</a></dt>
<dd>View and report bugs in libvirt packages</dd>
<ul>
<li>
The <a href="http://libvirt.org/drvqemu.html">KVM/QEMU</a> Linux hypervisor
</li>
<li>
The <a href="http://libvirt.org/drvxen.html">Xen</a> hypervisor
on Linux and Solaris hosts.
</li>
<li>
The <a href="http://libvirt.org/drvlxc.html">LXC</a> Linux container system
</li>
<li>
The <a href="http://libvirt.org/drvopenvz.html">OpenVZ</a> Linux container system
</li>
<li>
The <a href="http://libvirt.org/drvuml.html">User Mode Linux</a> paravirtualized kernel
</li>
<li>
The <a href="http://libvirt.org/drvvbox.html">VirtualBox</a> hypervisor
</li>
<li>
The <a href="http://libvirt.org/drvesx.html">VMware ESX and GSX</a> hypervisors
</li>
<li>
The <a href="http://libvirt.org/drvvmware.html">VMware Workstation and Player</a> hypervisors
</li>
<li>
The <a href="http://libvirt.org/drvhyperv.html">Microsoft Hyper-V</a> hypervisor
</li>
<li>
The <a href="http://libvirt.org/drvphyp.html">IBM PowerVM</a> hypervisor
</li>
<li>
The <a href="http://libvirt.org/drvvirtuozzo.html">Virtuozzo</a> hypervisor
</li>
<li>
The <a href="http://libvirt.org/drvbhyve.html">Bhyve</a> hypervisor
</li>
<li>
Virtual networks using bridging, NAT, VEPA and VN-LINK.
</li>
<li>
Storage on IDE/SCSI/USB disks, FibreChannel, LVM, iSCSI, NFS and filesystems
</li>
</ul>
<dt><a href="format.html">XML configuration</a></dt>
<dd>Description of the XML schemas for
<a href="formatdomain.html" shape="rect">domains</a>,
<a href="formatnetwork.html" shape="rect">networks</a>,
<a href="formatnwfilter.html" shape="rect">network filtering</a>,
<a href="formatstorage.html" shape="rect">storage</a>,
<a href="formatstorageencryption.html" shape="rect">storage encryption</a>,
<a href="formatcaps.html" shape="rect">capabilities</a>,
<a href="formatdomaincaps.html" shape="rect">domain capabilities</a>,
<a href="formatnode.html" shape="rect">node devices</a>,
<a href="formatsecret.html" shape="rect">secrets</a>,
<a href="formatsnapshot.html" shape="rect">snapshots</a></dd>
<dt><a href="http://wiki.libvirt.org">Wiki</a></dt>
<dd>Read further community contributed content</dd>
</dl>
</div>
<h2>libvirt provides:</h2>
<div class="panel">
<h2>Blog Planet</h2>
<div id="planet">
</div>
<p>
Read more on the <a href="http://planet.virt-tools.org/">Virt Tools blog planet</a>
</p>
</div>
<br class="clear"/>
<ul>
<li>Remote management using TLS encryption and x509 certificates</li>
<li>Remote management authenticating with Kerberos and SASL</li>
<li>Local access control using PolicyKit</li>
<li>Zero-conf discovery using Avahi multicast-DNS</li>
<li>Management of virtual machines, virtual networks and storage</li>
<li>Portable client API for Linux, Solaris and Windows</li>
</ul>
<p class="image">
<img src="libvirtLogo.png" alt="libvirt Logo"/>
</p>
</body>
</html>

View File

@@ -14,7 +14,6 @@
<li>Introduction to basic rules and guidelines for
<a href="hacking.html">hacking</a> on libvirt code</li>
<li>Guide to adding <a href="api_extension.html">public APIs</a></li>
<li>Insight into libvirt <a href="internals/eventloop.html">event loop and worker pool</a></li>
<li>Approach for <a href="internals/command.html">spawning commands</a>
from libvirt driver code</li>
<li>The libvirt <a href="internals/rpc.html">RPC infrastructure</a></li>

View File

@@ -83,7 +83,7 @@
</p>
<pre>
virCommandPtr cmd = virCommandNew("/usr/bin/dnsmasq");
virCommandPtr cmd = virCommandNew("/usr/bin/dnsmasq");
</pre>
<p>
@@ -100,7 +100,7 @@ virCommandPtr cmd = virCommandNew("/usr/bin/dnsmasq");
</p>
<pre>
virCommandAddArg(cmd, "-strict-order");
virCommandAddArg(cmd, "-strict-order");
</pre>
<p>
@@ -109,7 +109,7 @@ virCommandAddArg(cmd, "-strict-order");
</p>
<pre>
virCommandAddArgPair(cmd, "--conf-file", "/etc/dnsmasq.conf");
virCommandAddArgPair(cmd, "--conf-file", "/etc/dnsmasq.conf");
</pre>
<p>
@@ -118,20 +118,20 @@ virCommandAddArgPair(cmd, "--conf-file", "/etc/dnsmasq.conf");
</p>
<pre>
virCommandAddArgFormat(cmd, "%d", count);
virCommandAddArgFormat(cmd, "%d", count);
</pre>
<p>
To add an entire NULL terminated array of arguments in one go,
To add a entire NULL terminated array of arguments in one go,
there are two options.
</p>
<pre>
const char *const args[] = {
"--strict-order", "--except-interface", "lo", NULL
};
virCommandAddArgSet(cmd, args);
virCommandAddArgList(cmd, "--domain", "localdomain", NULL);
const char *const args[] = {
"--strict-order", "--except-interface", "lo", NULL
};
virCommandAddArgSet(cmd, args);
virCommandAddArgList(cmd, "--domain", "localdomain", NULL);
</pre>
<p>
@@ -140,14 +140,14 @@ virCommandAddArgList(cmd, "--domain", "localdomain", NULL);
</p>
<pre>
const char *const args[] = {
"/usr/bin/dnsmasq",
"--strict-order", "--except-interface",
"lo", "--domain", "localdomain", NULL
};
virCommandPtr cmd1 = virCommandNewArgs(cmd, args);
virCommandPtr cmd2 = virCommandNewArgList("/usr/bin/dnsmasq",
"--domain", "localdomain", NULL);
const char *const args[] = {
"/usr/bin/dnsmasq",
"--strict-order", "--except-interface",
"lo", "--domain", "localdomain", NULL
};
virCommandPtr cmd1 = virCommandNewArgs(cmd, args);
virCommandPtr cmd2 = virCommandNewArgList("/usr/bin/dnsmasq",
"--domain", "localdomain", NULL);
</pre>
<h3><a name="env">Setting up the environment</a></h3>
@@ -163,7 +163,7 @@ virCommandPtr cmd2 = virCommandNewArgList("/usr/bin/dnsmasq",
</p>
<pre>
virCommandAddEnvPassCommon(cmd);
virCommandAddEnvPassCommon(cmd);
</pre>
<p>
@@ -177,8 +177,8 @@ virCommandAddEnvPassCommon(cmd);
</p>
<pre>
virCommandAddEnvPass(cmd, "DISPLAY");
virCommandAddEnvPass(cmd, "XAUTHORITY");
virCommandAddEnvPass(cmd, "DISPLAY");
virCommandAddEnvPass(cmd, "XAUTHORITY");
</pre>
<p>
@@ -187,7 +187,7 @@ virCommandAddEnvPass(cmd, "XAUTHORITY");
</p>
<pre>
virCommandAddEnvPair(cmd, "TERM", "xterm");
virCommandAddEnvPair(cmd, "TERM", "xterm");
</pre>
<p>
@@ -196,7 +196,7 @@ virCommandAddEnvPair(cmd, "TERM", "xterm");
</p>
<pre>
virCommandAddEnvString(cmd, "TERM=xterm");
virCommandAddEnvString(cmd, "TERM=xterm");
</pre>
<h3><a name="misc">Miscellaneous other options</a></h3>
@@ -210,7 +210,7 @@ virCommandAddEnvString(cmd, "TERM=xterm");
</p>
<pre>
virCommandDaemonize(cmd);
virCommandDaemonize(cmd);
</pre>
<p>
@@ -221,7 +221,7 @@ virCommandDaemonize(cmd);
</p>
<pre>
virCommandSetPidFile(cmd, "/var/run/dnsmasq.pid");
virCommandSetPidFile(cmd, "/var/run/dnsmasq.pid");
</pre>
<p>
@@ -240,7 +240,7 @@ virCommandSetPidFile(cmd, "/var/run/dnsmasq.pid");
</p>
<pre>
virCommandClearCaps(cmd);
virCommandClearCaps(cmd);
</pre>
<h3><a name="fds">Managing file handles</a></h3>
@@ -256,13 +256,13 @@ virCommandClearCaps(cmd);
</p>
<pre>
int sharedfd = open("cmd.log", "w+");
int childfd = open("conf.txt", "r");
virCommandPassFD(cmd, sharedfd, 0);
virCommandPassFD(cmd, childfd,
VIR_COMMAND_PASS_FD_CLOSE_PARENT);
if (VIR_CLOSE(sharedfd) &lt; 0)
goto cleanup;
int sharedfd = open("cmd.log", "w+");
int childfd = open("conf.txt", "r");
virCommandPassFD(cmd, sharedfd, 0);
virCommandPassFD(cmd, childfd,
VIR_COMMAND_PASS_FD_CLOSE_PARENT);
if (VIR_CLOSE(sharedfd) &lt; 0)
goto cleanup;
</pre>
<p>
@@ -282,7 +282,7 @@ if (VIR_CLOSE(sharedfd) &lt; 0)
</p>
<pre>
virCommandSetInputFD(cmd, 7);
virCommandSetInputFD(cmd, 7);
</pre>
<p>
@@ -291,10 +291,10 @@ virCommandSetInputFD(cmd, 7);
</p>
<pre>
int outfd = open("out.log", "w+");
int errfd = open("err.log", "w+");
virCommandSetOutputFD(cmd, &amp;outfd);
virCommandSetErrorFD(cmd, &amp;errfd);
int outfd = open("out.log", "w+");
int errfd = open("err.log", "w+");
virCommandSetOutputFD(cmd, &amp;outfd);
virCommandSetErrorFD(cmd, &amp;errfd);
</pre>
<p>
@@ -304,10 +304,10 @@ virCommandSetErrorFD(cmd, &amp;errfd);
</p>
<pre>
int outfd = -1;
int errfd = -1
virCommandSetOutputFD(cmd, &amp;outfd);
virCommandSetErrorFD(cmd, &amp;errfd);
int outfd = -1;
int errfd = -1
virCommandSetOutputFD(cmd, &amp;outfd);
virCommandSetErrorFD(cmd, &amp;errfd);
</pre>
<p>
@@ -326,7 +326,7 @@ virCommandSetErrorFD(cmd, &amp;errfd);
</p>
<pre>
virCommandNonblockingFDs(cmd);
virCommandNonblockingFDs(cmd);
</pre>
<h3><a name="buffers">Feeding &amp; capturing strings to/from the child</a></h3>
@@ -350,8 +350,8 @@ virCommandNonblockingFDs(cmd);
</p>
<pre>
const char *input = "Hello World\n";
virCommandSetInputBuffer(cmd, input);
const char *input = "Hello World\n";
virCommandSetInputBuffer(cmd, input);
</pre>
<p>
@@ -362,9 +362,9 @@ virCommandSetInputBuffer(cmd, input);
</p>
<pre>
char *output = NULL, *errors = NULL;
virCommandSetOutputBuffer(cmd, &amp;output);
virCommandSetErrorBuffer(cmd, &amp;errors);
char *output = NULL, *errors = NULL;
virCommandSetOutputBuffer(cmd, &amp;output);
virCommandSetErrorBuffer(cmd, &amp;errors);
</pre>
<p>
@@ -392,7 +392,7 @@ virCommandSetErrorBuffer(cmd, &amp;errors);
</p>
<pre>
virCommandSetWorkingDirectory(cmd, LOCALSTATEDIR);
virCommandSetWorkingDirectory(cmd, LOCALSTATEDIR);
</pre>
<h3><a name="hooks">Any additional hooks</a></h3>
@@ -406,7 +406,7 @@ virCommandSetWorkingDirectory(cmd, LOCALSTATEDIR);
</p>
<pre>
virCommandSetPreExecHook(cmd, hook, opaque);
virCommandSetPreExecHook(cmd, hook, opaque);
</pre>
<h3><a name="logging">Logging commands</a></h3>
@@ -418,20 +418,20 @@ virCommandSetPreExecHook(cmd, hook, opaque);
</p>
<pre>
int logfd = ...;
char *timestamp = virTimestamp();
char *string = NULL;
int logfd = ...;
char *timestamp = virTimestamp();
char *string = NULL;
dprintf(logfd, "%s: ", timestamp);
VIR_FREE(timestamp);
virCommandWriteArgLog(cmd, logfd);
dprintf(logfd, "%s: ", timestamp);
VIR_FREE(timestamp);
virCommandWriteArgLog(cmd, logfd);
string = virCommandToString(cmd);
if (string)
VIR_DEBUG("about to run %s", string);
VIR_FREE(string);
if (virCommandRun(cmd, NULL) &lt; 0)
return -1;
string = virCommandToString(cmd);
if (string)
VIR_DEBUG("about to run %s", string);
VIR_FREE(string);
if (virCommandRun(cmd, NULL) &lt; 0)
return -1;
</pre>
<h3><a name="sync">Running commands synchronously</a></h3>
@@ -443,8 +443,8 @@ if (virCommandRun(cmd, NULL) &lt; 0)
</p>
<pre>
if (virCommandRun(cmd, NULL) &lt; 0)
return -1;
if (virCommandRun(cmd, NULL) &lt; 0)
return -1;
</pre>
<p>
@@ -465,19 +465,19 @@ if (virCommandRun(cmd, NULL) &lt; 0)
</p>
<pre>
int status;
if (virCommandRun(cmd, &amp;status) &lt; 0)
return -1;
if (status == 1) {
...do stuff...
}
int status;
if (virCommandRun(cmd, &amp;status) &lt; 0)
return -1;
if (status == 1) {
...do stuff...
}
virCommandRawStatus(cmd2);
if (virCommandRun(cmd2, &amp;status) &lt; 0)
return -1;
if (WIFEXITED(status) &amp;&amp; WEXITSTATUS(status) == 1) {
...do stuff...
}
virCommandRawStatus(cmd2);
if (virCommandRun(cmd2, &amp;status) &lt; 0)
return -1;
if (WIFEXITED(status) &amp;&amp; WEXITSTATUS(status) == 1) {
...do stuff...
}
</pre>
<h3><a name="async">Running commands asynchronously</a></h3>
@@ -490,19 +490,19 @@ if (WIFEXITED(status) &amp;&amp; WEXITSTATUS(status) == 1) {
</p>
<pre>
pid_t pid;
if (virCommandRunAsync(cmd, &amp;pid) &lt; 0)
return -1;
pid_t pid;
if (virCommandRunAsync(cmd, &amp;pid) &lt; 0)
return -1;
... do something while pid is running ...
... do something while pid is running ...
int status;
if (virCommandWait(cmd, &amp;status) &lt; 0)
return -1;
int status;
if (virCommandWait(cmd, &amp;status) &lt; 0)
return -1;
if (WEXITSTATUS(status)...) {
..do stuff..
}
if (WEXITSTATUS(status)...) {
..do stuff..
}
</pre>
<p>
@@ -540,7 +540,7 @@ if (WEXITSTATUS(status)...) {
</p>
<pre>
virCommandFree(cmd);
virCommandFree(cmd);
</pre>
<p>

View File

@@ -1,106 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Libvirt's event loop</h1>
<ul id="toc"></ul>
<p>
This page describes the event loop approach used in
libvirt. Both server and client.
</p>
<h2><a name="event_loop">Event driven programming</a></h2>
<p>Traditionally, a program simply ran once, then terminated.
This type of program was very common in the early days of
computing, and lacked any form of user interactivity. This is
still used frequently, particularly in small one purpose
programs.</p>
<p>However, that approach is not suitable for all the types
of applications. For instance graphical applications spend
most of their run time waiting for an input from user. Only
after it happened (in our example a button was clicked, a key
pressed, etc.) an event is generated to which they respond
by executing desired function. If generalized, this is how
many long running programs (daemons) work. Even those who are
not waiting for direct user input and have no graphical
interface. Such as Libvirt.</p>
<img alt="event loop" src="http://libvirt.org/git/?p=libvirt-media.git;a=blob_plain;f=png/event_loop_simple.png;hb=HEAD"/>
<p>In Libvirt this approach is used in combination with
<code>poll(2)</code> as all the communication with its
clients (and domains it manages too) happens through sockets.
Therefore whenever new client connects, it is given exclusive
file descriptor which is then watched for incoming events,
e.g. messages. </p>
<h2><a name="api">The event loop API</a></h2>
<p>To work with event loop from our code we have plenty of
APIs.</p>
<ul>
<li><code>virEventAddHandle</code>: Registers a
callback for monitoring file handle events.</li>
<li><code>virEventUpdateHandle</code>: Change set of events
monitored file handle is being watched for.</li>
<li><code>virEventRemoveHandle</code>: Unregisters
previously registered file handle so that it is no
longer monitored for any events.</li>
<li><code>virEventAddTimeout</code>: Registers a
callback for timer event.</li>
<li><code>virEventUpdateTimeout</code>: Changes frequency
for a timer.</li>
<li><code>virEventRemoveTimeout</code>: Unregisters
a timer.</li>
</ul>
<p>For more information on these APIs continue reading <a
href="../html/libvirt-libvirt-event.html">here</a>.</p>
<h2><a name="worker_pool">Worker pool</a></h2>
<p>Looking back at the image above we can see one big
limitation. While processing a message event loop is blocked
and for an outside observer unresponsive. This is not
acceptable for Libvirt. Therefore we have came up with the
following solution.</p>
<img alt="event loop" src="http://libvirt.org/git/?p=libvirt-media.git;a=blob_plain;f=png/event_loop_worker.png;hb=HEAD"/>
<p>The event loop does only necessary minimum and hand over
message processing to another thread. In fact, there can be
as many processing threads as configured increasing
processing power.</p>
<p>To break this high level description into smaller pieces,
here is what happens when user calls an API:</p>
<ol>
<li>User (or management application) calls a Libvirt API.
Depending on the connection URI, this may or may not
involve server. Well, for the sake of our
demonstration we assume the former.</li>
<li>Remote driver encodes the API among it's arguments
into an <a href="rpc.html">RPC message</a> and sends
it to the server.</li>
<li>Here, server is waiting in <code>poll(2)</code> for
an event, like incoming message.</li>
<li>As soon as the first bytes of message are received,
even loop wakes up and server starts reading the
whole message.</li>
<li>Once fully read, the event loop notifies threads
known as worker threads from which one picks the incoming
message, decodes and process it.</li>
<li>As soon as API execution is finished, a reply is sent
to the client.</li>
</ol>
<p>In case that there's no free worker to process an incoming
message in step 5, message is placed at the end of a message
queue and is processed in next iteration.</p>
</body>
</html>

View File

@@ -122,7 +122,7 @@
</p>
<pre>
#include &lt;libvirt/plugins/lock_manager.h&gt;
#include &lt;libvirt/plugins/lock_manager.h&gt;
</pre>
<p>
@@ -141,7 +141,7 @@
</p>
<pre>
lockManager="sanlock"
lockManager="sanlock"
</pre>
<p>
@@ -169,40 +169,40 @@ lockManager="sanlock"
</p>
<pre>
virLockManagerParam params[] = {
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
.key = "uuid",
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
.key = "name",
.value = { .str = dom->def->name },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "id",
.value = { .i = dom->def->id },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "pid",
.value = { .i = dom->pid },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_CSTRING,
.key = "uri",
.value = { .cstr = driver->uri },
},
};
mgr = virLockManagerNew(lockPlugin,
VIR_LOCK_MANAGER_TYPE_DOMAIN,
ARRAY_CARDINALITY(params),
params,
0)));
virLockManagerParam params[] = {
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
.key = "uuid",
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
.key = "name",
.value = { .str = dom->def->name },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "id",
.value = { .i = dom->def->id },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "pid",
.value = { .i = dom->pid },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_CSTRING,
.key = "uri",
.value = { .cstr = driver->uri },
},
};
mgr = virLockManagerNew(lockPlugin,
VIR_LOCK_MANAGER_TYPE_DOMAIN,
ARRAY_CARDINALITY(params),
params,
0)));
foreach (initial disks)
virLockManagerAddResource(mgr,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
$path, 0, NULL, $flags);
foreach (initial disks)
virLockManagerAddResource(mgr,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
$path, 0, NULL, $flags);
if (virLockManagerAcquire(lock, NULL, 0) &lt; 0);
...abort...
if (virLockManagerAcquire(lock, NULL, 0) &lt; 0);
...abort...
</pre>
<h3><a name="usageLockAttach">Lock release</a></h3>
@@ -214,40 +214,40 @@ if (virLockManagerAcquire(lock, NULL, 0) &lt; 0);
</p>
<pre>
char *state = NULL;
virLockManagerParam params[] = {
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
.key = "uuid",
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
.key = "name",
.value = { .str = dom->def->name },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "id",
.value = { .i = dom->def->id },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "pid",
.value = { .i = dom->pid },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_CSTRING,
.key = "uri",
.value = { .cstr = driver->uri },
},
};
mgr = virLockManagerNew(lockPlugin,
VIR_LOCK_MANAGER_TYPE_DOMAIN,
ARRAY_CARDINALITY(params),
params,
0)));
char *state = NULL;
virLockManagerParam params[] = {
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UUID,
.key = "uuid",
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_STRING,
.key = "name",
.value = { .str = dom->def->name },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "id",
.value = { .i = dom->def->id },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_UINT,
.key = "pid",
.value = { .i = dom->pid },
},
{ .type = VIR_LOCK_MANAGER_PARAM_TYPE_CSTRING,
.key = "uri",
.value = { .cstr = driver->uri },
},
};
mgr = virLockManagerNew(lockPlugin,
VIR_LOCK_MANAGER_TYPE_DOMAIN,
ARRAY_CARDINALITY(params),
params,
0)));
foreach (initial disks)
virLockManagerAddResource(mgr,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
$path, 0, NULL, $flags);
foreach (initial disks)
virLockManagerAddResource(mgr,
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK,
$path, 0, NULL, $flags);
virLockManagerRelease(mgr, &amp; state, 0);
virLockManagerRelease(mgr, &amp; state, 0);
</pre>
<p>

View File

@@ -210,13 +210,13 @@
</p>
<pre>
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
</pre>
<h4><a name="wireexamplescallerr">Method call with error</a></h4>
@@ -226,13 +226,13 @@ C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
</p>
<pre>
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+--------------------------+
C &lt;-- |48| 8 | 1 | 3 | 2 | 1 | 0 | .o.oOo.o.oOo.o.oOo.o.oOo | &lt;-- S (error)
+--+-----------------------+--------------------------+
+--+-----------------------+--------------------------+
C &lt;-- |48| 8 | 1 | 3 | 2 | 1 | 0 | .o.oOo.o.oOo.o.oOo.o.oOo | &lt;-- S (error)
+--+-----------------------+--------------------------+
</pre>
<h4><a name="wireexamplescallup">Method call with upload stream</a></h4>
@@ -243,33 +243,33 @@ C &lt;-- |48| 8 | 1 | 3 | 2 | 1 | 0 | .o.oOo.o.oOo.o.oOo.o.oOo | &lt;-- S (er
</p>
<pre>
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
...
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+
C --&gt; |24| 8 | 1 | 3 | 3 | 1 | 0 | --&gt; S (stream finish)
+--+-----------------------+
+--+-----------------------+
C &lt;-- |24| 8 | 1 | 3 | 3 | 1 | 0 | &lt;-- S (stream finish)
+--+-----------------------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
...
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+
C --&gt; |24| 8 | 1 | 3 | 3 | 1 | 0 | --&gt; S (stream finish)
+--+-----------------------+
+--+-----------------------+
C &lt;-- |24| 8 | 1 | 3 | 3 | 1 | 0 | &lt;-- S (stream finish)
+--+-----------------------+
</pre>
<h4><a name="wireexamplescallbi">Method call bidirectional stream</a></h4>
@@ -280,80 +280,80 @@ C &lt;-- |24| 8 | 1 | 3 | 3 | 1 | 0 | &lt;-- S (stream finish)
</p>
<pre>
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
..
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+
C --&gt; |24| 8 | 1 | 3 | 3 | 1 | 0 | --&gt; S (stream finish)
+--+-----------------------+
+--+-----------------------+
C &lt;-- |24| 8 | 1 | 3 | 3 | 1 | 0 | &lt;-- S (stream finish)
+--+-----------------------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C &lt;-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | &lt;-- S (stream data down)
+--+-----------------------+-------------....-------+
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
..
+--+-----------------------+-------------....-------+
C --&gt; |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --&gt; S (stream data up)
+--+-----------------------+-------------....-------+
+--+-----------------------+
C --&gt; |24| 8 | 1 | 3 | 3 | 1 | 0 | --&gt; S (stream finish)
+--+-----------------------+
+--+-----------------------+
C &lt;-- |24| 8 | 1 | 3 | 3 | 1 | 0 | &lt;-- S (stream finish)
+--+-----------------------+
</pre>
<h4><a name="wireexamplescallmany">Method calls overlapping</a></h4>
<pre>
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call 1)
+--+-----------------------+-----------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 2 | 0 | .o.oOo.o. | --&gt; S (call 2)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 2 | 0 | .o.oOo | &lt;-- S (reply 2)
+--+-----------------------+--------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 3 | 0 | .o.oOo.o. | --&gt; S (call 3)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 3 | 0 | .o.oOo | &lt;-- S (reply 3)
+--+-----------------------+--------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 4 | 0 | .o.oOo.o. | --&gt; S (call 4)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply 1)
+--+-----------------------+--------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 4 | 0 | .o.oOo | &lt;-- S (reply 4)
+--+-----------------------+--------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --&gt; S (call 1)
+--+-----------------------+-----------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 2 | 0 | .o.oOo.o. | --&gt; S (call 2)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 2 | 0 | .o.oOo | &lt;-- S (reply 2)
+--+-----------------------+--------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 3 | 0 | .o.oOo.o. | --&gt; S (call 3)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 3 | 0 | .o.oOo | &lt;-- S (reply 3)
+--+-----------------------+--------+
+--+-----------------------+-----------+
C --&gt; |38| 8 | 1 | 3 | 0 | 4 | 0 | .o.oOo.o. | --&gt; S (call 4)
+--+-----------------------+-----------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply 1)
+--+-----------------------+--------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 4 | 0 | .o.oOo | &lt;-- S (reply 4)
+--+-----------------------+--------+
</pre>
<h4><a name="wireexamplescallfd">Method call with passed FD</a></h4>
@@ -368,13 +368,13 @@ C &lt;-- |32| 8 | 1 | 3 | 1 | 4 | 0 | .o.oOo | &lt;-- S (reply 4)
</p>
<pre>
+--+-----------------------+---------------+-------+
C --&gt; |44| 8 | 1 | 3 | 0 | 1 | 0 | 2 | .o.oOo.o. | 0 | 0 | --&gt; S (call)
+--+-----------------------+---------------+-------+
+--+-----------------------+---------------+-------+
C --&gt; |44| 8 | 1 | 3 | 0 | 1 | 0 | 2 | .o.oOo.o. | 0 | 0 | --&gt; S (call)
+--+-----------------------+---------------+-------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
+--+-----------------------+--------+
C &lt;-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | &lt;-- S (reply)
+--+-----------------------+--------+
</pre>

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