mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-09-22 13:45:17 +03:00
Compare commits
1 Commits
v0.7.5
...
LIBXEN_FIR
Author | SHA1 | Date | |
---|---|---|---|
|
9f25f7f0db |
47
.gitignore
vendored
47
.gitignore
vendored
@@ -1,47 +0,0 @@
|
||||
*.a
|
||||
*.o
|
||||
*~
|
||||
.git
|
||||
.git-module-status
|
||||
ABOUT-NLS
|
||||
COPYING
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.rpath
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
coverage
|
||||
cscope.files
|
||||
cscope.out
|
||||
libtool
|
||||
libvirt-*.tar.gz
|
||||
libvirt.pc
|
||||
libvirt.spec
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
mingw32-libvirt.spec
|
||||
mkinstalldirs
|
||||
results.log
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
update.log
|
||||
tests/*.log
|
||||
/GNUmakefile
|
||||
/maint.mk
|
||||
gnulib/
|
||||
*.orig
|
||||
*.rej
|
||||
*#*#
|
||||
*.#*#
|
||||
ChangeLog
|
||||
NEWS
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "gnulib"]
|
||||
path = .gnulib
|
||||
url = git://git.sv.gnu.org/gnulib.git
|
1
.gnulib
1
.gnulib
Submodule .gnulib deleted from 3fd9a2df88
298
.hgignore
298
.hgignore
@@ -1,298 +0,0 @@
|
||||
syntax: glob
|
||||
*.a
|
||||
*.o
|
||||
*~
|
||||
.git
|
||||
ABOUT-NLS
|
||||
COPYING
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
build-aux/compile
|
||||
build-aux/config.guess
|
||||
build-aux/config.rpath
|
||||
build-aux/config.sub
|
||||
build-aux/depcomp
|
||||
build-aux/install-sh
|
||||
build-aux/ltmain.sh
|
||||
build-aux/missing
|
||||
build-aux/mkinstalldirs
|
||||
build-aux/mktempd
|
||||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.rpath
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
coverage
|
||||
docs/.memdump
|
||||
docs/Makefile
|
||||
docs/Makefile.in
|
||||
docs/apibuild.pyc
|
||||
docs/devhelp/Makefile
|
||||
docs/devhelp/Makefile.in
|
||||
docs/devhelp/libvirt.devhelp
|
||||
docs/examples/.deps
|
||||
docs/examples/.libs
|
||||
docs/examples/.memdump
|
||||
docs/examples/Makefile
|
||||
docs/examples/Makefile.in
|
||||
docs/examples/info1
|
||||
docs/examples/python/Makefile
|
||||
docs/examples/python/Makefile.in
|
||||
docs/examples/suspend
|
||||
docs/schemas/Makefile
|
||||
docs/schemas/Makefile.in
|
||||
examples/domain-events/events-c/*.exe
|
||||
examples/domain-events/events-c/.deps
|
||||
examples/domain-events/events-c/.libs
|
||||
examples/domain-events/events-c/Makefile
|
||||
examples/domain-events/events-c/Makefile.in
|
||||
examples/domain-events/events-c/event-test
|
||||
examples/hellolibvirt/.deps
|
||||
examples/hellolibvirt/.libs
|
||||
examples/hellolibvirt/Makefile
|
||||
examples/hellolibvirt/Makefile.in
|
||||
examples/hellolibvirt/hellolibvirt
|
||||
gnulib/lib/*.la
|
||||
gnulib/lib/*.lo
|
||||
gnulib/lib/.deps
|
||||
gnulib/lib/.libs
|
||||
gnulib/lib/Makefile
|
||||
gnulib/lib/Makefile.in
|
||||
gnulib/lib/alloca.h
|
||||
gnulib/lib/arpa/inet.h
|
||||
gnulib/lib/arpa_inet.h
|
||||
gnulib/lib/errno.h
|
||||
gnulib/lib/float.h
|
||||
gnulib/lib/netdb.h
|
||||
gnulib/lib/netinet/in.h
|
||||
gnulib/lib/netinet_in.h
|
||||
gnulib/lib/poll.h
|
||||
gnulib/lib/stdbool.h
|
||||
gnulib/lib/stdint.h
|
||||
gnulib/lib/stdio.h
|
||||
gnulib/lib/stdlib.h
|
||||
gnulib/lib/string.h
|
||||
gnulib/lib/sys/select.h
|
||||
gnulib/lib/sys/socket.h
|
||||
gnulib/lib/sys/stat.h
|
||||
gnulib/lib/sys/time.h
|
||||
gnulib/lib/sys_ioctl.h
|
||||
gnulib/lib/sys_select.h
|
||||
gnulib/lib/sys_socket.h
|
||||
gnulib/lib/sys_stat.h
|
||||
gnulib/lib/sys_time.h
|
||||
gnulib/lib/time.h
|
||||
gnulib/lib/unistd.h
|
||||
gnulib/lib/wchar.h
|
||||
gnulib/tests/.deps
|
||||
gnulib/tests/.libs
|
||||
gnulib/tests/Makefile
|
||||
gnulib/tests/Makefile.in
|
||||
gnulib/tests/sys
|
||||
gnulib/tests/test-EOVERFLOW
|
||||
gnulib/tests/test-alloca-opt
|
||||
gnulib/tests/test-arpa_inet
|
||||
gnulib/tests/test-c-ctype
|
||||
gnulib/tests/test-errno
|
||||
gnulib/tests/test-fseeko
|
||||
gnulib/tests/test-getaddrinfo
|
||||
gnulib/tests/test-getdelim
|
||||
gnulib/tests/test-gethostname
|
||||
gnulib/tests/test-getline
|
||||
gnulib/tests/test-gettimeofday
|
||||
gnulib/tests/test-lseek
|
||||
gnulib/tests/test-lstat
|
||||
gnulib/tests/test-netdb
|
||||
gnulib/tests/test-netinet_in
|
||||
gnulib/tests/test-perror
|
||||
gnulib/tests/test-poll
|
||||
gnulib/tests/test-random_r
|
||||
gnulib/tests/test-snprintf
|
||||
gnulib/tests/test-sockets
|
||||
gnulib/tests/test-stdbool
|
||||
gnulib/tests/test-stdint
|
||||
gnulib/tests/test-stdio
|
||||
gnulib/tests/test-stdlib
|
||||
gnulib/tests/test-strerror
|
||||
gnulib/tests/test-string
|
||||
gnulib/tests/test-sys_select
|
||||
gnulib/tests/test-sys_socket
|
||||
gnulib/tests/test-sys_stat
|
||||
gnulib/tests/test-sys_time
|
||||
gnulib/tests/test-time
|
||||
gnulib/tests/test-unistd
|
||||
gnulib/tests/test-vasnprintf
|
||||
gnulib/tests/test-vasprintf
|
||||
gnulib/tests/test-wchar
|
||||
include/Makefile
|
||||
include/Makefile.in
|
||||
include/libvirt/Makefile
|
||||
include/libvirt/Makefile.in
|
||||
libtool
|
||||
libvirt-*.tar.gz
|
||||
libvirt.pc
|
||||
libvirt.spec
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
m4/Makefile
|
||||
m4/Makefile.in
|
||||
m4/acinclude.m4
|
||||
m4/aclocal.m4
|
||||
m4/codeset.m4
|
||||
m4/gettext.m4
|
||||
m4/glibc21.m4
|
||||
m4/iconv.m4
|
||||
m4/intdiv0.m4
|
||||
m4/intmax.m4
|
||||
m4/inttypes-pri.m4
|
||||
m4/inttypes.m4
|
||||
m4/inttypes_h.m4
|
||||
m4/isc-posix.m4
|
||||
m4/lcmessage.m4
|
||||
m4/lib-ld.m4
|
||||
m4/lib-link.m4
|
||||
m4/lib-prefix.m4
|
||||
m4/libtool.m4
|
||||
m4/longdouble.m4
|
||||
m4/longlong.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
m4/nls.m4
|
||||
m4/po.m4
|
||||
m4/printf-posix.m4
|
||||
m4/progtest.m4
|
||||
m4/signed.m4
|
||||
m4/size_max.m4
|
||||
m4/stdint_h.m4
|
||||
m4/uintmax_t.m4
|
||||
m4/ulonglong.m4
|
||||
m4/wchar_t.m4
|
||||
m4/wint_t.m4
|
||||
m4/xsize.m4
|
||||
mingw32-libvirt.spec
|
||||
mkinstalldirs
|
||||
po/*.gmo
|
||||
po/Makefile
|
||||
po/Makefile.in
|
||||
po/Makefile.in.in
|
||||
po/Makevars.template
|
||||
po/POTFILES
|
||||
po/Rules-quot
|
||||
po/boldquot.sed
|
||||
po/en@boldquot.header
|
||||
po/en@quot.header
|
||||
po/insert-header.sin
|
||||
po/quot.sed
|
||||
po/remove-potcdate.sed
|
||||
po/remove-potcdate.sin
|
||||
po/stamp-po
|
||||
proxy/.deps
|
||||
proxy/.libs
|
||||
proxy/Makefile
|
||||
proxy/Makefile.in
|
||||
proxy/libvirt_proxy
|
||||
python/*.la
|
||||
python/*.lo
|
||||
python/*.loT
|
||||
python/*.pyc
|
||||
python/.deps
|
||||
python/.libs
|
||||
python/Makefile
|
||||
python/Makefile.in
|
||||
python/gen_prog
|
||||
python/generated.stamp
|
||||
python/libvirt-export.c
|
||||
python/libvirt-py.[ch]
|
||||
python/libvirt.py
|
||||
python/libvirtclass.py
|
||||
python/libvirtclass.txt
|
||||
python/tests/Makefile
|
||||
python/tests/Makefile.in
|
||||
qemud/*.gcda
|
||||
qemud/*.gcno
|
||||
qemud/*.la
|
||||
qemud/*.lo
|
||||
qemud/.deps
|
||||
qemud/.libs
|
||||
qemud/Makefile
|
||||
qemud/Makefile.in
|
||||
qemud/libvirt_qemud
|
||||
qemud/libvirtd
|
||||
qemud/libvirtd.init
|
||||
qemud/libvirtd.logrotate
|
||||
results.log
|
||||
src/*.cov
|
||||
src/*.exe
|
||||
src/*.gcda
|
||||
src/*.gcno
|
||||
src/*.gcov
|
||||
src/*.i
|
||||
src/*.la
|
||||
src/*.lo
|
||||
src/*.loT
|
||||
src/*.s
|
||||
src/.deps
|
||||
src/.libs
|
||||
src/Makefile
|
||||
src/Makefile.in
|
||||
src/libvirt.syms
|
||||
src/libvirt_lxc
|
||||
src/libvirt_parthelper
|
||||
src/virsh
|
||||
src/virsh-net-edit.c
|
||||
src/virsh-pool-edit.c
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
tests/*.exe
|
||||
tests/*.gcda
|
||||
tests/*.gcno
|
||||
tests/.deps
|
||||
tests/.libs
|
||||
tests/Makefile
|
||||
tests/Makefile.in
|
||||
tests/confdata/Makefile
|
||||
tests/confdata/Makefile.in
|
||||
tests/conftest
|
||||
tests/eventtest
|
||||
tests/nodedevxml2xmltest
|
||||
tests/nodeinfotest
|
||||
tests/object-locking
|
||||
tests/object-locking-files.txt
|
||||
tests/object-locking.cmi
|
||||
tests/object-locking.cmx
|
||||
tests/qemuargv2xmltest
|
||||
tests/qemuhelptest
|
||||
tests/qemuxml2argvtest
|
||||
tests/qemuxml2xmltest
|
||||
tests/qparamtest
|
||||
tests/reconnect
|
||||
tests/seclabeltest
|
||||
tests/sexpr2xmldata/Makefile
|
||||
tests/sexpr2xmldata/Makefile.in
|
||||
tests/sexpr2xmltest
|
||||
tests/statstest
|
||||
tests/virshtest
|
||||
tests/xencapsdata/Makefile
|
||||
tests/xencapsdata/Makefile.in
|
||||
tests/xencapstest
|
||||
tests/xmconfigdata/Makefile
|
||||
tests/xmconfigdata/Makefile.in
|
||||
tests/xmconfigtest
|
||||
tests/xml2sexprdata/Makefile
|
||||
tests/xml2sexprdata/Makefile.in
|
||||
tests/xml2sexprtest
|
||||
tools/Makefile
|
||||
tools/Makefile.in
|
||||
tools/virt-xml-validate
|
||||
tools/virt-xml-validate.1
|
||||
update.log
|
@@ -1 +0,0 @@
|
||||
^gnulib/.*
|
@@ -1 +0,0 @@
|
||||
^ChangeLog
|
@@ -1,7 +0,0 @@
|
||||
^src/libvirt\.c$
|
||||
^src/qemu/qemu_driver\.c$
|
||||
^src/qemu/qemu_monitor\.c$
|
||||
^src/util/util\.c$
|
||||
^src/xen/xend_internal\.c$
|
||||
^daemon/libvirtd.c$
|
||||
^gnulib/
|
@@ -1 +0,0 @@
|
||||
^gnulib/m4/intl\.m4$
|
@@ -1 +0,0 @@
|
||||
gnulib/.*
|
@@ -1,5 +0,0 @@
|
||||
^ChangeLog$
|
||||
^ChangeLog-old$
|
||||
^include/libvirt/virterror\.h$
|
||||
^daemon/dispatch\.c$
|
||||
^src/util/virterror\.c$
|
@@ -1,3 +0,0 @@
|
||||
^gnulib/
|
||||
^po/
|
||||
ChangeLog
|
@@ -1,2 +0,0 @@
|
||||
^gnulib/lib/getaddrinfo\.c$
|
||||
^gnulib/m4/
|
@@ -1,2 +0,0 @@
|
||||
^src/util/util\.c$
|
||||
^ChangeLog-old$
|
@@ -1 +0,0 @@
|
||||
^gnulib/lib/strsep\.c$
|
@@ -1,10 +0,0 @@
|
||||
^gnulib/
|
||||
^po/
|
||||
^ChangeLog$
|
||||
^ChangeLog-old$
|
||||
^Makefile*
|
||||
^docs/
|
||||
^tests/
|
||||
^tools/virsh\.c$
|
||||
^tools/console\.c$
|
||||
^build-aux/
|
@@ -1 +0,0 @@
|
||||
^gnulib/
|
@@ -1,9 +0,0 @@
|
||||
^gnulib/
|
||||
^ChangeLog-old$
|
||||
^docs/
|
||||
^examples/domain-events/events-c/event-test\.c$
|
||||
^src/internal\.h$
|
||||
^src/lxc/lxc_container\.c$
|
||||
^src/node_device/node_device_devkit\.c$
|
||||
^src/node_device/node_device_hal\.c$
|
||||
^src/storage/parthelper\.c$
|
@@ -1 +0,0 @@
|
||||
^src/util/util\.c$
|
@@ -1,4 +0,0 @@
|
||||
^examples/
|
||||
^gnulib/lib/dummy\.c$
|
||||
^gnulib/tests/dummy\.c$
|
||||
^ChangeLog$
|
@@ -1 +0,0 @@
|
||||
^examples/
|
@@ -1,7 +0,0 @@
|
||||
\.fig$
|
||||
\.gif$
|
||||
\.ico$
|
||||
\.png$
|
||||
^ChangeLog$
|
||||
^NEWS$
|
||||
^docs/.*
|
100
AUTHORS
100
AUTHORS
@@ -1,100 +0,0 @@
|
||||
libvirt Authors
|
||||
===============
|
||||
|
||||
The libvirt project was initiated by:
|
||||
|
||||
Daniel Veillard <veillard@redhat.com> or <daniel@veillard.com>
|
||||
|
||||
The primary maintainers and people with commit access rights:
|
||||
|
||||
Daniel Veillard <veillard@redhat.com>
|
||||
Daniel Berrange <berrange@redhat.com>
|
||||
Richard W.M. Jones <rjones@redhat.com>
|
||||
Karel Zak <kzak@redhat.com>
|
||||
Mark McLoughlin <markmc@redhat.com>
|
||||
Anthony Liguori <aliguori@us.ibm.com>
|
||||
Jim Meyering <meyering@redhat.com>
|
||||
Jim Fehlig <jfehlig@novell.com>
|
||||
Chris Lalancette <clalance@redhat.com>
|
||||
Atsushi SAKAI <sakaia@jp.fujitsu.com>
|
||||
Dave Leskovec <dlesko@linux.vnet.ibm.com>
|
||||
Cole Robinson <crobinso@redhat.com>
|
||||
Dan Smith <danms@us.ibm.com>
|
||||
Guido Günther <agx@sigxcpu.org>
|
||||
John Levon <john.levon@sun.com>
|
||||
Matthias Bolte <matthias.bolte@googlemail.com>
|
||||
|
||||
Patches have also been contributed by:
|
||||
|
||||
David Lutterkort <dlutter@redhat.com>
|
||||
Andrew Puch <apuch@redhat.com>
|
||||
Philippe Berthault <philippe.berthault@Bull.net>
|
||||
Hugh Brock <hbrock@redhat.com>
|
||||
Michel Ponceau <michel.ponceau@bull.net>
|
||||
Jeremy Katz <katzj@redhat.com>
|
||||
Pete Vetere <pvetere@redhat.com>
|
||||
Kazuki Mizushima <mizushima.kazuk@jp.fujitsu.com>
|
||||
Saori Fukuta <fukuta.saori@jp.fujitsu.com>
|
||||
Tatsuro Enokura <fj7716hz@aa.jp.fujitsu.com>
|
||||
Takahashi Tomohiro <takatom@jp.fujitsu.com>
|
||||
Nobuhiro Itou <fj0873gn@aa.jp.fujitsu.com>
|
||||
Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>
|
||||
Mark Johnson <johnson.nh@gmail.com>
|
||||
Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
|
||||
Shuveb Hussain <shuveb@binarykarma.com>
|
||||
Jim Paris <jim@jtan.com>
|
||||
Daniel Hokka Zakrisson <daniel@hozac.com>
|
||||
Mads Chr. Olesen <shiyee@shiyee.dk>
|
||||
Anton Protopopov <aspsk2@gmail.com>
|
||||
Stefan de Konink <dekonink@kinkrsoftware.nl>
|
||||
Kaitlin Rupert <kaitlin@linux.vnet.ibm.com>
|
||||
Evgeniy Sokolov <evg@openvz.org>
|
||||
David Lively <dlively@virtualiron.com>
|
||||
Charles Duffy <Charles_Duffy@messageone.com>
|
||||
Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
James Morris <jmorris@namei.org>
|
||||
Chris Wright <chrisw@redhat.com>
|
||||
Ben Guthro <ben.guthro@gmail.com>
|
||||
Shigeki Sakamoto <fj0588di@aa.jp.fujitsu.com>
|
||||
Gerd von Egidy <lists@egidy.de>
|
||||
Itamar Heim <iheim@redhat.com>
|
||||
Dave Allan <dallan@redhat.com>
|
||||
Markus Armbruster <armbru@redhat.com>
|
||||
Ryota Ozaki <ozaki.ryota@gmail.com>
|
||||
James Morris <jmorris@namei.org>
|
||||
Daniel J Walsh <dwalsh@redhat.com>
|
||||
Maximilian Wilhelm <max@rfc2324.org>
|
||||
Pritesh Kothari <Pritesh.Kothari@Sun.COM>
|
||||
Amit Shah <amit.shah@redhat.com>
|
||||
Florian Vichot <florian.vichot@diateam.net>
|
||||
Takahashi Tomohiro <takatom@jp.fujitsu.com>
|
||||
Serge E. Hallyn <serue@us.ibm.com>
|
||||
Soren Hansen <soren@canonical.com>
|
||||
Laine Stump <laine@redhat.com>
|
||||
Abel Míguez Rodríguez<amiguezr@pdi.ucm.es>
|
||||
Doug Goldstein <cardoe@gentoo.org>
|
||||
Javier Fontan <jfontan@gmail.com>
|
||||
Federico Simoncelli <federico.simoncelli@gmail.com>
|
||||
Amy Griffis <amy.griffis@hp.com>
|
||||
Henrik Persson E <henrik.e.persson@ericsson.com>
|
||||
Satoru SATOH <satoru.satoh@gmail.com>
|
||||
Paolo Bonzini <pbonzini@redhat.com>
|
||||
Miloslav Trmač <mitr@redhat.com>
|
||||
Jiri Denemark <jdenemar@redhat.com>
|
||||
Jamie Strandboge <jamie@canonical.com>
|
||||
Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
|
||||
Matthew Booth <mbooth@redhat.com>
|
||||
Diego Elio Pettenò <flameeyes@gmail.com>
|
||||
Adam Litke <agl@us.ibm.com>
|
||||
Steve Yarmie <steve.yarmie@gmail.com>
|
||||
Dan Kenigsberg <danken@redhat.com>
|
||||
Yuji NISHIDA <nishidy@nict.go.jp>
|
||||
|
||||
[....send patches to get your name here....]
|
||||
|
||||
The libvirt Logo was designed by Diana Fong
|
||||
|
||||
-- End
|
||||
;; Local Variables:
|
||||
;; coding: utf-8
|
||||
;; End:
|
@@ -506,3 +506,5 @@ if necessary. Here is a sample; alter the names:
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
|
4
ChangeLog
Normal file
4
ChangeLog
Normal file
@@ -0,0 +1,4 @@
|
||||
Wed Nov 2 13:44:47 CET 2005 Daniel Veillard <veillard@redhat.com>
|
||||
|
||||
* src/libxen.c src/Makefile.am include/libxen.h configure.in
|
||||
Makefile.am COPYING.LIB: creation
|
16699
ChangeLog-old
16699
ChangeLog-old
File diff suppressed because it is too large
Load Diff
394
HACKING
394
HACKING
@@ -1,394 +0,0 @@
|
||||
Libvirt contributor guidelines
|
||||
==============================
|
||||
|
||||
|
||||
General tips for contributing patches
|
||||
=====================================
|
||||
|
||||
(1) Discuss any large changes on the mailing list first. Post patches
|
||||
early and listen to feedback.
|
||||
|
||||
(2) Post patches in unified diff format. A command similar to this
|
||||
should work:
|
||||
|
||||
diff -urp libvirt.orig/ libvirt.modified/ > libvirt-myfeature.patch
|
||||
|
||||
or:
|
||||
|
||||
cvs diff -up > libvirt-myfeature.patch
|
||||
|
||||
(3) 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.
|
||||
|
||||
(4) Make sure your patches apply against libvirt CVS. Developers
|
||||
only follow CVS and don't care much about released versions.
|
||||
|
||||
(5) Run the automated tests on your code before submitting any changes.
|
||||
In particular, configure with compile warnings set to -Werror:
|
||||
|
||||
./configure --enable-compile-warnings=error
|
||||
|
||||
and run the tests:
|
||||
|
||||
make check
|
||||
make syntax-check
|
||||
make -C tests valgrind
|
||||
|
||||
The latter test checks for memory leaks.
|
||||
|
||||
If you encounter any failing tests, the VIR_TEST_DEBUG environment variable
|
||||
may provide extra information to debug the failures. Larger values of
|
||||
VIR_TEST_DEBUG may provide larger amounts of information:
|
||||
|
||||
VIR_TEST_DEBUG=1 make check (or)
|
||||
VIR_TEST_DEBUG=2 make check
|
||||
|
||||
Also, individual tests can be run from inside the 'tests/' directory, like:
|
||||
|
||||
./qemuxml2xmltest
|
||||
|
||||
(6) Update tests and/or documentation, particularly if you are adding
|
||||
a new feature or changing the output of a program.
|
||||
|
||||
|
||||
There is more on this subject, including lots of links to background
|
||||
reading on the subject, on this page:
|
||||
|
||||
http://et.redhat.com/~rjones/how-to-supply-code-to-open-source-projects/
|
||||
|
||||
|
||||
|
||||
Code indentation
|
||||
================
|
||||
Libvirt's C source code generally adheres to some basic code-formatting
|
||||
conventions. The existing code base is not totally consistent on this
|
||||
front, but we do prefer that contributed code be formatted similarly.
|
||||
In short, use spaces-not-TABs for indentation, use 4 spaces for each
|
||||
indentation level, and other than that, follow the K&R style.
|
||||
|
||||
If you use Emacs, add the following to one of one of your start-up files
|
||||
(e.g., ~/.emacs), to help ensure that you get indentation right:
|
||||
|
||||
;;; When editing C sources in libvirt, use this style.
|
||||
(defun libvirt-c-mode ()
|
||||
"C mode with adjusted defaults for use with libvirt."
|
||||
(interactive)
|
||||
(c-set-style "K&R")
|
||||
(setq indent-tabs-mode nil) ; indent using spaces, not TABs
|
||||
(setq c-indent-level 4)
|
||||
(setq c-basic-offset 4))
|
||||
(add-hook 'c-mode-hook
|
||||
'(lambda () (if (string-match "/libvirt" (buffer-file-name))
|
||||
(libvirt-c-mode))))
|
||||
|
||||
Code formatting (especially for new code)
|
||||
=========================================
|
||||
With new code, we can be even more strict.
|
||||
Please apply the following function (using GNU indent) to any new code.
|
||||
Note that this also gives you an idea of the type of spacing we prefer
|
||||
around operators and keywords:
|
||||
|
||||
indent-libvirt()
|
||||
{
|
||||
indent -bad -bap -bbb -bli4 -br -ce -brs -cs -i4 -l75 -lc75 \
|
||||
-sbi4 -psl -saf -sai -saw -sbi4 -ss -sc -cdw -cli4 -npcs -nbc \
|
||||
--no-tabs "$@"
|
||||
}
|
||||
|
||||
Note that sometimes you'll have to postprocess that output further, by
|
||||
piping it through "expand -i", since some leading TABs can get through.
|
||||
Usually they're in macro definitions or strings, and should be converted
|
||||
anyhow.
|
||||
|
||||
|
||||
C types
|
||||
=======
|
||||
Use the right type.
|
||||
|
||||
Scalars
|
||||
-------
|
||||
If you're using "int" or "long", odds are good that there's a better type.
|
||||
If a variable is counting something, be sure to declare it with an
|
||||
unsigned type.
|
||||
If it's memory-size-related, use size_t (use ssize_t only if required).
|
||||
If it's file-size related, use uintmax_t, or maybe off_t.
|
||||
If it's file-offset related (i.e., signed), use off_t.
|
||||
If it's just counting small numbers use "unsigned int";
|
||||
(on all but oddball embedded systems, you can assume that that
|
||||
type is at least four bytes wide).
|
||||
If a variable has boolean semantics, give it the "bool" type
|
||||
and use the corresponding "true" and "false" macros. It's ok
|
||||
to include <stdbool.h>, since libvirt's use of gnulib ensures
|
||||
that it exists and is usable.
|
||||
In the unusual event that you require a specific width, use a
|
||||
standard type like int32_t, uint32_t, uint64_t, etc.
|
||||
|
||||
While using "bool" is good for readability, it comes with minor caveats:
|
||||
- Don't use "bool" in places where the type size must be constant across
|
||||
all systems, like public interfaces and on-the-wire protocols. Note
|
||||
that it would be possible (albeit wasteful) to use "bool" in libvirt's
|
||||
logical wire protocol, since XDR maps that to its lower-level bool_t
|
||||
type, which *is* fixed-size.
|
||||
- Don't compare a bool variable against the literal, "true",
|
||||
since a value with a logical non-false value need not be "1".
|
||||
I.e., don't write "if (seen == 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.
|
||||
|
||||
Also, if you try to use e.g., "unsigned int" as a type, and that
|
||||
conflicts with the signedness of a related variable, sometimes
|
||||
it's best just to use the *wrong* type, if "pulling the thread"
|
||||
and fixing all related variables would be too invasive.
|
||||
|
||||
Finally, while using descriptive types is important, be careful not to
|
||||
go overboard. If whatever you're doing causes warnings, or requires
|
||||
casts, then reconsider or ask for help.
|
||||
|
||||
Pointers
|
||||
--------
|
||||
Ensure that all of your pointers are "const-correct".
|
||||
Unless a pointer is used to modify the pointed-to storage,
|
||||
give it the "const" attribute. That way, the reader knows
|
||||
up-front that this is a read-only pointer. Perhaps more
|
||||
importantly, if we're diligent about this, when you see a non-const
|
||||
pointer, you're guaranteed that it is used to modify the storage
|
||||
it points to, or it is aliased to another pointer that is.
|
||||
|
||||
|
||||
Low level memory management
|
||||
===========================
|
||||
|
||||
Use of the malloc/free/realloc/calloc APIs is deprecated in the libvirt
|
||||
codebase, because they encourage a number of serious coding bugs and do
|
||||
not enable compile time verification of checks for NULL. Instead of these
|
||||
routines, use the macros from memory.h
|
||||
|
||||
- eg to allocate a single object:
|
||||
|
||||
virDomainPtr domain;
|
||||
|
||||
if (VIR_ALLOC(domain) < 0) {
|
||||
__virRaiseError(VIR_ERROR_NO_MEMORY)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
- eg to allocate an array of objects
|
||||
|
||||
virDomainPtr domains;
|
||||
int ndomains = 10;
|
||||
|
||||
if (VIR_ALLOC_N(domains, ndomains) < 0) {
|
||||
__virRaiseError(VIR_ERROR_NO_MEMORY)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- eg to allocate an array of object pointers
|
||||
|
||||
virDomainPtr *domains;
|
||||
int ndomains = 10;
|
||||
|
||||
if (VIR_ALLOC_N(domains, ndomains) < 0) {
|
||||
__virRaiseError(VIR_ERROR_NO_MEMORY)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- eg to re-allocate the array of domains to be longer
|
||||
|
||||
ndomains = 20
|
||||
|
||||
if (VIR_REALLOC_N(domains, ndomains) < 0) {
|
||||
__virRaiseError(VIR_ERROR_NO_MEMORY)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- eg to free the domain
|
||||
|
||||
VIR_FREE(domain);
|
||||
|
||||
|
||||
|
||||
String comparisons
|
||||
==================
|
||||
|
||||
Do not use the strcmp, strncmp, etc functions directly. Instead use
|
||||
one of the following semantically named macros
|
||||
|
||||
- For strict equality:
|
||||
|
||||
STREQ(a,b)
|
||||
STRNEQ(a,b)
|
||||
|
||||
- For case sensitive equality:
|
||||
STRCASEEQ(a,b)
|
||||
STRCASENEQ(a,b)
|
||||
|
||||
- For strict equality of a substring:
|
||||
|
||||
STREQLEN(a,b,n)
|
||||
STRNEQLEN(a,b,n)
|
||||
|
||||
- For case sensitive equality of a substring:
|
||||
|
||||
STRCASEEQLEN(a,b,n)
|
||||
STRCASENEQLEN(a,b,n)
|
||||
|
||||
- For strict equality of a prefix:
|
||||
|
||||
STRPREFIX(a,b)
|
||||
|
||||
|
||||
|
||||
String copying
|
||||
==============
|
||||
|
||||
Do not use the strncpy function. According to the man page, it does
|
||||
*not* guarantee a NULL-terminated buffer, which makes it extremely dangerous
|
||||
to use. Instead, use one of the functionally equivalent functions:
|
||||
|
||||
- virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
|
||||
The first three arguments have the same meaning as for strncpy; namely the
|
||||
destination, source, and number of bytes to copy, respectively. The last
|
||||
argument is the number of bytes available in the destination string; if a
|
||||
copy of the source string (including a \0) will not fit into the
|
||||
destination, no bytes are copied and the routine returns NULL.
|
||||
Otherwise, n bytes from the source are copied into the destination and a
|
||||
trailing \0 is appended.
|
||||
|
||||
- virStrcpy(char *dest, const char *src, size_t destbytes)
|
||||
Use this variant if you know you want to copy the entire src string
|
||||
into dest. Note that this is a macro, so arguments could be
|
||||
evaluated more than once. This is equivalent to
|
||||
virStrncpy(dest, src, strlen(src), destbytes)
|
||||
|
||||
- virStrcpyStatic(char *dest, const char *src)
|
||||
Use this variant if you know you want to copy the entire src string
|
||||
into dest *and* you know that your destination string is a static string
|
||||
(i.e. that sizeof(dest) returns something meaningful). Note that
|
||||
this is a macro, so arguments could be evaluated more than once. This is
|
||||
equivalent to virStrncpy(dest, src, strlen(src), sizeof(dest)).
|
||||
|
||||
|
||||
|
||||
Variable length string buffer
|
||||
=============================
|
||||
|
||||
If there is a need for complex string concatenations, avoid using
|
||||
the usual sequence of malloc/strcpy/strcat/snprintf functions and
|
||||
make use of the virBuffer API described in buf.h
|
||||
|
||||
eg typical usage is as follows:
|
||||
|
||||
char *
|
||||
somefunction(...) {
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
...
|
||||
|
||||
virBufferAddLit(&buf, "<domain>\n");
|
||||
virBufferVSprint(&buf, " <memory>%d</memory>\n", memory);
|
||||
...
|
||||
virBufferAddLit(&buf, "</domain>\n");
|
||||
|
||||
...
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virBufferFreeAndReset(&buf);
|
||||
virReportOOMError(...);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
||||
|
||||
Include files
|
||||
=============
|
||||
|
||||
There are now quite a large number of include files, both libvirt
|
||||
internal and external, and system includes. To manage all this
|
||||
complexity it's best to stick to the following general plan for all
|
||||
*.c source files:
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
* ....
|
||||
* ....
|
||||
* ....
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h> Must come first in every file.
|
||||
|
||||
#include <stdio.h> Any system includes you need.
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if HAVE_NUMACTL Some system includes aren't supported
|
||||
#include <numa.h> everywhere so need these #if defences.
|
||||
#endif
|
||||
|
||||
#include "internal.h" Include this first, after system includes.
|
||||
|
||||
#include "util.h" Any libvirt internal header files.
|
||||
#include "buf.h"
|
||||
|
||||
static myInternalFunc () The actual code.
|
||||
{
|
||||
...
|
||||
|
||||
Of particular note: *DO NOT* include libvirt/libvirt.h or
|
||||
libvirt/virterror.h. It is included by "internal.h" already and there
|
||||
are some special reasons why you cannot include these files
|
||||
explicitly.
|
||||
|
||||
|
||||
Printf-style functions
|
||||
======================
|
||||
|
||||
Whenever you add a new printf-style function, i.e., one with a format
|
||||
string argument and following "..." in its prototype, be sure to use
|
||||
gcc's printf attribute directive in the prototype. For example, here's
|
||||
the one for virAsprintf, in util.h:
|
||||
|
||||
int virAsprintf(char **strp, const char *fmt, ...)
|
||||
ATTRIBUTE_FMT_PRINTF(2, 3);
|
||||
|
||||
This makes it so gcc's -Wformat and -Wformat-security options can do
|
||||
their jobs and cross-check format strings with the number and types
|
||||
of arguments.
|
||||
|
||||
|
||||
|
||||
Libvirt commiters guidelines
|
||||
============================
|
||||
|
||||
The AUTHORS files indicates the list of people with commit acces right
|
||||
who can actually merge the patches.
|
||||
|
||||
The general rule for commiting patches is to make sure it has been reviewed
|
||||
properly in the mailing-list first, usually if a couple of persons gave an
|
||||
ACK or +1 to a patch and nobody raised an objection on the list it should
|
||||
be good to go. If the patch touches a part of the code where you're not the
|
||||
main maintainer or not have a very clear idea of how things work, it's better
|
||||
to wait for a more authoritative feedback though. Before commiting please
|
||||
also rebuild locally and run 'make check syntax-check' and make sure they
|
||||
don't raise error. Try to look for warnings too for example configure with
|
||||
--enable-compile-warnings=error
|
||||
which adds -Werror to compile flags, so no warnings get missed
|
||||
|
||||
Exceptions to that 'review and approval on the list first' is fixing failures
|
||||
to build:
|
||||
- if a recently commited patch breaks compilation on a platform
|
||||
or for a given driver then it's fine to commit a minimal fix
|
||||
directly without getting the review feedback first
|
||||
- similary if make check or make syntax-chek breaks, if there is
|
||||
an obvious fix, it's fine to commit immediately
|
||||
The patch should still be sent to the list (or tell what the fix was if
|
||||
trivial) and 'make check syntax-check' should pass too before commiting
|
||||
anything
|
||||
Similary fixes for documentation and code comments can be managed
|
||||
in the same way, but still make sure they get reviewed if non-trivial.
|
90
Makefile.am
90
Makefile.am
@@ -1,91 +1,9 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
LCOV = lcov
|
||||
GENHTML = genhtml
|
||||
|
||||
SUBDIRS = gnulib/lib include src daemon tools proxy docs gnulib/tests \
|
||||
python tests po examples/domain-events/events-c examples/hellolibvirt \
|
||||
examples/dominfo examples/domsuspend examples/python examples/apparmor
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
|
||||
|
||||
XML_EXAMPLES = $(wildcard examples/xml/test/*.xml) $(wildcard examples/xml/storage/*.xml)
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog-old \
|
||||
libvirt.spec libvirt.spec.in \
|
||||
mingw32-libvirt.spec.in \
|
||||
libvirt.pc libvirt.pc.in \
|
||||
autobuild.sh \
|
||||
.x-sc_avoid_ctype_macros \
|
||||
.x-sc_avoid_if_before_free \
|
||||
.x-sc_avoid_write \
|
||||
.x-sc_m4_quote_check \
|
||||
.x-sc_prohibit_asprintf \
|
||||
.x-sc_prohibit_gethostby \
|
||||
.x-sc_prohibit_gethostname \
|
||||
.x-sc_prohibit_have_config_h \
|
||||
.x-sc_prohibit_HAVE_MBRTOWC \
|
||||
.x-sc_prohibit_nonreentrant \
|
||||
.x-sc_prohibit_strcmp \
|
||||
.x-sc_prohibit_strcmp_and_strncmp \
|
||||
.x-sc_prohibit_strncpy \
|
||||
.x-sc_prohibit_VIR_ERR_NO_MEMORY \
|
||||
.x-sc_require_config_h \
|
||||
.x-sc_require_config_h_first \
|
||||
.x-sc_trailing_blank \
|
||||
Makefile.nonreentrant \
|
||||
autogen.sh \
|
||||
examples/domain-events/events-python \
|
||||
$(XML_EXAMPLES)
|
||||
SUBDIRS = src #docs
|
||||
EXTRA_DIST = libxen.spec.in libxen.spec COPYING.LIB \
|
||||
libxen.pc.in libxen.pc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libvirt.pc
|
||||
pkgconfig_DATA = libxen.pc
|
||||
|
||||
NEWS: $(top_srcdir)/docs/news.xsl $(top_srcdir)/docs/news.html.in
|
||||
-@(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 );
|
||||
|
||||
|
||||
rpm: clean
|
||||
@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz)
|
||||
|
||||
check-local: all tests
|
||||
|
||||
tests:
|
||||
@(cd docs/examples ; $(MAKE) MAKEFLAGS+=--silent tests)
|
||||
@(if [ "$(pythondir)" != "" ] ; then cd python ; \
|
||||
$(MAKE) MAKEFLAGS+=--silent tests ; fi)
|
||||
|
||||
cov: clean-cov
|
||||
mkdir $(top_builddir)/coverage
|
||||
$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp -d $(top_srcdir)/src -d $(top_srcdir)/daemon -d $(top_srcdir)/tests
|
||||
$(LCOV) -r $(top_builddir)/coverage/libvirt.info.tmp -o $(top_builddir)/coverage/libvirt.info *usr*
|
||||
rm $(top_builddir)/coverage/libvirt.info.tmp
|
||||
$(GENHTML) -s -t "libvirt" -o $(top_builddir)/coverage --legend $(top_builddir)/coverage/libvirt.info
|
||||
|
||||
clean-cov:
|
||||
rm -rf $(top_builddir)/coverage
|
||||
|
||||
MAINTAINERCLEANFILES = .git-module-status
|
||||
|
||||
# disable this check
|
||||
distuninstallcheck:
|
||||
|
||||
dist-hook: gen-ChangeLog
|
||||
|
||||
# Generate the ChangeLog file (with all entries since the switch to git)
|
||||
# and insert it into the directory we're about to use to create a tarball.
|
||||
gen_start_date = 2009-07-04
|
||||
.PHONY: gen-ChangeLog
|
||||
gen-ChangeLog:
|
||||
if test -d .git; then \
|
||||
$(top_srcdir)/build-aux/gitlog-to-changelog \
|
||||
--since=$(gen_start_date) > $(distdir)/cl-t; \
|
||||
rm -f $(distdir)/ChangeLog; \
|
||||
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
|
||||
fi
|
||||
|
@@ -1,85 +0,0 @@
|
||||
|
||||
#
|
||||
# Generated by running the following on Fedora 9:
|
||||
#
|
||||
# nm -D --defined-only /lib/libc.so.6 \
|
||||
# | grep '_r$' \
|
||||
# | awk '{print $3}' \
|
||||
# | grep -v __ \
|
||||
# | grep -v qsort \ # Red herring since we don't need to pass extra args to qsort comparator
|
||||
# | grep -v readdir \ # This is safe as long as each DIR * instance is only used by one thread
|
||||
# | sort \
|
||||
# | uniq \
|
||||
# | sed -e 's/_r//'
|
||||
#
|
||||
|
||||
NON_REENTRANT =
|
||||
NON_REENTRANT += asctime
|
||||
NON_REENTRANT += ctime
|
||||
NON_REENTRANT += drand48
|
||||
NON_REENTRANT += ecvt
|
||||
NON_REENTRANT += erand48
|
||||
NON_REENTRANT += ether_aton
|
||||
NON_REENTRANT += ether_ntoa
|
||||
NON_REENTRANT += fcvt
|
||||
NON_REENTRANT += fgetgrent
|
||||
NON_REENTRANT += fgetpwent
|
||||
NON_REENTRANT += fgetspent
|
||||
NON_REENTRANT += getaliasbyname
|
||||
NON_REENTRANT += getaliasent
|
||||
NON_REENTRANT += getdate
|
||||
NON_REENTRANT += getgrent
|
||||
NON_REENTRANT += getgrgid
|
||||
NON_REENTRANT += getgrnam
|
||||
NON_REENTRANT += gethostbyaddr
|
||||
NON_REENTRANT += gethostbyname2
|
||||
NON_REENTRANT += gethostbyname
|
||||
NON_REENTRANT += gethostent
|
||||
NON_REENTRANT += getlogin
|
||||
NON_REENTRANT += getmntent
|
||||
NON_REENTRANT += getnetbyaddr
|
||||
NON_REENTRANT += getnetbyname
|
||||
NON_REENTRANT += getnetent
|
||||
NON_REENTRANT += getnetgrent
|
||||
NON_REENTRANT += getprotobyname
|
||||
NON_REENTRANT += getprotobynumber
|
||||
NON_REENTRANT += getprotoent
|
||||
NON_REENTRANT += getpwent
|
||||
NON_REENTRANT += getpwnam
|
||||
NON_REENTRANT += getpwuid
|
||||
NON_REENTRANT += getrpcbyname
|
||||
NON_REENTRANT += getrpcbynumber
|
||||
NON_REENTRANT += getrpcent
|
||||
NON_REENTRANT += getservbyname
|
||||
NON_REENTRANT += getservbyport
|
||||
NON_REENTRANT += getservent
|
||||
NON_REENTRANT += getspent
|
||||
NON_REENTRANT += getspnam
|
||||
NON_REENTRANT += getutent
|
||||
NON_REENTRANT += getutid
|
||||
NON_REENTRANT += getutline
|
||||
NON_REENTRANT += gmtime
|
||||
NON_REENTRANT += hcreate
|
||||
NON_REENTRANT += hdestroy
|
||||
NON_REENTRANT += hsearch
|
||||
NON_REENTRANT += initstate
|
||||
NON_REENTRANT += jrand48
|
||||
NON_REENTRANT += lcong48
|
||||
NON_REENTRANT += localtime
|
||||
NON_REENTRANT += lrand48
|
||||
NON_REENTRANT += mrand48
|
||||
NON_REENTRANT += nrand48
|
||||
NON_REENTRANT += ptsname
|
||||
NON_REENTRANT += qecvt
|
||||
NON_REENTRANT += qfcvt
|
||||
NON_REENTRANT += random
|
||||
NON_REENTRANT += rand
|
||||
NON_REENTRANT += seed48
|
||||
NON_REENTRANT += setstate
|
||||
NON_REENTRANT += sgetspent
|
||||
NON_REENTRANT += srand48
|
||||
NON_REENTRANT += srandom
|
||||
NON_REENTRANT += strerror
|
||||
NON_REENTRANT += strtok
|
||||
NON_REENTRANT += tmpnam
|
||||
NON_REENTRANT += ttyname
|
13
README
13
README
@@ -1,13 +0,0 @@
|
||||
|
||||
LibVirt : simple API for virtualization
|
||||
|
||||
Libvirt is a C toolkit to interact with the virtualization capabilities
|
||||
of recent versions of Linux (and other OSes). It is free software
|
||||
available under the GNU Lesser General Public License. Virtualization of
|
||||
the Linux Operating System means the ability to run multiple instances of
|
||||
Operating Systems concurrently on a single hardware system where the basic
|
||||
resources are driven by a Linux instance. The library aim at providing
|
||||
long term stable C API initially for the Xen paravirtualization but
|
||||
should be able to integrate other virtualization mechanisms if needed.
|
||||
|
||||
Daniel Veillard <veillard@redhat.com>
|
@@ -1,52 +0,0 @@
|
||||
-*- outline -*-
|
||||
|
||||
These notes intend to help people working on the checked-out sources.
|
||||
These requirements do not apply when building from a distribution tarball.
|
||||
See also HACKING for more detailed libvirt contribution guidelines.
|
||||
|
||||
* Requirements
|
||||
|
||||
We've opted to keep only the highest-level sources in the GIT repository.
|
||||
This eases our maintenance burden, (fewer merges etc.), but imposes more
|
||||
requirements on anyone wishing to build from the just-checked-out sources.
|
||||
Note the requirements to build the released archive are much less and
|
||||
are just the requirements of the standard ./configure && make procedure.
|
||||
Specific development tools and versions will be checked for and listed by
|
||||
the bootstrap script. See README-prereq for specific notes on obtaining
|
||||
these prerequisite tools.
|
||||
|
||||
Valgrind <http://valgrind.org/> is also highly recommended, if
|
||||
Valgrind supports your architecture. See also README-valgrind.
|
||||
|
||||
While building from a just-cloned source tree may require installing a
|
||||
few prerequisites, later, a plain `git pull && make' should be sufficient.
|
||||
|
||||
* First GIT checkout
|
||||
|
||||
You can get a copy of the source repository like this:
|
||||
|
||||
$ git clone git://libvirt.org/libvirt
|
||||
$ cd libvirt
|
||||
|
||||
The next step is to get all required pieces from gnulib,
|
||||
to run autoreconf, and to invoke ./configure:
|
||||
|
||||
$ ./autogen.sh
|
||||
|
||||
And there you are! Just
|
||||
|
||||
$ make
|
||||
$ make check
|
||||
|
||||
At this point, there should be no difference between your local copy,
|
||||
and the GIT master copy:
|
||||
|
||||
$ git diff
|
||||
|
||||
should output no difference.
|
||||
|
||||
Enjoy!
|
||||
|
||||
Local Variables:
|
||||
indent-tabs-mode: nil
|
||||
End:
|
29
TODO
29
TODO
@@ -1,29 +0,0 @@
|
||||
TODO:
|
||||
- libvirt_virDomainSetMemory should check memory is > 0
|
||||
- check how to better handle renaming of domains (xm rename and cache)
|
||||
|
||||
- UUID lookup in hash.c
|
||||
|
||||
Other environment:
|
||||
- support for UML
|
||||
|
||||
+ UML control layer should be easy at least for one user but incomplete
|
||||
|
||||
Probable TODOs:
|
||||
- event on big domain state change (create, crashed, paused, shutdown, destroy)
|
||||
- bindings for more languages
|
||||
|
||||
Would-be-nice TODO:
|
||||
- man page for virsh and the libraries entry points
|
||||
- more documentation and examples on using the toolkit
|
||||
- examples for the error handling code
|
||||
|
||||
Cleanup:
|
||||
- now that libxml2 is linked in, drop hash.[ch] and get back to libxml2 ones ?
|
||||
same for the buffers
|
||||
|
||||
Autoconf:
|
||||
- On Debian and other platforms, C++ compiler is required because
|
||||
autoconf macros to detect libtool depend on it. (This is probably
|
||||
an autoconf or libtool m4 macro bug, and the fact that it happens
|
||||
on Debian is a red herring).
|
109
acinclude.m4
109
acinclude.m4
@@ -1,109 +0,0 @@
|
||||
dnl
|
||||
dnl Taken from gnome-common/macros2/gnome-compiler-flags.m4
|
||||
dnl
|
||||
dnl We've added:
|
||||
dnl -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Winline -Wredundant-decls
|
||||
dnl We've removed
|
||||
dnl CFLAGS="$realsave_CFLAGS"
|
||||
dnl to avoid clobbering user-specified CFLAGS
|
||||
dnl
|
||||
AC_DEFUN([LIBVIRT_COMPILE_WARNINGS],[
|
||||
dnl ******************************
|
||||
dnl More compiler warnings
|
||||
dnl ******************************
|
||||
|
||||
AC_ARG_ENABLE(compile-warnings,
|
||||
AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
|
||||
[Turn on compiler warnings]),,
|
||||
[enable_compile_warnings="m4_default([$1],[maximum])"])
|
||||
|
||||
warnCFLAGS=
|
||||
|
||||
common_flags="-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables"
|
||||
|
||||
case "$enable_compile_warnings" in
|
||||
no)
|
||||
try_compiler_flags=""
|
||||
;;
|
||||
minimum)
|
||||
try_compiler_flags="-Wall -Wformat -Wformat-security $common_flags"
|
||||
;;
|
||||
yes)
|
||||
try_compiler_flags="-Wall -Wformat -Wformat-security -Wmissing-prototypes $common_flags"
|
||||
;;
|
||||
maximum|error)
|
||||
try_compiler_flags="-Wall -Wformat -Wformat-security -Wmissing-prototypes -Wnested-externs -Wpointer-arith"
|
||||
try_compiler_flags="$try_compiler_flags -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return"
|
||||
try_compiler_flags="$try_compiler_flags -Wstrict-prototypes -Winline -Wredundant-decls -Wno-sign-compare"
|
||||
try_compiler_flags="$try_compiler_flags $common_flags"
|
||||
if test "$enable_compile_warnings" = "error" ; then
|
||||
try_compiler_flags="$try_compiler_flags -Werror"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings)
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPILER_FLAGS=
|
||||
for option in $try_compiler_flags; do
|
||||
gl_COMPILER_FLAGS($option)
|
||||
done
|
||||
unset option
|
||||
unset try_compiler_flags
|
||||
|
||||
AC_ARG_ENABLE(iso-c,
|
||||
AC_HELP_STRING([--enable-iso-c],
|
||||
[Try to warn if code is not ISO C ]),,
|
||||
[enable_iso_c=no])
|
||||
|
||||
AC_MSG_CHECKING(what language compliance flags to pass to the C compiler)
|
||||
complCFLAGS=
|
||||
if test "x$enable_iso_c" != "xno"; then
|
||||
if test "x$GCC" = "xyes"; then
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-ansi[\ \ ]*) ;;
|
||||
*) complCFLAGS="$complCFLAGS -ansi" ;;
|
||||
esac
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-pedantic[\ \ ]*) ;;
|
||||
*) complCFLAGS="$complCFLAGS -pedantic" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($complCFLAGS)
|
||||
|
||||
WARN_CFLAGS="$COMPILER_FLAGS $complCFLAGS"
|
||||
AC_SUBST(WARN_CFLAGS)
|
||||
|
||||
dnl Needed to keep compile quiet on python 2.4
|
||||
COMPILER_FLAGS=
|
||||
gl_COMPILER_FLAGS(-Wno-redundant-decls)
|
||||
WARN_PYTHON_CFLAGS=$COMPILER_FLAGS
|
||||
AC_SUBST(WARN_PYTHON_CFLAGS)
|
||||
])
|
||||
|
||||
|
||||
dnl
|
||||
dnl To support the old pkg-config from RHEL4 vintage, we need
|
||||
dnl to define the PKG_PROG_PKG_CONFIG macro if its not already
|
||||
dnl present
|
||||
m4_ifndef([PKG_PROG_PKG_CONFIG],
|
||||
[AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])])
|
96
autobuild.sh
96
autobuild.sh
@@ -1,96 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
set -v
|
||||
|
||||
# Make things clean.
|
||||
|
||||
test -n "$1" && RESULTS=$1 || RESULTS=results.log
|
||||
|
||||
test -f Makefile && make -k distclean || :
|
||||
rm -rf coverage
|
||||
|
||||
#rm -rf build
|
||||
#mkdir build
|
||||
#cd build
|
||||
|
||||
./autogen.sh --prefix="$AUTOBUILD_INSTALL_ROOT" \
|
||||
--enable-test-coverage \
|
||||
--enable-compile-warnings=error \
|
||||
--with-xen-proxy
|
||||
|
||||
# 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
|
||||
make check 2>&1 | tee "$RESULTS"
|
||||
make syntax-check 2>&1 | tee -a "$RESULTS"
|
||||
test -x /usr/bin/lcov && make cov
|
||||
|
||||
rm -f *.tar.gz
|
||||
make dist
|
||||
|
||||
if [ -n "$AUTOBUILD_COUNTER" ]; then
|
||||
EXTRA_RELEASE=".auto$AUTOBUILD_COUNTER"
|
||||
else
|
||||
NOW=`date +"%s"`
|
||||
EXTRA_RELEASE=".$USER$NOW"
|
||||
fi
|
||||
|
||||
if [ -f /usr/bin/rpmbuild ]; then
|
||||
rpmbuild --nodeps \
|
||||
--define "extra_release $EXTRA_RELEASE" \
|
||||
--define "_sourcedir `pwd`" \
|
||||
-ba --clean libvirt.spec
|
||||
fi
|
||||
|
||||
if [ -x /usr/bin/i686-pc-mingw32-gcc ]; then
|
||||
make distclean
|
||||
|
||||
PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw/lib/pkgconfig" \
|
||||
CC="i686-pc-mingw32-gcc" \
|
||||
./configure \
|
||||
--build=$(uname -m)-pc-linux \
|
||||
--host=i686-pc-mingw32 \
|
||||
--prefix="$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw" \
|
||||
--enable-compile-warnings=error \
|
||||
--without-sasl \
|
||||
--without-avahi \
|
||||
--without-polkit \
|
||||
--without-python \
|
||||
--without-xen \
|
||||
--without-qemu \
|
||||
--without-lxc \
|
||||
--without-uml \
|
||||
--without-vbox \
|
||||
--without-openvz \
|
||||
--without-one \
|
||||
--without-phyp \
|
||||
--without-netcf \
|
||||
--without-libvirtd
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
#set -o pipefail
|
||||
#make check 2>&1 | tee "$RESULTS"
|
||||
|
||||
if [ -f /usr/bin/rpmbuild ]; then
|
||||
rpmbuild --nodeps \
|
||||
--define "extra_release $EXTRA_RELEASE" \
|
||||
--define "_sourcedir `pwd`" \
|
||||
-ba --clean mingw32-libvirt.spec
|
||||
fi
|
||||
fi
|
91
autogen.sh
91
autogen.sh
@@ -1,91 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
THEDIR=`pwd`
|
||||
cd $srcdir
|
||||
DIE=0
|
||||
|
||||
(autopoint --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have autopoint installed to compile libvirt."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or see http://www.gnu.org/software/gettext"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have autoconf installed to compile libvirt."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or see http://www.gnu.org/software/autoconf"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(libtool --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have libtool installed to compile libvirt."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or see http://www.gnu.org/software/libtool"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
DIE=1
|
||||
echo "You must have automake installed to compile libvirt."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or see http://www.gnu.org/software/automake"
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -f src/libvirt.c || {
|
||||
echo "You must run this script in the top-level libvirt directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
EXTRA_ARGS=
|
||||
if test "x$1" = "x--system"; then
|
||||
shift
|
||||
EXTRA_ARGS="--prefix=/usr --sysconfdir=/etc --localstatedir=/var"
|
||||
echo "Running ./configure with $EXTRA_ARGS $@"
|
||||
else
|
||||
if test -z "$*"; 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
|
||||
|
||||
# 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.
|
||||
curr_status=.git-module-status
|
||||
t=$(git submodule status)
|
||||
if test "$t" = "$(cat $curr_status 2>/dev/null)"; then
|
||||
: # good, it's up to date
|
||||
else
|
||||
echo running bootstrap...
|
||||
./bootstrap && echo "$t" > $curr_status
|
||||
fi
|
||||
|
||||
# Automake requires that ChangeLog exist.
|
||||
touch ChangeLog
|
||||
|
||||
autoreconf -if
|
||||
|
||||
cd $THEDIR
|
||||
|
||||
if test x$OBJ_DIR != x; then
|
||||
mkdir -p "$OBJ_DIR"
|
||||
cd "$OBJ_DIR"
|
||||
fi
|
||||
|
||||
$srcdir/configure $EXTRA_ARGS "$@" && {
|
||||
echo
|
||||
echo "Now type 'make' to compile libvirt."
|
||||
}
|
117
bootstrap
117
bootstrap
@@ -1,117 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this before autogen.sh, to pull in all of the gnulib-related bits.
|
||||
|
||||
usage() {
|
||||
echo >&2 "\
|
||||
Usage: $0 [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
Options:
|
||||
--gnulib-srcdir=DIRNAME Specify the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
do not want to waste your bandwidth downloading
|
||||
them again.
|
||||
|
||||
If the file bootstrap.conf exists in the current working directory, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
"
|
||||
}
|
||||
|
||||
for option
|
||||
do
|
||||
case $option in
|
||||
--help)
|
||||
usage
|
||||
exit;;
|
||||
--gnulib-srcdir=*)
|
||||
GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
|
||||
*)
|
||||
echo >&2 "$0: $option: unknown option"
|
||||
exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get gnulib files.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-)
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule init || exit $?
|
||||
git submodule update || exit $?
|
||||
GNULIB_SRCDIR=.gnulib
|
||||
;;
|
||||
*)
|
||||
# Redirect the gnulib submodule to the directory on the command line
|
||||
# if possible.
|
||||
if test -d "$GNULIB_SRCDIR"/.git && \
|
||||
git config --file .gitmodules submodule.gnulib.url >/dev/null; then
|
||||
git submodule init
|
||||
GNULIB_SRCDIR=`cd $GNULIB_SRCDIR && pwd`
|
||||
git config --replace-all submodule.gnulib.url $GNULIB_SRCDIR
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule update || exit $?
|
||||
GNULIB_SRCDIR=.gnulib
|
||||
else
|
||||
echo >&2 "$0: invalid gnulib srcdir: $GNULIB_SRCDIR"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
|
||||
<$gnulib_tool || exit
|
||||
|
||||
modules='
|
||||
areadlink
|
||||
base64
|
||||
c-ctype
|
||||
close
|
||||
connect
|
||||
getaddrinfo
|
||||
gethostname
|
||||
getpass
|
||||
gettext
|
||||
gitlog-to-changelog
|
||||
gnumakefile
|
||||
inet_pton
|
||||
ioctl
|
||||
maintainer-makefile
|
||||
mkstemp
|
||||
mktempd
|
||||
perror
|
||||
physmem
|
||||
poll
|
||||
posix-shell
|
||||
recv
|
||||
random_r
|
||||
send
|
||||
setsockopt
|
||||
socket
|
||||
stpcpy
|
||||
strchrnul
|
||||
strndup
|
||||
strerror
|
||||
strsep
|
||||
sys_stat
|
||||
time_r
|
||||
useless-if-before-free
|
||||
vasprintf
|
||||
verify
|
||||
vc-list-files
|
||||
'
|
||||
|
||||
# Tell gnulib to:
|
||||
# require LGPLv2+
|
||||
# put *.m4 files in new gnulib/m4/ dir
|
||||
# put *.[ch] files in new gnulib/lib/ dir.
|
||||
|
||||
$gnulib_tool \
|
||||
--lgpl=2 \
|
||||
--with-tests \
|
||||
--m4-base=gnulib/m4 \
|
||||
--source-base=gnulib/lib \
|
||||
--tests-base=gnulib/tests \
|
||||
--import $modules
|
3
build-aux/.gitignore
vendored
3
build-aux/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
*
|
||||
/link-warning.h
|
||||
/mktempd
|
267
cfg.mk
267
cfg.mk
@@ -1,267 +0,0 @@
|
||||
# Customize Makefile.maint. -*- makefile -*-
|
||||
# Copyright (C) 2003-2009 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Use alpha.gnu.org for alpha and beta releases.
|
||||
# Use ftp.gnu.org for major releases.
|
||||
gnu_ftp_host-alpha = alpha.gnu.org
|
||||
gnu_ftp_host-beta = alpha.gnu.org
|
||||
gnu_ftp_host-major = ftp.gnu.org
|
||||
gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
|
||||
|
||||
url_dir_list = \
|
||||
ftp://$(gnu_rel_host)/gnu/coreutils
|
||||
|
||||
# Tests not to run as part of "make distcheck".
|
||||
local-checks-to-skip = \
|
||||
changelog-check \
|
||||
check-AUTHORS \
|
||||
makefile-check \
|
||||
makefile_path_separator_check \
|
||||
patch-check \
|
||||
sc_GPL_version \
|
||||
sc_always_defined_macros \
|
||||
sc_cast_of_alloca_return_value \
|
||||
sc_dd_max_sym_length \
|
||||
sc_error_exit_success \
|
||||
sc_file_system \
|
||||
sc_immutable_NEWS \
|
||||
sc_makefile_path_separator_check \
|
||||
sc_obsolete_symbols \
|
||||
sc_prohibit_S_IS_definition \
|
||||
sc_prohibit_atoi_atof \
|
||||
sc_prohibit_jm_in_m4 \
|
||||
sc_prohibit_quote_without_use \
|
||||
sc_prohibit_quotearg_without_use \
|
||||
sc_prohibit_stat_st_blocks \
|
||||
sc_root_tests \
|
||||
sc_space_tab \
|
||||
sc_sun_os_names \
|
||||
sc_system_h_headers \
|
||||
sc_tight_scope \
|
||||
sc_two_space_separator_in_usage \
|
||||
sc_error_message_uppercase \
|
||||
sc_program_name \
|
||||
sc_require_test_exit_idiom \
|
||||
sc_makefile_check \
|
||||
sc_useless_cpp_parens
|
||||
|
||||
useless_free_options = \
|
||||
--name=sexpr_free \
|
||||
--name=VIR_FREE \
|
||||
--name=xmlFree \
|
||||
--name=xmlXPathFreeContext \
|
||||
--name=xmlXPathFreeObject
|
||||
|
||||
# Avoid uses of write(2). Either switch to streams (fwrite), or use
|
||||
# the safewrite wrapper.
|
||||
sc_avoid_write:
|
||||
@if $(VC_LIST_EXCEPT) | grep '\.c$$' > /dev/null; then \
|
||||
grep '\<write *(' $$($(VC_LIST_EXCEPT) | grep '\.c$$') && \
|
||||
{ echo "$(ME): the above files use write;" \
|
||||
" consider using the safewrite wrapper instead" \
|
||||
1>&2; exit 1; } || :; \
|
||||
else :; \
|
||||
fi
|
||||
|
||||
# Use STREQ rather than comparing strcmp == 0, or != 0.
|
||||
# Similarly, use STREQLEN or STRPREFIX rather than strncmp.
|
||||
sc_prohibit_strcmp_and_strncmp:
|
||||
@re='strn?cmp *\(' \
|
||||
msg='use STREQ() in place of the above uses of str[n]cmp' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
# Use virAsprintf rather than a'sprintf since *strp is undefined on error.
|
||||
sc_prohibit_asprintf:
|
||||
@re='\<[a]sprintf\>' \
|
||||
msg='use virAsprintf, not a'sprintf \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
sc_prohibit_strncpy:
|
||||
@re='strncpy *\(' \
|
||||
msg='use virStrncpy, not strncpy' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
sc_prohibit_gethostname:
|
||||
@re='gethostname *\(' \
|
||||
msg='use virGetHostname, not gethostname' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
sc_prohibit_VIR_ERR_NO_MEMORY:
|
||||
@re='\<V''IR_ERR_NO_MEMORY\>' \
|
||||
msg='use virReportOOMError, not V'IR_ERR_NO_MEMORY \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
include $(srcdir)/Makefile.nonreentrant
|
||||
sc_prohibit_nonreentrant:
|
||||
@fail=0 ; \
|
||||
for i in $(NON_REENTRANT) ; \
|
||||
do \
|
||||
grep --before 2 --after 1 -nE "\<$$i\>[:space:]*\(" $$($(VC_LIST_EXCEPT)) && \
|
||||
fail=1 && echo "$(ME): use $${i}_r, not $${i}" || : ; \
|
||||
done ; \
|
||||
exit $$fail
|
||||
|
||||
# Prohibit the inclusion of <ctype.h>.
|
||||
sc_prohibit_ctype_h:
|
||||
@grep -E '^# *include *<ctype\.h>' $$($(VC_LIST_EXCEPT)) && \
|
||||
{ echo "$(ME): don't use ctype.h; instead, use c-ctype.h" \
|
||||
1>&2; exit 1; } || :
|
||||
|
||||
# Ensure that no C source file uses TABs for indentation.
|
||||
# Also match *.h.in files, to get libvirt.h.in.
|
||||
# Exclude files in gnulib, since they're imported.
|
||||
sc_TAB_in_indentation:
|
||||
@grep -lE '^ * ' /dev/null \
|
||||
$$($(VC_LIST_EXCEPT) \
|
||||
| grep -E '\.[ch](\.in)?$$' \
|
||||
| grep -v '^gnulib/') && \
|
||||
{ echo '$(ME): found TAB(s) used for indentation in C sources;'\
|
||||
'use spaces' 1>&2; exit 1; } || :
|
||||
|
||||
ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\
|
||||
|isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper
|
||||
|
||||
sc_avoid_ctype_macros:
|
||||
@grep -E '\b($(ctype_re)) *\(' /dev/null \
|
||||
$$($(VC_LIST_EXCEPT)) && \
|
||||
{ echo "$(ME): don't use ctype macros (use c-ctype.h)" \
|
||||
1>&2; exit 1; } || :
|
||||
|
||||
sc_prohibit_virBufferAdd_with_string_literal:
|
||||
@re='\<virBufferAdd *\([^,]+, *"[^"]' \
|
||||
msg='use virBufferAddLit, not virBufferAdd, with a string literal' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
# Not only do they fail to deal well with ipv6, but the gethostby*
|
||||
# functions are also not thread-safe.
|
||||
sc_prohibit_gethostby:
|
||||
@re='\<gethostby(addr|name2?) *\(' \
|
||||
msg='use getaddrinfo, not gethostby*' \
|
||||
$(_prohibit_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 \
|
||||
# |grep -vE '^(qsort|if|close|assert|fputc|free|N_|vir.*GetName|.*Unlock|virNodeListDevices|virHashRemoveEntry|freeaddrinfo|.*[fF]ree|xdrmem_create|xmlXPathFreeObject|virUUIDFormat|openvzSetProgramSentinal|polkit_action_unref)$'
|
||||
|
||||
msg_gen_function =
|
||||
msg_gen_function += DEBUG0
|
||||
msg_gen_function += DISABLE_fprintf
|
||||
msg_gen_function += ERROR
|
||||
msg_gen_function += ERROR0
|
||||
msg_gen_function += REMOTE_DEBUG
|
||||
msg_gen_function += ReportError
|
||||
msg_gen_function += VIR_FREE
|
||||
msg_gen_function += VIR_INFO
|
||||
msg_gen_function += VIR_USE_CPU
|
||||
msg_gen_function += errorf
|
||||
msg_gen_function += lxcError
|
||||
msg_gen_function += networkLog
|
||||
msg_gen_function += networkReportError
|
||||
msg_gen_function += oneError
|
||||
msg_gen_function += openvzError
|
||||
msg_gen_function += openvzLog
|
||||
msg_gen_function += qemudDispatchClientFailure
|
||||
msg_gen_function += qemudLog
|
||||
msg_gen_function += qemudReportError
|
||||
msg_gen_function += regerror
|
||||
msg_gen_function += remoteDispatchFormatError
|
||||
msg_gen_function += umlLog
|
||||
msg_gen_function += umlReportError
|
||||
msg_gen_function += virConfError
|
||||
msg_gen_function += virDomainReportError
|
||||
msg_gen_function += virSecurityReportError
|
||||
msg_gen_function += virHashError
|
||||
msg_gen_function += virLibConnError
|
||||
msg_gen_function += virLibDomainError
|
||||
msg_gen_function += virLog
|
||||
msg_gen_function += virNetworkReportError
|
||||
msg_gen_function += virNodeDeviceReportError
|
||||
msg_gen_function += virProxyError
|
||||
msg_gen_function += virRaiseError
|
||||
msg_gen_function += virReportErrorHelper
|
||||
msg_gen_function += virReportSystemError
|
||||
msg_gen_function += virSexprError
|
||||
msg_gen_function += virStorageLog
|
||||
msg_gen_function += virStorageReportError
|
||||
msg_gen_function += virXMLError
|
||||
msg_gen_function += virXenInotifyError
|
||||
msg_gen_function += virXenStoreError
|
||||
msg_gen_function += virXendError
|
||||
msg_gen_function += vshCloseLogFile
|
||||
msg_gen_function += xenUnifiedError
|
||||
msg_gen_function += xenXMError
|
||||
|
||||
# Uncomment the following and run "make syntax-check" to see diagnostics
|
||||
# that are not yet marked for translation, but that need to be rewritten
|
||||
# so that they are translatable.
|
||||
# msg_gen_function += error
|
||||
# msg_gen_function += fprintf
|
||||
# msg_gen_function += testError
|
||||
# msg_gen_function += virXenError
|
||||
# msg_gen_function += vshPrint
|
||||
# msg_gen_function += vshError
|
||||
|
||||
func_or := $(shell printf '$(msg_gen_function)'|tr -s '[[:space:]]' '|')
|
||||
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.
|
||||
# The sed filters eliminate false-positives like these:
|
||||
# _("...: "
|
||||
# "%s", _("no storage vol w..."
|
||||
sc_libvirt_unmarked_diagnostics:
|
||||
@grep -nE \
|
||||
'\<$(func_re) \([^"]*"[^"]*[a-z]{3}' $$($(VC_LIST_EXCEPT)) \
|
||||
| grep -v '_''(' && \
|
||||
{ echo '$(ME): found unmarked diagnostic(s)' 1>&2; \
|
||||
exit 1; } || :
|
||||
@{ grep -nE '\<$(func_re) *\(.*;$$' $$($(VC_LIST_EXCEPT)); \
|
||||
grep -A1 -nE '\<$(func_re) *\(.*,$$' $$($(VC_LIST_EXCEPT)); } \
|
||||
| sed 's/_("[^"][^"]*"//;s/[ ]"%s"//' \
|
||||
| grep '[ ]"' && \
|
||||
{ echo '$(ME): found unmarked diagnostic(s)' 1>&2; \
|
||||
exit 1; } || :
|
||||
|
||||
# Disallow trailing blank lines.
|
||||
sc_prohibit_trailing_blank_lines:
|
||||
@$(VC_LIST_EXCEPT) | xargs perl -ln -0777 -e \
|
||||
'/\n\n+$$/ and print $$ARGV' > $@-t
|
||||
@found=0; test -s $@-t && { found=1; cat $@-t 1>&2; \
|
||||
echo '$(ME): found trailing blank line(s)' 1>&2; }; \
|
||||
rm -f $@-t; \
|
||||
test $$found = 0
|
||||
|
||||
# We don't use this feature of maint.mk.
|
||||
prev_version_file = /dev/null
|
||||
|
||||
ifeq (0,$(MAKELEVEL))
|
||||
_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)
|
||||
_submodule_hash = sed 's/.//;s/ .*//'
|
||||
_update_required := $(shell \
|
||||
actual=$$(git submodule status | $(_submodule_hash)); \
|
||||
stamp="$$($(_submodule_hash) $(_curr_status) 2>/dev/null)"; \
|
||||
test "$$stamp" = "$$actual"; echo $$?)
|
||||
ifeq (1,$(_update_required))
|
||||
$(error gnulib update required; run ./autogen.sh first)
|
||||
endif
|
||||
endif
|
2009
configure.in
2009
configure.in
File diff suppressed because it is too large
Load Diff
12
daemon/.gitignore
vendored
12
daemon/.gitignore
vendored
@@ -1,12 +0,0 @@
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.la
|
||||
*.lo
|
||||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
libvirt_qemud
|
||||
libvirtd
|
||||
libvirtd.init
|
||||
libvirtd.logrotate
|
@@ -1,257 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
DAEMON_SOURCES = \
|
||||
event.c event.h \
|
||||
libvirtd.c libvirtd.h \
|
||||
remote.c remote.h \
|
||||
dispatch.c dispatch.h \
|
||||
stream.c stream.h \
|
||||
remote_dispatch_prototypes.h \
|
||||
remote_dispatch_table.h \
|
||||
remote_dispatch_args.h \
|
||||
remote_dispatch_ret.h \
|
||||
../src/remote/remote_protocol.c
|
||||
|
||||
AVAHI_SOURCES = \
|
||||
mdns.c mdns.h
|
||||
|
||||
DISTCLEANFILES =
|
||||
EXTRA_DIST = \
|
||||
remote_generate_stubs.pl \
|
||||
libvirtd.conf \
|
||||
libvirtd.init.in \
|
||||
libvirtd.policy-0 \
|
||||
libvirtd.policy-1 \
|
||||
libvirtd.sasl \
|
||||
libvirtd.sysconf \
|
||||
libvirtd.aug \
|
||||
libvirtd.logrotate.in \
|
||||
test_libvirtd.aug \
|
||||
$(AVAHI_SOURCES) \
|
||||
$(DAEMON_SOURCES)
|
||||
|
||||
BUILT_SOURCES =
|
||||
|
||||
if WITH_LIBVIRTD
|
||||
|
||||
sbin_PROGRAMS = libvirtd
|
||||
|
||||
confdir = $(sysconfdir)/libvirt/
|
||||
conf_DATA = libvirtd.conf
|
||||
|
||||
augeasdir = $(datadir)/augeas/lenses
|
||||
augeas_DATA = libvirtd.aug
|
||||
|
||||
augeastestsdir = $(datadir)/augeas/lenses/tests
|
||||
augeastests_DATA = test_libvirtd.aug
|
||||
|
||||
libvirtd_SOURCES = $(DAEMON_SOURCES)
|
||||
|
||||
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
|
||||
libvirtd_CFLAGS = \
|
||||
-I$(top_srcdir)/gnulib/lib -I../gnulib/lib \
|
||||
-I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/util \
|
||||
-I$(top_srcdir)/src/conf \
|
||||
-I$(top_srcdir)/src/remote \
|
||||
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
|
||||
$(POLKIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) -DLOCAL_STATE_DIR="\"$(localstatedir)\"" \
|
||||
$(COVERAGE_CFLAGS) \
|
||||
-DSYSCONF_DIR="\"$(sysconfdir)\"" \
|
||||
-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" \
|
||||
-DREMOTE_PID_FILE="\"$(REMOTE_PID_FILE)\"" \
|
||||
-DGETTEXT_PACKAGE=\"$(PACKAGE)\"
|
||||
|
||||
libvirtd_LDFLAGS = \
|
||||
$(WARN_CFLAGS) \
|
||||
$(COVERAGE_LDFLAGS)
|
||||
|
||||
libvirtd_LDADD = \
|
||||
$(LIBXML_LIBS) \
|
||||
$(GNUTLS_LIBS) \
|
||||
$(SASL_LIBS) \
|
||||
$(POLKIT_LIBS)
|
||||
|
||||
libvirtd_LDADD += ../src/libvirt_util.la
|
||||
|
||||
if WITH_DRIVER_MODULES
|
||||
libvirtd_LDADD += ../src/libvirt_driver.la
|
||||
else
|
||||
if WITH_QEMU
|
||||
libvirtd_LDADD += ../src/libvirt_driver_qemu.la
|
||||
endif
|
||||
|
||||
if WITH_LXC
|
||||
libvirtd_LDADD += ../src/libvirt_driver_lxc.la
|
||||
endif
|
||||
|
||||
if WITH_UML
|
||||
libvirtd_LDADD += ../src/libvirt_driver_uml.la
|
||||
endif
|
||||
|
||||
if WITH_ONE
|
||||
libvirtd_LDADD += ../src/libvirt_driver_one.la
|
||||
endif
|
||||
|
||||
if WITH_STORAGE_DIR
|
||||
libvirtd_LDADD += ../src/libvirt_driver_storage.la
|
||||
endif
|
||||
|
||||
if WITH_NETWORK
|
||||
libvirtd_LDADD += ../src/libvirt_driver_network.la
|
||||
endif
|
||||
|
||||
if WITH_NETCF
|
||||
libvirtd_LDADD += ../src/libvirt_driver_interface.la
|
||||
endif
|
||||
|
||||
if WITH_NODE_DEVICES
|
||||
libvirtd_LDADD += ../src/libvirt_driver_nodedev.la
|
||||
endif
|
||||
|
||||
if WITH_SECRETS
|
||||
libvirtd_LDADD += ../src/libvirt_driver_secret.la
|
||||
endif
|
||||
endif
|
||||
|
||||
libvirtd_LDADD += ../src/libvirt.la
|
||||
|
||||
if HAVE_POLKIT
|
||||
if HAVE_POLKIT0
|
||||
policydir = $(datadir)/PolicyKit/policy
|
||||
policyfile = libvirtd.policy-0
|
||||
else
|
||||
policydir = $(datadir)/polkit-1/actions
|
||||
policyfile = libvirtd.policy-1
|
||||
endif
|
||||
endif
|
||||
|
||||
if HAVE_AVAHI
|
||||
libvirtd_SOURCES += $(AVAHI_SOURCES)
|
||||
libvirtd_CFLAGS += $(AVAHI_CFLAGS)
|
||||
libvirtd_LDADD += $(AVAHI_LIBS)
|
||||
endif
|
||||
|
||||
|
||||
install-data-local: install-init install-data-sasl install-data-polkit \
|
||||
install-logrotate
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt
|
||||
|
||||
uninstall-local:: uninstall-init uninstall-data-sasl uninstall-data-polkit
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
|
||||
|
||||
if HAVE_POLKIT
|
||||
install-data-polkit:: install-init
|
||||
mkdir -p $(DESTDIR)$(policydir)
|
||||
$(INSTALL_DATA) $(srcdir)/$(policyfile) $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
uninstall-data-polkit:: install-init
|
||||
rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
else
|
||||
install-data-polkit::
|
||||
uninstall-data-polkit::
|
||||
endif
|
||||
|
||||
|
||||
remote.c: remote_dispatch_prototypes.h \
|
||||
remote_dispatch_table.h \
|
||||
remote_dispatch_args.h \
|
||||
remote_dispatch_ret.h
|
||||
|
||||
REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
|
||||
|
||||
remote_dispatch_prototypes.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
|
||||
perl -w $(srcdir)/remote_generate_stubs.pl -p $(REMOTE_PROTOCOL) > $@
|
||||
|
||||
remote_dispatch_table.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
|
||||
perl -w $(srcdir)/remote_generate_stubs.pl -t $(REMOTE_PROTOCOL) > $@
|
||||
|
||||
remote_dispatch_args.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
|
||||
perl -w $(srcdir)/remote_generate_stubs.pl -a $(REMOTE_PROTOCOL) > $@
|
||||
|
||||
remote_dispatch_ret.h: $(srcdir)/remote_generate_stubs.pl $(REMOTE_PROTOCOL)
|
||||
perl -w $(srcdir)/remote_generate_stubs.pl -r $(REMOTE_PROTOCOL) > $@
|
||||
|
||||
BUILT_SOURCES += libvirtd.logrotate
|
||||
|
||||
libvirtd.logrotate: libvirtd.logrotate.in
|
||||
sed \
|
||||
-e s!\@localstatedir\@!@localstatedir@!g \
|
||||
< $< > $@-t
|
||||
mv $@-t $@
|
||||
|
||||
install-logrotate: libvirtd.logrotate
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu/
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/lxc/
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/uml/
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/logrotate.d/
|
||||
$(INSTALL_DATA) $< $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
install-init: libvirtd.init
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d
|
||||
$(INSTALL_SCRIPT) libvirtd.init \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
|
||||
$(INSTALL_SCRIPT) $(srcdir)/libvirtd.sysconf \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
|
||||
uninstall-init:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
|
||||
BUILT_SOURCES += libvirtd.init
|
||||
|
||||
libvirtd.init: libvirtd.init.in
|
||||
sed \
|
||||
-e s!\@localstatedir\@!@localstatedir@!g \
|
||||
-e s!\@sbindir\@!@sbindir@!g \
|
||||
-e s!\@sysconfdir\@!@sysconfdir@!g \
|
||||
< $< > $@-t
|
||||
chmod a+x $@-t
|
||||
mv $@-t $@
|
||||
|
||||
check-local:
|
||||
test -x '$(AUGPARSE)' \
|
||||
&& '$(AUGPARSE)' -I $(srcdir) $(srcdir)/test_libvirtd.aug || :
|
||||
|
||||
else
|
||||
|
||||
install-init:
|
||||
uninstall-init:
|
||||
libvirtd.init:
|
||||
|
||||
endif # LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
|
||||
# This must be added last, since functions it provides/replaces
|
||||
# are used by nearly every other library.
|
||||
libvirtd_LDADD += ../gnulib/lib/libgnu.la $(LIBSOCKET)
|
||||
|
||||
else # WITH_LIBVIRTD
|
||||
install-data-local: install-data-sasl
|
||||
uninstall-local:: uninstall-data-sasl
|
||||
endif # WITH_LIBVIRTD
|
||||
|
||||
# This is needed for clients too, so can't wrap in
|
||||
# the WITH_LIBVIRTD conditional
|
||||
if HAVE_SASL
|
||||
install-data-sasl:
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/sasl2/
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sasl $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
|
||||
|
||||
uninstall-data-sasl:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sasl2/
|
||||
else
|
||||
install-data-sasl:
|
||||
uninstall-data-sasl:
|
||||
endif
|
||||
|
||||
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
CLEANFILES += *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
|
@@ -1,52 +0,0 @@
|
||||
|
||||
Threading in the libvirtd daemon
|
||||
================================
|
||||
|
||||
To allow efficient processing of RPC requests, the libvirtd daemon
|
||||
makes use of threads.
|
||||
|
||||
- The process leader. This is the initial thread of control
|
||||
when the daemon starts running. It is responsible for
|
||||
initializing all the state, and starting the event loop.
|
||||
Once that's all done, this thread does nothing except
|
||||
wait for the event loop to quit, thus indicating an orderly
|
||||
shutdown is required.
|
||||
|
||||
- The event loop. This thread runs the event loop, sitting
|
||||
in poll() on all monitored file handles, and calculating
|
||||
and dispatching any timers that may be registered. When
|
||||
this thread quits, the entire daemon will shutdown.
|
||||
|
||||
- The workers. These 'n' threads all sit around waiting to
|
||||
process incoming RPC requests. Since RPC requests may take
|
||||
a long time to complete, with long idle periods, there will
|
||||
be quite a few workers running.
|
||||
|
||||
The use of threads obviously requires locking to ensure safety when
|
||||
accessing/changing data structures.
|
||||
|
||||
- the top level lock is on 'struct qemud_server'. This must be
|
||||
held before acquiring any other lock
|
||||
|
||||
- Each 'struct qemud_client' object has a lock. The server lock
|
||||
must be held before acquiring it. Once the client lock is acquired
|
||||
the server lock can (optionally) be dropped.
|
||||
|
||||
- The event loop has its own self-contained lock. You can ignore
|
||||
this as a caller of virEvent APIs.
|
||||
|
||||
|
||||
The server lock is used in conjunction with a condition variable
|
||||
to pass jobs from the event loop thread to the workers. The main
|
||||
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 onto the 'dx' job queue for the
|
||||
associated client object. The job condition will be signalled and
|
||||
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
|
||||
with its other work. Critically important, is that now libvirt
|
||||
API call will ever be made with the server or client locks held.
|
||||
|
||||
-- End
|
@@ -1,668 +0,0 @@
|
||||
/*
|
||||
* dispatch.h: RPC message dispatching infrastructure
|
||||
*
|
||||
* Copyright (C) 2007, 2008, 2009 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Richard W.M. Jones <rjones@redhat.com>
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dispatch.h"
|
||||
#include "remote.h"
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
/* Convert a libvirt virError object into wire format */
|
||||
static void
|
||||
remoteDispatchCopyError (remote_error *rerr,
|
||||
virErrorPtr verr)
|
||||
{
|
||||
rerr->code = verr->code;
|
||||
rerr->domain = verr->domain;
|
||||
rerr->message = verr->message ? malloc(sizeof(char*)) : NULL;
|
||||
if (rerr->message) *rerr->message = strdup(verr->message);
|
||||
rerr->level = verr->level;
|
||||
rerr->str1 = verr->str1 ? malloc(sizeof(char*)) : NULL;
|
||||
if (rerr->str1) *rerr->str1 = strdup(verr->str1);
|
||||
rerr->str2 = verr->str2 ? malloc(sizeof(char*)) : NULL;
|
||||
if (rerr->str2) *rerr->str2 = strdup(verr->str2);
|
||||
rerr->str3 = verr->str3 ? malloc(sizeof(char*)) : NULL;
|
||||
if (rerr->str3) *rerr->str3 = strdup(verr->str3);
|
||||
rerr->int1 = verr->int1;
|
||||
rerr->int2 = verr->int2;
|
||||
}
|
||||
|
||||
|
||||
/* A set of helpers for sending back errors to client
|
||||
in various ways .... */
|
||||
|
||||
static void
|
||||
remoteDispatchStringError (remote_error *rerr,
|
||||
int code, const char *msg)
|
||||
{
|
||||
virError verr;
|
||||
|
||||
memset(&verr, 0, sizeof verr);
|
||||
|
||||
/* Construct the dummy libvirt virError. */
|
||||
verr.code = code;
|
||||
verr.domain = VIR_FROM_REMOTE;
|
||||
verr.message = (char *)msg;
|
||||
verr.level = VIR_ERR_ERROR;
|
||||
verr.str1 = (char *)msg;
|
||||
|
||||
remoteDispatchCopyError(rerr, &verr);
|
||||
}
|
||||
|
||||
|
||||
void remoteDispatchAuthError (remote_error *rerr)
|
||||
{
|
||||
remoteDispatchStringError (rerr, VIR_ERR_AUTH_FAILED, "authentication failed");
|
||||
}
|
||||
|
||||
|
||||
void remoteDispatchFormatError (remote_error *rerr,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char msgbuf[1024];
|
||||
char *msg = msgbuf;
|
||||
|
||||
va_start (args, fmt);
|
||||
vsnprintf (msgbuf, sizeof msgbuf, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
remoteDispatchStringError (rerr, VIR_ERR_RPC, msg);
|
||||
}
|
||||
|
||||
|
||||
void remoteDispatchGenericError (remote_error *rerr)
|
||||
{
|
||||
remoteDispatchStringError(rerr,
|
||||
VIR_ERR_INTERNAL_ERROR,
|
||||
"library function returned error but did not set virterror");
|
||||
}
|
||||
|
||||
|
||||
void remoteDispatchOOMError (remote_error *rerr)
|
||||
{
|
||||
remoteDispatchStringError(rerr,
|
||||
VIR_ERR_NO_MEMORY,
|
||||
"out of memory");
|
||||
}
|
||||
|
||||
|
||||
void remoteDispatchConnError (remote_error *rerr,
|
||||
virConnectPtr conn)
|
||||
{
|
||||
virErrorPtr verr;
|
||||
|
||||
if (conn)
|
||||
verr = virConnGetLastError(conn);
|
||||
else
|
||||
verr = virGetLastError();
|
||||
if (verr)
|
||||
remoteDispatchCopyError(rerr, verr);
|
||||
else
|
||||
remoteDispatchGenericError(rerr);
|
||||
}
|
||||
|
||||
static int
|
||||
remoteSerializeError(struct qemud_client *client,
|
||||
remote_error *rerr,
|
||||
int program,
|
||||
int version,
|
||||
int procedure,
|
||||
int type,
|
||||
int serial)
|
||||
{
|
||||
XDR xdr;
|
||||
unsigned int len;
|
||||
struct qemud_client_message *msg = NULL;
|
||||
|
||||
DEBUG("prog=%d ver=%d proc=%d type=%d serial=%d, msg=%s",
|
||||
program, version, procedure, type, serial,
|
||||
rerr->message ? *rerr->message : "(none)");
|
||||
|
||||
if (VIR_ALLOC(msg) < 0)
|
||||
goto fatal_error;
|
||||
|
||||
/* Return header. */
|
||||
msg->hdr.prog = program;
|
||||
msg->hdr.vers = version;
|
||||
msg->hdr.proc = procedure;
|
||||
msg->hdr.type = type;
|
||||
msg->hdr.serial = serial;
|
||||
msg->hdr.status = REMOTE_ERROR;
|
||||
|
||||
msg->bufferLength = sizeof(msg->buffer);
|
||||
|
||||
/* Serialise the return header. */
|
||||
xdrmem_create (&xdr,
|
||||
msg->buffer,
|
||||
msg->bufferLength,
|
||||
XDR_ENCODE);
|
||||
|
||||
len = 0; /* We'll come back and write this later. */
|
||||
if (!xdr_u_int (&xdr, &len))
|
||||
goto xdr_error;
|
||||
|
||||
if (!xdr_remote_message_header (&xdr, &msg->hdr))
|
||||
goto xdr_error;
|
||||
|
||||
/* Error was not set, so synthesize a generic error message. */
|
||||
if (rerr->code == 0)
|
||||
remoteDispatchGenericError(rerr);
|
||||
|
||||
if (!xdr_remote_error (&xdr, rerr))
|
||||
goto xdr_error;
|
||||
|
||||
/* Write the length word. */
|
||||
len = xdr_getpos (&xdr);
|
||||
if (xdr_setpos (&xdr, 0) == 0)
|
||||
goto xdr_error;
|
||||
|
||||
if (!xdr_u_int (&xdr, &len))
|
||||
goto xdr_error;
|
||||
|
||||
xdr_destroy (&xdr);
|
||||
|
||||
msg->bufferLength = len;
|
||||
msg->bufferOffset = 0;
|
||||
|
||||
/* Put reply on end of tx queue to send out */
|
||||
qemudClientMessageQueuePush(&client->tx, msg);
|
||||
qemudUpdateClientEvent(client);
|
||||
xdr_free((xdrproc_t)xdr_remote_error, (char *)rerr);
|
||||
|
||||
return 0;
|
||||
|
||||
xdr_error:
|
||||
xdr_destroy(&xdr);
|
||||
VIR_FREE(msg);
|
||||
fatal_error:
|
||||
xdr_free((xdrproc_t)xdr_remote_error, (char *)rerr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: the client to send the error to
|
||||
* @rerr: the error object to send
|
||||
* @req: the message this error is in reply to
|
||||
*
|
||||
* Send an error message to the client
|
||||
*
|
||||
* Returns 0 if the error was sent, -1 upon fatal error
|
||||
*/
|
||||
int
|
||||
remoteSerializeReplyError(struct qemud_client *client,
|
||||
remote_error *rerr,
|
||||
remote_message_header *req) {
|
||||
/*
|
||||
* For data streams, errors are sent back as data streams
|
||||
* For method calls, errors are sent back as method replies
|
||||
*/
|
||||
return remoteSerializeError(client,
|
||||
rerr,
|
||||
req->prog,
|
||||
req->vers,
|
||||
req->proc,
|
||||
req->type == REMOTE_STREAM ? REMOTE_STREAM : REMOTE_REPLY,
|
||||
req->serial);
|
||||
}
|
||||
|
||||
int
|
||||
remoteSerializeStreamError(struct qemud_client *client,
|
||||
remote_error *rerr,
|
||||
int proc,
|
||||
int serial)
|
||||
{
|
||||
return remoteSerializeError(client,
|
||||
rerr,
|
||||
REMOTE_PROGRAM,
|
||||
REMOTE_PROTOCOL_VERSION,
|
||||
proc,
|
||||
REMOTE_STREAM,
|
||||
serial);
|
||||
}
|
||||
|
||||
/*
|
||||
* @msg: the complete incoming message, whose header to decode
|
||||
*
|
||||
* Decodes the header part of the client message, but does not
|
||||
* validate the decoded fields in the header. It expects
|
||||
* bufferLength to refer to length of the data packet. Upon
|
||||
* return bufferOffset will refer to the amount of the packet
|
||||
* consumed by decoding of the header.
|
||||
*
|
||||
* returns 0 if successfully decoded, -1 upon fatal error
|
||||
*/
|
||||
int
|
||||
remoteDecodeClientMessageHeader (struct qemud_client_message *msg)
|
||||
{
|
||||
XDR xdr;
|
||||
int ret = -1;
|
||||
|
||||
msg->bufferOffset = REMOTE_MESSAGE_HEADER_XDR_LEN;
|
||||
|
||||
/* Parse the header. */
|
||||
xdrmem_create (&xdr,
|
||||
msg->buffer + msg->bufferOffset,
|
||||
msg->bufferLength - msg->bufferOffset,
|
||||
XDR_DECODE);
|
||||
|
||||
if (!xdr_remote_message_header (&xdr, &msg->hdr))
|
||||
goto cleanup;
|
||||
|
||||
msg->bufferOffset += xdr_getpos(&xdr);
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
xdr_destroy(&xdr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @msg: the outgoing message, whose header to encode
|
||||
*
|
||||
* Encodes the header part of the client message, setting the
|
||||
* message offset ready to encode the payload. Leaves space
|
||||
* for the length field later. Upon return bufferLength will
|
||||
* refer to the total available space for message, while
|
||||
* bufferOffset will refer to current space used by header
|
||||
*
|
||||
* returns 0 if successfully encoded, -1 upon fatal error
|
||||
*/
|
||||
int
|
||||
remoteEncodeClientMessageHeader (struct qemud_client_message *msg)
|
||||
{
|
||||
XDR xdr;
|
||||
int ret = -1;
|
||||
unsigned int len = 0;
|
||||
|
||||
msg->bufferLength = sizeof(msg->buffer);
|
||||
msg->bufferOffset = 0;
|
||||
|
||||
/* Format the header. */
|
||||
xdrmem_create (&xdr,
|
||||
msg->buffer,
|
||||
msg->bufferLength,
|
||||
XDR_ENCODE);
|
||||
|
||||
/* The real value is filled in shortly */
|
||||
if (!xdr_u_int (&xdr, &len)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!xdr_remote_message_header (&xdr, &msg->hdr))
|
||||
goto cleanup;
|
||||
|
||||
len = xdr_getpos(&xdr);
|
||||
xdr_setpos(&xdr, 0);
|
||||
|
||||
/* Fill in current length - may be re-written later
|
||||
* if a payload is added
|
||||
*/
|
||||
if (!xdr_u_int (&xdr, &len)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
msg->bufferOffset += len;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
xdr_destroy(&xdr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
remoteDispatchClientCall (struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
struct qemud_client_message *msg);
|
||||
|
||||
|
||||
/*
|
||||
* @server: the unlocked server object
|
||||
* @client: the locked client object
|
||||
* @msg: the complete incoming message packet, with header already decoded
|
||||
*
|
||||
* This function gets called from qemud when it pulls a incoming
|
||||
* remote protocol messsage off the dispatch queue for processing.
|
||||
*
|
||||
* The @msg parameter must have had its header decoded already by
|
||||
* calling remoteDecodeClientMessageHeader
|
||||
*
|
||||
* Returns 0 if the message was dispatched, -1 upon fatal error
|
||||
*/
|
||||
int
|
||||
remoteDispatchClientRequest (struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
struct qemud_client_message *msg)
|
||||
{
|
||||
int ret;
|
||||
remote_error rerr;
|
||||
|
||||
DEBUG("prog=%d ver=%d type=%d satus=%d serial=%d proc=%d",
|
||||
msg->hdr.prog, msg->hdr.vers, msg->hdr.type,
|
||||
msg->hdr.status, msg->hdr.serial, msg->hdr.proc);
|
||||
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
|
||||
/* Check version, etc. */
|
||||
if (msg->hdr.prog != REMOTE_PROGRAM) {
|
||||
remoteDispatchFormatError (&rerr,
|
||||
_("program mismatch (actual %x, expected %x)"),
|
||||
msg->hdr.prog, REMOTE_PROGRAM);
|
||||
goto error;
|
||||
}
|
||||
if (msg->hdr.vers != REMOTE_PROTOCOL_VERSION) {
|
||||
remoteDispatchFormatError (&rerr,
|
||||
_("version mismatch (actual %x, expected %x)"),
|
||||
msg->hdr.vers, REMOTE_PROTOCOL_VERSION);
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (msg->hdr.type) {
|
||||
case REMOTE_CALL:
|
||||
return remoteDispatchClientCall(server, client, msg);
|
||||
|
||||
case REMOTE_STREAM:
|
||||
/* Since stream data is non-acked, async, we may continue to received
|
||||
* stream packets after we closed down a stream. Just drop & ignore
|
||||
* these.
|
||||
*/
|
||||
VIR_INFO("Ignoring unexpected stream data serial=%d proc=%d status=%d",
|
||||
msg->hdr.serial, msg->hdr.proc, msg->hdr.status);
|
||||
qemudClientMessageRelease(client, msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
remoteDispatchFormatError (&rerr, _("type (%d) != REMOTE_CALL"),
|
||||
(int) msg->hdr.type);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
ret = remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
||||
|
||||
if (ret >= 0)
|
||||
VIR_FREE(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @server: the unlocked server object
|
||||
* @client: the locked client object
|
||||
* @msg: the complete incoming method call, with header already decoded
|
||||
*
|
||||
* This method is used to dispatch an message representing an
|
||||
* incoming method call from a client. It decodes the payload
|
||||
* to obtain method call arguments, invokves the method and
|
||||
* then sends a reply packet with the return values
|
||||
*
|
||||
* Returns 0 if the reply was sent, or -1 upon fatal error
|
||||
*/
|
||||
int
|
||||
remoteDispatchClientCall (struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
struct qemud_client_message *msg)
|
||||
{
|
||||
XDR xdr;
|
||||
remote_error rerr;
|
||||
dispatch_args args;
|
||||
dispatch_ret ret;
|
||||
const dispatch_data *data = NULL;
|
||||
int rv = -1;
|
||||
unsigned int len;
|
||||
virConnectPtr conn = NULL;
|
||||
|
||||
memset(&args, 0, sizeof args);
|
||||
memset(&ret, 0, sizeof ret);
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
|
||||
if (msg->hdr.status != REMOTE_OK) {
|
||||
remoteDispatchFormatError (&rerr, _("status (%d) != REMOTE_OK"),
|
||||
(int) msg->hdr.status);
|
||||
goto rpc_error;
|
||||
}
|
||||
|
||||
/* If client is marked as needing auth, don't allow any RPC ops,
|
||||
* except for authentication ones
|
||||
*/
|
||||
if (client->auth) {
|
||||
if (msg->hdr.proc != REMOTE_PROC_AUTH_LIST &&
|
||||
msg->hdr.proc != REMOTE_PROC_AUTH_SASL_INIT &&
|
||||
msg->hdr.proc != REMOTE_PROC_AUTH_SASL_START &&
|
||||
msg->hdr.proc != REMOTE_PROC_AUTH_SASL_STEP &&
|
||||
msg->hdr.proc != REMOTE_PROC_AUTH_POLKIT
|
||||
) {
|
||||
/* Explicitly *NOT* calling remoteDispatchAuthError() because
|
||||
we want back-compatability with libvirt clients which don't
|
||||
support the VIR_ERR_AUTH_FAILED error code */
|
||||
remoteDispatchFormatError (&rerr, "%s", _("authentication required"));
|
||||
goto rpc_error;
|
||||
}
|
||||
}
|
||||
|
||||
data = remoteGetDispatchData(msg->hdr.proc);
|
||||
|
||||
if (!data) {
|
||||
remoteDispatchFormatError (&rerr, _("unknown procedure: %d"),
|
||||
msg->hdr.proc);
|
||||
goto rpc_error;
|
||||
}
|
||||
|
||||
/* De-serialize payload with args from the wire message */
|
||||
xdrmem_create (&xdr,
|
||||
msg->buffer + msg->bufferOffset,
|
||||
msg->bufferLength - msg->bufferOffset,
|
||||
XDR_DECODE);
|
||||
if (!((data->args_filter)(&xdr, &args))) {
|
||||
xdr_destroy (&xdr);
|
||||
remoteDispatchFormatError (&rerr, "%s", _("parse args failed"));
|
||||
goto rpc_error;
|
||||
}
|
||||
xdr_destroy (&xdr);
|
||||
|
||||
/* Call function. */
|
||||
conn = client->conn;
|
||||
virMutexUnlock(&client->lock);
|
||||
|
||||
/*
|
||||
* When the RPC handler is called:
|
||||
*
|
||||
* - Server object is unlocked
|
||||
* - Client object is unlocked
|
||||
*
|
||||
* Without locking, it is safe to use:
|
||||
*
|
||||
* 'conn', 'rerr', 'args and 'ret'
|
||||
*/
|
||||
rv = (data->fn)(server, client, conn, &msg->hdr, &rerr, &args, &ret);
|
||||
|
||||
virMutexLock(&server->lock);
|
||||
virMutexLock(&client->lock);
|
||||
virMutexUnlock(&server->lock);
|
||||
|
||||
xdr_free (data->args_filter, (char*)&args);
|
||||
|
||||
if (rv < 0)
|
||||
goto rpc_error;
|
||||
|
||||
/* Return header. We're re-using same message object, so
|
||||
* only need to tweak type/status fields */
|
||||
/*msg->hdr.prog = msg->hdr.prog;*/
|
||||
/*msg->hdr.vers = msg->hdr.vers;*/
|
||||
/*msg->hdr.proc = msg->hdr.proc;*/
|
||||
msg->hdr.type = REMOTE_REPLY;
|
||||
/*msg->hdr.serial = msg->hdr.serial;*/
|
||||
msg->hdr.status = REMOTE_OK;
|
||||
|
||||
if (remoteEncodeClientMessageHeader(msg) < 0) {
|
||||
xdr_free (data->ret_filter, (char*)&ret);
|
||||
goto fatal_error;
|
||||
}
|
||||
|
||||
|
||||
/* Now for the payload */
|
||||
xdrmem_create (&xdr,
|
||||
msg->buffer,
|
||||
msg->bufferLength,
|
||||
XDR_ENCODE);
|
||||
|
||||
if (xdr_setpos(&xdr, msg->bufferOffset) == 0)
|
||||
goto xdr_error;
|
||||
|
||||
/* If OK, serialise return structure, if error serialise error. */
|
||||
/* Serialise reply data */
|
||||
if (!((data->ret_filter) (&xdr, &ret)))
|
||||
goto xdr_error;
|
||||
|
||||
/* Update the length word. */
|
||||
msg->bufferOffset += xdr_getpos (&xdr);
|
||||
len = msg->bufferOffset;
|
||||
if (xdr_setpos (&xdr, 0) == 0)
|
||||
goto xdr_error;
|
||||
|
||||
if (!xdr_u_int (&xdr, &len))
|
||||
goto xdr_error;
|
||||
|
||||
xdr_destroy (&xdr);
|
||||
xdr_free (data->ret_filter, (char*)&ret);
|
||||
|
||||
/* Reset ready for I/O */
|
||||
msg->bufferLength = len;
|
||||
msg->bufferOffset = 0;
|
||||
|
||||
/* Put reply on end of tx queue to send out */
|
||||
qemudClientMessageQueuePush(&client->tx, msg);
|
||||
qemudUpdateClientEvent(client);
|
||||
|
||||
return 0;
|
||||
|
||||
rpc_error:
|
||||
/* Semi-bad stuff happened, we can still try to send back
|
||||
* an RPC error message to client */
|
||||
rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
||||
|
||||
if (rv >= 0)
|
||||
VIR_FREE(msg);
|
||||
|
||||
return rv;
|
||||
|
||||
xdr_error:
|
||||
/* Seriously bad stuff happened, so we'll kill off this client
|
||||
and not send back any RPC error */
|
||||
xdr_free (data->ret_filter, (char*)&ret);
|
||||
xdr_destroy (&xdr);
|
||||
fatal_error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
remoteSendStreamData(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
const char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct qemud_client_message *msg;
|
||||
XDR xdr;
|
||||
|
||||
DEBUG("client=%p stream=%p data=%p len=%d", client, stream, data, len);
|
||||
|
||||
if (VIR_ALLOC(msg) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return header. We're re-using same message object, so
|
||||
* only need to tweak type/status fields */
|
||||
msg->hdr.prog = REMOTE_PROGRAM;
|
||||
msg->hdr.vers = REMOTE_PROTOCOL_VERSION;
|
||||
msg->hdr.proc = stream->procedure;
|
||||
msg->hdr.type = REMOTE_STREAM;
|
||||
msg->hdr.serial = stream->serial;
|
||||
/*
|
||||
* NB
|
||||
* data != NULL + len > 0 => REMOTE_CONTINUE (Sending back data)
|
||||
* data != NULL + len == 0 => REMOTE_CONTINUE (Sending read EOF)
|
||||
* data == NULL => REMOTE_OK (Sending finish handshake confirmation)
|
||||
*/
|
||||
msg->hdr.status = data ? REMOTE_CONTINUE : REMOTE_OK;
|
||||
|
||||
if (remoteEncodeClientMessageHeader(msg) < 0)
|
||||
goto fatal_error;
|
||||
|
||||
if (data && len) {
|
||||
if ((msg->bufferLength - msg->bufferOffset) < len)
|
||||
goto fatal_error;
|
||||
|
||||
/* Now for the payload */
|
||||
xdrmem_create (&xdr,
|
||||
msg->buffer,
|
||||
msg->bufferLength,
|
||||
XDR_ENCODE);
|
||||
|
||||
/* Skip over existing header already written */
|
||||
if (xdr_setpos(&xdr, msg->bufferOffset) == 0)
|
||||
goto xdr_error;
|
||||
|
||||
memcpy(msg->buffer + msg->bufferOffset, data, len);
|
||||
msg->bufferOffset += len;
|
||||
|
||||
/* Update the length word. */
|
||||
len = msg->bufferOffset;
|
||||
if (xdr_setpos (&xdr, 0) == 0)
|
||||
goto xdr_error;
|
||||
|
||||
if (!xdr_u_int (&xdr, &len))
|
||||
goto xdr_error;
|
||||
|
||||
xdr_destroy (&xdr);
|
||||
|
||||
DEBUG("Total %d", msg->bufferOffset);
|
||||
}
|
||||
if (data)
|
||||
msg->streamTX = 1;
|
||||
|
||||
/* Reset ready for I/O */
|
||||
msg->bufferLength = msg->bufferOffset;
|
||||
msg->bufferOffset = 0;
|
||||
|
||||
/* Put reply on end of tx queue to send out */
|
||||
qemudClientMessageQueuePush(&client->tx, msg);
|
||||
qemudUpdateClientEvent(client);
|
||||
|
||||
return 0;
|
||||
|
||||
xdr_error:
|
||||
xdr_destroy (&xdr);
|
||||
fatal_error:
|
||||
VIR_FREE(msg);
|
||||
return -1;
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* dispatch.h: RPC message dispatching infrastructure
|
||||
*
|
||||
* Copyright (C) 2007, 2008, 2009 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Richard W.M. Jones <rjones@redhat.com>
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __LIBVIRTD_DISPATCH_H__
|
||||
#define __LIBVIRTD_DISPATCH_H__
|
||||
|
||||
|
||||
#include "libvirtd.h"
|
||||
|
||||
|
||||
int
|
||||
remoteDecodeClientMessageHeader (struct qemud_client_message *req);
|
||||
int
|
||||
remoteEncodeClientMessageHeader (struct qemud_client_message *req);
|
||||
|
||||
int
|
||||
remoteDispatchClientRequest (struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
struct qemud_client_message *req);
|
||||
|
||||
|
||||
void remoteDispatchFormatError (remote_error *rerr,
|
||||
const char *fmt, ...)
|
||||
ATTRIBUTE_FMT_PRINTF(2, 3);
|
||||
|
||||
void remoteDispatchAuthError (remote_error *rerr);
|
||||
void remoteDispatchGenericError (remote_error *rerr);
|
||||
void remoteDispatchOOMError (remote_error *rerr);
|
||||
void remoteDispatchConnError (remote_error *rerr,
|
||||
virConnectPtr conn);
|
||||
|
||||
|
||||
int
|
||||
remoteSerializeReplyError(struct qemud_client *client,
|
||||
remote_error *rerr,
|
||||
remote_message_header *req);
|
||||
int
|
||||
remoteSerializeStreamError(struct qemud_client *client,
|
||||
remote_error *rerr,
|
||||
int proc,
|
||||
int serial);
|
||||
|
||||
/* Having this here is dubious. It should be in remote.h
|
||||
* but qemud.c shouldn't depend on that header directly.
|
||||
* Refactor this later to deal with this properly.
|
||||
*/
|
||||
int remoteRelayDomainEvent (virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
int event,
|
||||
int detail,
|
||||
void *opaque);
|
||||
|
||||
|
||||
int
|
||||
remoteSendStreamData(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
const char *data,
|
||||
unsigned int len);
|
||||
|
||||
#endif /* __LIBVIRTD_DISPATCH_H__ */
|
712
daemon/event.c
712
daemon/event.c
@@ -1,712 +0,0 @@
|
||||
/*
|
||||
* event.c: event loop for monitoring file handles
|
||||
*
|
||||
* Copyright (C) 2007 Daniel P. Berrange
|
||||
* Copyright (C) 2007 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "threads.h"
|
||||
#include "logging.h"
|
||||
#include "event.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
|
||||
#define EVENT_DEBUG(fmt, ...) DEBUG(fmt, __VA_ARGS__)
|
||||
|
||||
static int virEventInterruptLocked(void);
|
||||
|
||||
/* State for a single file handle being monitored */
|
||||
struct virEventHandle {
|
||||
int watch;
|
||||
int fd;
|
||||
int events;
|
||||
virEventHandleCallback cb;
|
||||
virFreeCallback ff;
|
||||
void *opaque;
|
||||
int deleted;
|
||||
};
|
||||
|
||||
/* State for a single timer being generated */
|
||||
struct virEventTimeout {
|
||||
int timer;
|
||||
int frequency;
|
||||
unsigned long long expiresAt;
|
||||
virEventTimeoutCallback cb;
|
||||
virFreeCallback ff;
|
||||
void *opaque;
|
||||
int deleted;
|
||||
};
|
||||
|
||||
/* Allocate extra slots for virEventHandle/virEventTimeout
|
||||
records in this multiple */
|
||||
#define EVENT_ALLOC_EXTENT 10
|
||||
|
||||
/* State for the main event loop */
|
||||
struct virEventLoop {
|
||||
pthread_mutex_t lock;
|
||||
int running;
|
||||
pthread_t leader;
|
||||
int wakeupfd[2];
|
||||
int handlesCount;
|
||||
int handlesAlloc;
|
||||
struct virEventHandle *handles;
|
||||
int timeoutsCount;
|
||||
int timeoutsAlloc;
|
||||
struct virEventTimeout *timeouts;
|
||||
};
|
||||
|
||||
/* Only have one event loop */
|
||||
static struct virEventLoop eventLoop;
|
||||
|
||||
/* Unique ID for the next FD watch to be registered */
|
||||
static int nextWatch = 1;
|
||||
|
||||
/* Unique ID for the next timer to be registered */
|
||||
static int nextTimer = 1;
|
||||
|
||||
static void virEventLock(void)
|
||||
{
|
||||
pthread_mutex_lock(&eventLoop.lock);
|
||||
}
|
||||
|
||||
static void virEventUnlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&eventLoop.lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a callback for monitoring file handle events.
|
||||
* NB, it *must* be safe to call this from within a callback
|
||||
* For this reason we only ever append to existing list.
|
||||
*/
|
||||
int virEventAddHandleImpl(int fd, int events,
|
||||
virEventHandleCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff) {
|
||||
int watch;
|
||||
EVENT_DEBUG("Add handle fd=%d events=%d cb=%p opaque=%p", fd, events, cb, opaque);
|
||||
virEventLock();
|
||||
if (eventLoop.handlesCount == eventLoop.handlesAlloc) {
|
||||
EVENT_DEBUG("Used %d handle slots, adding %d more",
|
||||
eventLoop.handlesAlloc, EVENT_ALLOC_EXTENT);
|
||||
if (VIR_REALLOC_N(eventLoop.handles,
|
||||
(eventLoop.handlesAlloc + EVENT_ALLOC_EXTENT)) < 0) {
|
||||
virEventUnlock();
|
||||
return -1;
|
||||
}
|
||||
eventLoop.handlesAlloc += EVENT_ALLOC_EXTENT;
|
||||
}
|
||||
|
||||
watch = nextWatch++;
|
||||
|
||||
eventLoop.handles[eventLoop.handlesCount].watch = watch;
|
||||
eventLoop.handles[eventLoop.handlesCount].fd = fd;
|
||||
eventLoop.handles[eventLoop.handlesCount].events =
|
||||
virEventHandleTypeToPollEvent(events);
|
||||
eventLoop.handles[eventLoop.handlesCount].cb = cb;
|
||||
eventLoop.handles[eventLoop.handlesCount].ff = ff;
|
||||
eventLoop.handles[eventLoop.handlesCount].opaque = opaque;
|
||||
eventLoop.handles[eventLoop.handlesCount].deleted = 0;
|
||||
|
||||
eventLoop.handlesCount++;
|
||||
|
||||
virEventInterruptLocked();
|
||||
virEventUnlock();
|
||||
|
||||
return watch;
|
||||
}
|
||||
|
||||
void virEventUpdateHandleImpl(int watch, int events) {
|
||||
int i;
|
||||
EVENT_DEBUG("Update handle w=%d e=%d", watch, events);
|
||||
|
||||
if (watch <= 0) {
|
||||
VIR_WARN("Ignoring invalid update watch %d", watch);
|
||||
return;
|
||||
}
|
||||
|
||||
virEventLock();
|
||||
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
||||
if (eventLoop.handles[i].watch == watch) {
|
||||
eventLoop.handles[i].events =
|
||||
virEventHandleTypeToPollEvent(events);
|
||||
virEventInterruptLocked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
virEventUnlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unregister a callback from a file handle
|
||||
* NB, it *must* be safe to call this from within a callback
|
||||
* For this reason we only ever set a flag in the existing list.
|
||||
* Actual deletion will be done out-of-band
|
||||
*/
|
||||
int virEventRemoveHandleImpl(int watch) {
|
||||
int i;
|
||||
EVENT_DEBUG("Remove handle w=%d", watch);
|
||||
|
||||
if (watch <= 0) {
|
||||
VIR_WARN("Ignoring invalid remove watch %d", watch);
|
||||
return -1;
|
||||
}
|
||||
|
||||
virEventLock();
|
||||
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
||||
if (eventLoop.handles[i].deleted)
|
||||
continue;
|
||||
|
||||
if (eventLoop.handles[i].watch == watch) {
|
||||
EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd);
|
||||
eventLoop.handles[i].deleted = 1;
|
||||
virEventInterruptLocked();
|
||||
virEventUnlock();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
virEventUnlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register a callback for a timer event
|
||||
* NB, it *must* be safe to call this from within a callback
|
||||
* For this reason we only ever append to existing list.
|
||||
*/
|
||||
int virEventAddTimeoutImpl(int frequency,
|
||||
virEventTimeoutCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff) {
|
||||
struct timeval now;
|
||||
int ret;
|
||||
EVENT_DEBUG("Adding timer %d with %d ms freq", nextTimer, frequency);
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virEventLock();
|
||||
if (eventLoop.timeoutsCount == eventLoop.timeoutsAlloc) {
|
||||
EVENT_DEBUG("Used %d timeout slots, adding %d more",
|
||||
eventLoop.timeoutsAlloc, EVENT_ALLOC_EXTENT);
|
||||
if (VIR_REALLOC_N(eventLoop.timeouts,
|
||||
(eventLoop.timeoutsAlloc + EVENT_ALLOC_EXTENT)) < 0) {
|
||||
virEventUnlock();
|
||||
return -1;
|
||||
}
|
||||
eventLoop.timeoutsAlloc += EVENT_ALLOC_EXTENT;
|
||||
}
|
||||
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].timer = nextTimer++;
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].frequency = frequency;
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].cb = cb;
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].ff = ff;
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].opaque = opaque;
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].deleted = 0;
|
||||
eventLoop.timeouts[eventLoop.timeoutsCount].expiresAt =
|
||||
frequency >= 0 ? frequency +
|
||||
(((unsigned long long)now.tv_sec)*1000) +
|
||||
(((unsigned long long)now.tv_usec)/1000) : 0;
|
||||
|
||||
eventLoop.timeoutsCount++;
|
||||
ret = nextTimer-1;
|
||||
virEventInterruptLocked();
|
||||
virEventUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void virEventUpdateTimeoutImpl(int timer, int frequency) {
|
||||
struct timeval tv;
|
||||
int i;
|
||||
EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency);
|
||||
|
||||
if (timer <= 0) {
|
||||
VIR_WARN("Ignoring invalid update timer %d", timer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
virEventLock();
|
||||
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
|
||||
if (eventLoop.timeouts[i].timer == timer) {
|
||||
eventLoop.timeouts[i].frequency = frequency;
|
||||
eventLoop.timeouts[i].expiresAt =
|
||||
frequency >= 0 ? frequency +
|
||||
(((unsigned long long)tv.tv_sec)*1000) +
|
||||
(((unsigned long long)tv.tv_usec)/1000) : 0;
|
||||
virEventInterruptLocked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
virEventUnlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unregister a callback for a timer
|
||||
* NB, it *must* be safe to call this from within a callback
|
||||
* For this reason we only ever set a flag in the existing list.
|
||||
* Actual deletion will be done out-of-band
|
||||
*/
|
||||
int virEventRemoveTimeoutImpl(int timer) {
|
||||
int i;
|
||||
EVENT_DEBUG("Remove timer %d", timer);
|
||||
|
||||
if (timer <= 0) {
|
||||
VIR_WARN("Ignoring invalid remove timer %d", timer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
virEventLock();
|
||||
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
|
||||
if (eventLoop.timeouts[i].deleted)
|
||||
continue;
|
||||
|
||||
if (eventLoop.timeouts[i].timer == timer) {
|
||||
eventLoop.timeouts[i].deleted = 1;
|
||||
virEventInterruptLocked();
|
||||
virEventUnlock();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
virEventUnlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Iterates over all registered timeouts and determine which
|
||||
* will be the first to expire.
|
||||
* @timeout: filled with expiry time of soonest timer, or -1 if
|
||||
* no timeout is pending
|
||||
* returns: 0 on success, -1 on error
|
||||
*/
|
||||
static int virEventCalculateTimeout(int *timeout) {
|
||||
unsigned long long then = 0;
|
||||
int i;
|
||||
EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount);
|
||||
/* Figure out if we need a timeout */
|
||||
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
|
||||
if (eventLoop.timeouts[i].frequency < 0)
|
||||
continue;
|
||||
|
||||
EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt);
|
||||
if (then == 0 ||
|
||||
eventLoop.timeouts[i].expiresAt < then)
|
||||
then = eventLoop.timeouts[i].expiresAt;
|
||||
}
|
||||
|
||||
/* Calculate how long we should wait for a timeout if needed */
|
||||
if (then > 0) {
|
||||
struct timeval tv;
|
||||
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*timeout = then -
|
||||
((((unsigned long long)tv.tv_sec)*1000) +
|
||||
(((unsigned long long)tv.tv_usec)/1000));
|
||||
|
||||
if (*timeout < 0)
|
||||
*timeout = 0;
|
||||
} else {
|
||||
*timeout = -1;
|
||||
}
|
||||
|
||||
EVENT_DEBUG("Timeout at %llu due in %d ms", then, *timeout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a pollfd array containing data for all registered
|
||||
* file handles. The caller must free the returned data struct
|
||||
* returns: the pollfd array, or NULL on error
|
||||
*/
|
||||
static struct pollfd *virEventMakePollFDs(int *nfds) {
|
||||
struct pollfd *fds;
|
||||
int i;
|
||||
|
||||
*nfds = 0;
|
||||
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
||||
if (eventLoop.handles[i].events)
|
||||
(*nfds)++;
|
||||
}
|
||||
|
||||
/* Setup the poll file handle data structs */
|
||||
if (VIR_ALLOC_N(fds, *nfds) < 0)
|
||||
return NULL;
|
||||
|
||||
*nfds = 0;
|
||||
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
||||
EVENT_DEBUG("Prepare n=%d w=%d, f=%d e=%d", i,
|
||||
eventLoop.handles[i].watch,
|
||||
eventLoop.handles[i].fd,
|
||||
eventLoop.handles[i].events);
|
||||
if (!eventLoop.handles[i].events)
|
||||
continue;
|
||||
fds[*nfds].fd = eventLoop.handles[i].fd;
|
||||
fds[*nfds].events = eventLoop.handles[i].events;
|
||||
fds[*nfds].revents = 0;
|
||||
(*nfds)++;
|
||||
//EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events);
|
||||
}
|
||||
|
||||
return fds;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Iterate over all timers and determine if any have expired.
|
||||
* Invoke the user supplied callback for each timer whose
|
||||
* expiry time is met, and schedule the next timeout. Does
|
||||
* not try to 'catch up' on time if the actual expiry time
|
||||
* was later than the requested time.
|
||||
*
|
||||
* This method must cope with new timers being registered
|
||||
* by a callback, and must skip any timers marked as deleted.
|
||||
*
|
||||
* Returns 0 upon success, -1 if an error occurred
|
||||
*/
|
||||
static int virEventDispatchTimeouts(void) {
|
||||
struct timeval tv;
|
||||
unsigned long long now;
|
||||
int i;
|
||||
/* Save this now - it may be changed during dispatch */
|
||||
int ntimeouts = eventLoop.timeoutsCount;
|
||||
DEBUG("Dispatch %d", ntimeouts);
|
||||
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
now = (((unsigned long long)tv.tv_sec)*1000) +
|
||||
(((unsigned long long)tv.tv_usec)/1000);
|
||||
|
||||
for (i = 0 ; i < ntimeouts ; i++) {
|
||||
if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0)
|
||||
continue;
|
||||
|
||||
/* Add 20ms fuzz so we don't pointlessly spin doing
|
||||
* <10ms sleeps, particularly on kernels with low HZ
|
||||
* it is fine that a timer expires 20ms earlier than
|
||||
* requested
|
||||
*/
|
||||
if (eventLoop.timeouts[i].expiresAt <= (now+20)) {
|
||||
virEventTimeoutCallback cb = eventLoop.timeouts[i].cb;
|
||||
int timer = eventLoop.timeouts[i].timer;
|
||||
void *opaque = eventLoop.timeouts[i].opaque;
|
||||
eventLoop.timeouts[i].expiresAt =
|
||||
now + eventLoop.timeouts[i].frequency;
|
||||
|
||||
virEventUnlock();
|
||||
(cb)(timer, opaque);
|
||||
virEventLock();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Iterate over all file handles and dispatch any which
|
||||
* have pending events listed in the poll() data. Invoke
|
||||
* the user supplied callback for each handle which has
|
||||
* pending events
|
||||
*
|
||||
* This method must cope with new handles being registered
|
||||
* by a callback, and must skip any handles marked as deleted.
|
||||
*
|
||||
* Returns 0 upon success, -1 if an error occurred
|
||||
*/
|
||||
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
|
||||
int i, n;
|
||||
DEBUG("Dispatch %d", nfds);
|
||||
|
||||
/* NB, use nfds not eventLoop.handlesCount, because new
|
||||
* fds might be added on end of list, and they're not
|
||||
* in the fds array we've got */
|
||||
for (i = 0, n = 0 ; n < nfds && i < eventLoop.handlesCount ; n++) {
|
||||
while ((eventLoop.handles[i].fd != fds[n].fd ||
|
||||
eventLoop.handles[i].events == 0) &&
|
||||
i < eventLoop.handlesCount) {
|
||||
i++;
|
||||
}
|
||||
if (i == eventLoop.handlesCount)
|
||||
break;
|
||||
|
||||
DEBUG("i=%d w=%d", i, eventLoop.handles[i].watch);
|
||||
if (eventLoop.handles[i].deleted) {
|
||||
EVENT_DEBUG("Skip deleted n=%d w=%d f=%d", i,
|
||||
eventLoop.handles[i].watch, eventLoop.handles[i].fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fds[n].revents) {
|
||||
virEventHandleCallback cb = eventLoop.handles[i].cb;
|
||||
void *opaque = eventLoop.handles[i].opaque;
|
||||
int hEvents = virPollEventToEventHandleType(fds[n].revents);
|
||||
EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
|
||||
fds[n].fd, eventLoop.handles[i].watch,
|
||||
fds[n].revents, eventLoop.handles[i].opaque);
|
||||
virEventUnlock();
|
||||
(cb)(eventLoop.handles[i].watch,
|
||||
fds[n].fd, hEvents, opaque);
|
||||
virEventLock();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Used post dispatch to actually remove any timers that
|
||||
* were previously marked as deleted. This asynchronous
|
||||
* cleanup is needed to make dispatch re-entrant safe.
|
||||
*/
|
||||
static int virEventCleanupTimeouts(void) {
|
||||
int i;
|
||||
DEBUG("Cleanup %d", eventLoop.timeoutsCount);
|
||||
|
||||
/* Remove deleted entries, shuffling down remaining
|
||||
* entries as needed to form contiguous series
|
||||
*/
|
||||
for (i = 0 ; i < eventLoop.timeoutsCount ; ) {
|
||||
if (!eventLoop.timeouts[i].deleted) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
EVENT_DEBUG("Purging timeout %d with id %d", i, eventLoop.timeouts[i].timer);
|
||||
if (eventLoop.timeouts[i].ff)
|
||||
(eventLoop.timeouts[i].ff)(eventLoop.timeouts[i].opaque);
|
||||
|
||||
if ((i+1) < eventLoop.timeoutsCount) {
|
||||
memmove(eventLoop.timeouts+i,
|
||||
eventLoop.timeouts+i+1,
|
||||
sizeof(struct virEventTimeout)*(eventLoop.timeoutsCount-(i+1)));
|
||||
}
|
||||
eventLoop.timeoutsCount--;
|
||||
}
|
||||
|
||||
/* Release some memory if we've got a big chunk free */
|
||||
if ((eventLoop.timeoutsAlloc - EVENT_ALLOC_EXTENT) > eventLoop.timeoutsCount) {
|
||||
EVENT_DEBUG("Releasing %d out of %d timeout slots used, releasing %d",
|
||||
eventLoop.timeoutsCount, eventLoop.timeoutsAlloc, EVENT_ALLOC_EXTENT);
|
||||
if (VIR_REALLOC_N(eventLoop.timeouts,
|
||||
(eventLoop.timeoutsAlloc - EVENT_ALLOC_EXTENT)) < 0)
|
||||
return -1;
|
||||
eventLoop.timeoutsAlloc -= EVENT_ALLOC_EXTENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used post dispatch to actually remove any handles that
|
||||
* were previously marked as deleted. This asynchronous
|
||||
* cleanup is needed to make dispatch re-entrant safe.
|
||||
*/
|
||||
static int virEventCleanupHandles(void) {
|
||||
int i;
|
||||
DEBUG("Cleanupo %d", eventLoop.handlesCount);
|
||||
|
||||
/* Remove deleted entries, shuffling down remaining
|
||||
* entries as needed to form contiguous series
|
||||
*/
|
||||
for (i = 0 ; i < eventLoop.handlesCount ; ) {
|
||||
if (!eventLoop.handles[i].deleted) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (eventLoop.handles[i].ff)
|
||||
(eventLoop.handles[i].ff)(eventLoop.handles[i].opaque);
|
||||
|
||||
if ((i+1) < eventLoop.handlesCount) {
|
||||
memmove(eventLoop.handles+i,
|
||||
eventLoop.handles+i+1,
|
||||
sizeof(struct virEventHandle)*(eventLoop.handlesCount-(i+1)));
|
||||
}
|
||||
eventLoop.handlesCount--;
|
||||
}
|
||||
|
||||
/* Release some memory if we've got a big chunk free */
|
||||
if ((eventLoop.handlesAlloc - EVENT_ALLOC_EXTENT) > eventLoop.handlesCount) {
|
||||
EVENT_DEBUG("Releasing %d out of %d handles slots used, releasing %d",
|
||||
eventLoop.handlesCount, eventLoop.handlesAlloc, EVENT_ALLOC_EXTENT);
|
||||
if (VIR_REALLOC_N(eventLoop.handles,
|
||||
(eventLoop.handlesAlloc - EVENT_ALLOC_EXTENT)) < 0)
|
||||
return -1;
|
||||
eventLoop.handlesAlloc -= EVENT_ALLOC_EXTENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run a single iteration of the event loop, blocking until
|
||||
* at least one file handle has an event, or a timer expires
|
||||
*/
|
||||
int virEventRunOnce(void) {
|
||||
struct pollfd *fds = NULL;
|
||||
int ret, timeout, nfds;
|
||||
|
||||
virEventLock();
|
||||
eventLoop.running = 1;
|
||||
eventLoop.leader = pthread_self();
|
||||
|
||||
if (virEventCleanupTimeouts() < 0 ||
|
||||
virEventCleanupHandles() < 0)
|
||||
goto error;
|
||||
|
||||
if (!(fds = virEventMakePollFDs(&nfds)) ||
|
||||
virEventCalculateTimeout(&timeout) < 0)
|
||||
goto error;
|
||||
|
||||
virEventUnlock();
|
||||
|
||||
retry:
|
||||
EVENT_DEBUG("Poll on %d handles %p timeout %d", nfds, fds, timeout);
|
||||
ret = poll(fds, nfds, timeout);
|
||||
EVENT_DEBUG("Poll got %d event", ret);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
goto retry;
|
||||
}
|
||||
goto error_unlocked;
|
||||
}
|
||||
|
||||
virEventLock();
|
||||
if (virEventDispatchTimeouts() < 0)
|
||||
goto error;
|
||||
|
||||
if (ret > 0 &&
|
||||
virEventDispatchHandles(nfds, fds) < 0)
|
||||
goto error;
|
||||
|
||||
if (virEventCleanupTimeouts() < 0 ||
|
||||
virEventCleanupHandles() < 0)
|
||||
goto error;
|
||||
|
||||
eventLoop.running = 0;
|
||||
virEventUnlock();
|
||||
VIR_FREE(fds);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
virEventUnlock();
|
||||
error_unlocked:
|
||||
VIR_FREE(fds);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
|
||||
int fd,
|
||||
int events ATTRIBUTE_UNUSED,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
char c;
|
||||
virEventLock();
|
||||
saferead(fd, &c, sizeof(c));
|
||||
virEventUnlock();
|
||||
}
|
||||
|
||||
int virEventInit(void)
|
||||
{
|
||||
if (pthread_mutex_init(&eventLoop.lock, NULL) != 0)
|
||||
return -1;
|
||||
|
||||
if (pipe(eventLoop.wakeupfd) < 0 ||
|
||||
virSetNonBlock(eventLoop.wakeupfd[0]) < 0 ||
|
||||
virSetNonBlock(eventLoop.wakeupfd[1]) < 0 ||
|
||||
virSetCloseExec(eventLoop.wakeupfd[0]) < 0 ||
|
||||
virSetCloseExec(eventLoop.wakeupfd[1]) < 0)
|
||||
return -1;
|
||||
|
||||
if (virEventAddHandleImpl(eventLoop.wakeupfd[0],
|
||||
VIR_EVENT_HANDLE_READABLE,
|
||||
virEventHandleWakeup, NULL, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int virEventInterruptLocked(void)
|
||||
{
|
||||
char c = '\0';
|
||||
|
||||
if (!eventLoop.running ||
|
||||
pthread_self() == eventLoop.leader) {
|
||||
VIR_DEBUG("Skip interrupt, %d %d", eventLoop.running, (int)eventLoop.leader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
VIR_DEBUG0("Interrupting");
|
||||
if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int virEventInterrupt(void)
|
||||
{
|
||||
int ret;
|
||||
virEventLock();
|
||||
ret = virEventInterruptLocked();
|
||||
virEventUnlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virEventHandleTypeToPollEvent(int events)
|
||||
{
|
||||
int ret = 0;
|
||||
if(events & VIR_EVENT_HANDLE_READABLE)
|
||||
ret |= POLLIN;
|
||||
if(events & VIR_EVENT_HANDLE_WRITABLE)
|
||||
ret |= POLLOUT;
|
||||
if(events & VIR_EVENT_HANDLE_ERROR)
|
||||
ret |= POLLERR;
|
||||
if(events & VIR_EVENT_HANDLE_HANGUP)
|
||||
ret |= POLLHUP;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virPollEventToEventHandleType(int events)
|
||||
{
|
||||
int ret = 0;
|
||||
if(events & POLLIN)
|
||||
ret |= VIR_EVENT_HANDLE_READABLE;
|
||||
if(events & POLLOUT)
|
||||
ret |= VIR_EVENT_HANDLE_WRITABLE;
|
||||
if(events & POLLERR)
|
||||
ret |= VIR_EVENT_HANDLE_ERROR;
|
||||
if(events & POLLNVAL) /* Treat NVAL as error, since libvirt doesn't distinguish */
|
||||
ret |= VIR_EVENT_HANDLE_ERROR;
|
||||
if(events & POLLHUP)
|
||||
ret |= VIR_EVENT_HANDLE_HANGUP;
|
||||
return ret;
|
||||
}
|
134
daemon/event.h
134
daemon/event.h
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* event.h: event loop for monitoring file handles
|
||||
*
|
||||
* Copyright (C) 2007 Daniel P. Berrange
|
||||
* Copyright (C) 2007 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIRTD_EVENT_H__
|
||||
#define __VIRTD_EVENT_H__
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* virEventAddHandleImpl: register a callback for monitoring file handle events
|
||||
*
|
||||
* @fd: file handle to monitor for events
|
||||
* @events: bitset of events to watch from POLLnnn constants
|
||||
* @cb: callback to invoke when an event occurs
|
||||
* @opaque: user data to pass to callback
|
||||
*
|
||||
* returns -1 if the file handle cannot be registered, 0 upon success
|
||||
*/
|
||||
int virEventAddHandleImpl(int fd, int events,
|
||||
virEventHandleCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff);
|
||||
|
||||
/**
|
||||
* virEventUpdateHandleImpl: change event set for a monitored file handle
|
||||
*
|
||||
* @watch: watch whose handle to update
|
||||
* @events: bitset of events to watch from POLLnnn constants
|
||||
*
|
||||
* Will not fail if fd exists
|
||||
*/
|
||||
void virEventUpdateHandleImpl(int watch, int events);
|
||||
|
||||
/**
|
||||
* virEventRemoveHandleImpl: unregister a callback from a file handle
|
||||
*
|
||||
* @watch: watch whose handle to remove
|
||||
*
|
||||
* returns -1 if the file handle was not registered, 0 upon success
|
||||
*/
|
||||
int virEventRemoveHandleImpl(int watch);
|
||||
|
||||
/**
|
||||
* virEventAddTimeoutImpl: register a callback for a timer event
|
||||
*
|
||||
* @frequency: time between events in milliseconds
|
||||
* @cb: callback to invoke when an event occurs
|
||||
* @opaque: user data to pass to callback
|
||||
*
|
||||
* Setting frequency to -1 will disable the timer. Setting the frequency
|
||||
* to zero will cause it to fire on every event loop iteration.
|
||||
*
|
||||
* returns -1 if the file handle cannot be registered, a positive
|
||||
* integer timer id upon success
|
||||
*/
|
||||
int virEventAddTimeoutImpl(int frequency,
|
||||
virEventTimeoutCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff);
|
||||
|
||||
/**
|
||||
* virEventUpdateTimeoutImpl: change frequency for a timer
|
||||
*
|
||||
* @timer: timer id to change
|
||||
* @frequency: time between events in milliseconds
|
||||
*
|
||||
* Setting frequency to -1 will disable the timer. Setting the frequency
|
||||
* to zero will cause it to fire on every event loop iteration.
|
||||
*
|
||||
* Will not fail if timer exists
|
||||
*/
|
||||
void virEventUpdateTimeoutImpl(int timer, int frequency);
|
||||
|
||||
/**
|
||||
* virEventRemoveTimeoutImpl: unregister a callback for a timer
|
||||
*
|
||||
* @timer: the timer id to remove
|
||||
*
|
||||
* returns -1 if the timer was not registered, 0 upon success
|
||||
*/
|
||||
int virEventRemoveTimeoutImpl(int timer);
|
||||
|
||||
/**
|
||||
* virEventInit: Initialize the event loop
|
||||
*
|
||||
* returns -1 if initialization failed
|
||||
*/
|
||||
int virEventInit(void);
|
||||
|
||||
/**
|
||||
* virEventRunOnce: run a single iteration of the event loop.
|
||||
*
|
||||
* Blocks the caller until at least one file handle has an
|
||||
* event or the first timer expires.
|
||||
*
|
||||
* returns -1 if the event monitoring failed
|
||||
*/
|
||||
int virEventRunOnce(void);
|
||||
|
||||
int
|
||||
virEventHandleTypeToPollEvent(int events);
|
||||
int
|
||||
virPollEventToEventHandleType(int events);
|
||||
|
||||
|
||||
/**
|
||||
* virEventInterrupt: wakeup any thread waiting in poll()
|
||||
*
|
||||
* return -1 if wakup failed
|
||||
*/
|
||||
int virEventInterrupt(void);
|
||||
|
||||
|
||||
#endif /* __VIRTD_EVENT_H__ */
|
@@ -1,82 +0,0 @@
|
||||
(* /etc/libvirt/libvirtd.conf *)
|
||||
|
||||
module Libvirtd =
|
||||
autoload xfm
|
||||
|
||||
let eol = del /[ \t]*\n/ "\n"
|
||||
let value_sep = del /[ \t]*=[ \t]*/ " = "
|
||||
let indent = del /[ \t]*/ ""
|
||||
|
||||
let array_sep = del /,[ \t\n]*/ ", "
|
||||
let array_start = del /\[[ \t\n]*/ "[ "
|
||||
let array_end = del /\]/ "]"
|
||||
|
||||
let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
|
||||
let bool_val = store /0|1/
|
||||
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
|
||||
|
||||
let str_entry (kw:string) = [ key kw . value_sep . str_val ]
|
||||
let bool_entry (kw:string) = [ key kw . value_sep . bool_val ]
|
||||
let int_entry (kw:string) = [ key kw . value_sep . int_val ]
|
||||
let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ]
|
||||
|
||||
|
||||
(* Config entry grouped by function - same order as example config *)
|
||||
let network_entry = bool_entry "listen_tls"
|
||||
| bool_entry "listen_tcp"
|
||||
| str_entry "tls_port"
|
||||
| str_entry "tcp_port"
|
||||
| str_entry "listen_addr"
|
||||
| bool_entry "mdns_adv"
|
||||
| str_entry "mdns_name"
|
||||
|
||||
let sock_acl_entry = str_entry "unix_sock_group"
|
||||
| str_entry "unix_sock_ro_perms"
|
||||
| str_entry "unix_sock_rw_perms"
|
||||
| str_entry "unix_sock_dir"
|
||||
|
||||
let authentication_entry = str_entry "auth_unix_ro"
|
||||
| str_entry "auth_unix_rw"
|
||||
| str_entry "auth_tcp"
|
||||
| str_entry "auth_tls"
|
||||
|
||||
let certificate_entry = str_entry "key_file"
|
||||
| str_entry "cert_file"
|
||||
| str_entry "ca_file"
|
||||
| str_entry "crl_file"
|
||||
|
||||
let authorization_entry = bool_entry "tls_no_verify_certificate"
|
||||
| str_array_entry "tls_allowed_dn_list"
|
||||
| str_array_entry "sasl_allowed_username_list"
|
||||
|
||||
let processing_entry = int_entry "min_workers"
|
||||
| int_entry "max_workers"
|
||||
| int_entry "max_clients"
|
||||
| int_entry "max_requests"
|
||||
| int_entry "max_client_requests"
|
||||
|
||||
let logging_entry = int_entry "log_level"
|
||||
| str_entry "log_filters"
|
||||
| str_entry "log_outputs"
|
||||
|
||||
(* Each enty in the config is one of the following three ... *)
|
||||
let entry = network_entry
|
||||
| sock_acl_entry
|
||||
| authentication_entry
|
||||
| certificate_entry
|
||||
| authorization_entry
|
||||
| processing_entry
|
||||
| logging_entry
|
||||
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
|
||||
let empty = [ label "#empty" . eol ]
|
||||
|
||||
let record = indent . entry . eol
|
||||
|
||||
let lns = ( record | comment | empty ) *
|
||||
|
||||
let filter = incl "/etc/libvirt/libvirtd.conf"
|
||||
. Util.stdexcl
|
||||
|
||||
let xfm = transform lns filter
|
3201
daemon/libvirtd.c
3201
daemon/libvirtd.c
File diff suppressed because it is too large
Load Diff
@@ -1,314 +0,0 @@
|
||||
# Master libvirt daemon configuration file
|
||||
#
|
||||
# For further information consult http://libvirt.org/format.html
|
||||
#
|
||||
# NOTE: the tests/daemon-conf regression test script requires
|
||||
# that each "PARAMETER = VALUE" line in this file have the parameter
|
||||
# name just after a leading "#".
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Network connectivity controls
|
||||
#
|
||||
|
||||
# Flag listening for secure TLS connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# It is necessary to setup a CA and issue server certificates before
|
||||
# using this capability.
|
||||
#
|
||||
# This is enabled by default, uncomment this to disable it
|
||||
#listen_tls = 0
|
||||
|
||||
# Listen for unencrypted TCP connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# Using the TCP socket requires SASL authentication by default. Only
|
||||
# SASL mechanisms which support data encryption are allowed. This is
|
||||
# DIGEST_MD5 and GSSAPI (Kerberos5)
|
||||
#
|
||||
# This is disabled by default, uncomment this to enable it.
|
||||
#listen_tcp = 1
|
||||
|
||||
|
||||
|
||||
# Override the port for accepting secure TLS connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
#tls_port = "16514"
|
||||
|
||||
# Override the port for accepting insecure TCP connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
#tcp_port = "16509"
|
||||
|
||||
|
||||
# Override the default configuration which binds to all network
|
||||
# interfaces. This can be a numeric IPv4/6 address, or hostname
|
||||
#
|
||||
#listen_addr = "192.168.0.1"
|
||||
|
||||
|
||||
# Flag toggling mDNS advertizement of the libvirt service.
|
||||
#
|
||||
# Alternatively can disable for all services on a host by
|
||||
# stopping the Avahi daemon
|
||||
#
|
||||
# This is enabled by default, uncomment this to disable it
|
||||
#mdns_adv = 0
|
||||
|
||||
# Override the default mDNS advertizement name. This must be
|
||||
# unique on the immediate broadcast network.
|
||||
#
|
||||
# The default is "Virtualization Host HOSTNAME", where HOSTNAME
|
||||
# is subsituted for the short hostname of the machine (without domain)
|
||||
#
|
||||
#mdns_name = "Virtualization Host Joe Demo"
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# UNIX socket access controls
|
||||
#
|
||||
|
||||
# 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.
|
||||
#
|
||||
# This is restricted to 'root' by default.
|
||||
#unix_sock_group = "libvirt"
|
||||
|
||||
# Set the UNIX socket permissions for the R/O socket. This is used
|
||||
# for monitoring VM status only
|
||||
#
|
||||
# Default allows any user. If setting group ownership may want to
|
||||
# restrict this to:
|
||||
#unix_sock_ro_perms = "0777"
|
||||
|
||||
# Set the UNIX socket permissions for the R/W socket. This is used
|
||||
# for full management of VMs
|
||||
#
|
||||
# Default allows only root. If PolicyKit is enabled on the socket,
|
||||
# the default will change to allow everyone (eg, 0777)
|
||||
#
|
||||
# If not using PolicyKit and setting group ownership for access
|
||||
# control then you may want to relax this to:
|
||||
#unix_sock_rw_perms = "0770"
|
||||
|
||||
# Set the name of the directory in which sockets will be found/created.
|
||||
#unix_sock_dir = "/var/run/libvirt"
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authentication.
|
||||
#
|
||||
# - none: do not perform auth checks. If you can connect to the
|
||||
# socket you are allowed. This is suitable if there are
|
||||
# restrictions on connecting to the socket (eg, UNIX
|
||||
# socket permissions), or if there is a lower layer in
|
||||
# the network providing auth (eg, TLS/x509 certificates)
|
||||
#
|
||||
# - sasl: use SASL infrastructure. The actual auth scheme is then
|
||||
# controlled from /etc/sasl2/libvirt.conf. For the TCP
|
||||
# socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
|
||||
# For non-TCP or TLS sockets, any scheme is allowed.
|
||||
#
|
||||
# - polkit: use PolicyKit to authenticate. This is only suitable
|
||||
# for use on the UNIX sockets. The default policy will
|
||||
# require a user to supply their own password to gain
|
||||
# full read/write access (aka sudo like), while anyone
|
||||
# is allowed read/only access.
|
||||
#
|
||||
# Set an authentication scheme for UNIX read-only sockets
|
||||
# By default socket permissions allow anyone to connect
|
||||
#
|
||||
# To restrict monitoring of domains you may wish to enable
|
||||
# an authentication mechanism here
|
||||
#auth_unix_ro = "none"
|
||||
|
||||
# Set an authentication scheme for UNIX read-write sockets
|
||||
# By default socket permissions only allow root. If PolicyKit
|
||||
# support was compiled into libvirt, the default will be to
|
||||
# use 'polkit' auth.
|
||||
#
|
||||
# If the unix_sock_rw_perms are changed you may wish to enable
|
||||
# an authentication mechanism here
|
||||
#auth_unix_rw = "none"
|
||||
|
||||
# Change the authentication scheme for TCP sockets.
|
||||
#
|
||||
# If you don't enable SASL, then all TCP traffic is cleartext.
|
||||
# Don't do this outside of a dev/test scenario. For real world
|
||||
# use, always enable SASL and use the GSSAPI or DIGEST-MD5
|
||||
# mechanism in /etc/sasl2/libvirt.conf
|
||||
#auth_tcp = "sasl"
|
||||
|
||||
# Change the authentication scheme for TLS sockets.
|
||||
#
|
||||
# TLS sockets already have encryption provided by the TLS
|
||||
# layer, and limited authentication is done by certificates
|
||||
#
|
||||
# It is possible to make use of any SASL authentication
|
||||
# mechanism as well, by using 'sasl' for this option
|
||||
#auth_tls = "none"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# TLS x509 certificate configuration
|
||||
#
|
||||
|
||||
|
||||
# Override the default server key file path
|
||||
#
|
||||
#key_file = "/etc/pki/libvirt/private/serverkey.pem"
|
||||
|
||||
# Override the default server certificate file path
|
||||
#
|
||||
#cert_file = "/etc/pki/libvirt/servercert.pem"
|
||||
|
||||
# Override the default CA certificate path
|
||||
#
|
||||
#ca_file = "/etc/pki/CA/cacert.pem"
|
||||
|
||||
# Specify a certificate revocation list.
|
||||
#
|
||||
# Defaults to not using a CRL, uncomment to enable it
|
||||
#crl_file = "/etc/pki/CA/crl.pem"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authorization controls
|
||||
#
|
||||
|
||||
|
||||
# Flag to disable verification of client certificates
|
||||
#
|
||||
# Client certificate verification is the primary authentication mechanism.
|
||||
# Any client which does not present a certificate signed by the CA
|
||||
# will be rejected.
|
||||
#
|
||||
# Default is to always verify. Uncommenting this will disable
|
||||
# verification - make sure an IP whitelist is set
|
||||
#tls_no_verify_certificate = 1
|
||||
|
||||
|
||||
# A whitelist of allowed x509 Distinguished Names
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# "C=GB,ST=London,L=London,O=Red Hat,CN=*"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no DN's are checked
|
||||
#tls_allowed_dn_list = ["DN1", "DN2"]
|
||||
|
||||
|
||||
# A whitelist of allowed SASL usernames. The format for usernames
|
||||
# depends on the SASL authentication mechanism. Kerberos usernames
|
||||
# look like username@REALM
|
||||
#
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# "*@EXAMPLE.COM"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no Username's are checked
|
||||
#sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Processing controls
|
||||
#
|
||||
|
||||
# The maximum number of concurrent client connections to allow
|
||||
# over all sockets combined.
|
||||
#max_clients = 20
|
||||
|
||||
|
||||
# The minimum limit sets the number of workers to start up
|
||||
# initially. If the number of active clients exceeds this,
|
||||
# then more threads are spawned, upto max_workers limit.
|
||||
# Typically you'd want max_workers to equal maximum number
|
||||
# of clients allowed
|
||||
#min_workers = 5
|
||||
#max_workers = 20
|
||||
|
||||
# Total global limit on concurrent RPC calls. Should be
|
||||
# at least as large as max_workers. Beyond this, RPC requests
|
||||
# will be read into memory and queued. This directly impact
|
||||
# memory usage, currently each request requires 256 KB of
|
||||
# memory. So by default upto 5 MB of memory is used
|
||||
#
|
||||
# XXX this isn't actually enforced yet, only the per-client
|
||||
# limit is used so far
|
||||
#max_requests = 20
|
||||
|
||||
# Limit on concurrent requests from a single client
|
||||
# connection. To avoid one client monopolizing the server
|
||||
# this should be a small fraction of the global max_requests
|
||||
# and max_workers parameter
|
||||
#max_client_requests = 5
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Logging controls
|
||||
#
|
||||
|
||||
# Logging level: 4 errors, 3 warnings, 2 informations, 1 debug
|
||||
# basically 1 will log everything possible
|
||||
#log_level = 3
|
||||
|
||||
# Logging filters:
|
||||
# A filter allows to select a different logging level for a given category
|
||||
# of logs
|
||||
# The format for a filter is:
|
||||
# x:name
|
||||
# where name is a match string e.g. remote or qemu
|
||||
# the x prefix is the minimal level where matching messages should be logged
|
||||
# 1: DEBUG
|
||||
# 2: INFO
|
||||
# 3: WARNING
|
||||
# 4: ERROR
|
||||
#
|
||||
# Multiple filter can be defined in a single @filters, they just need to be
|
||||
# separated by spaces.
|
||||
#
|
||||
# e.g:
|
||||
# log_filters="3:remote 4:event"
|
||||
# to only get warning or errors from the remote layer and only errors from
|
||||
# the event layer.
|
||||
|
||||
# Logging outputs:
|
||||
# An output is one of the places to save logging informations
|
||||
# The format for an output can be:
|
||||
# x:stderr
|
||||
# output goes to stderr
|
||||
# x:syslog:name
|
||||
# use syslog for the output and use the given name as the ident
|
||||
# x:file:file_path
|
||||
# output to a file, with the given filepath
|
||||
# In all case the x prefix is the minimal level, acting as a filter
|
||||
# 1: DEBUG
|
||||
# 2: INFO
|
||||
# 3: WARNING
|
||||
# 4: ERROR
|
||||
#
|
||||
# Multiple output can be defined, they just need to be separated by spaces.
|
||||
# e.g.:
|
||||
# log_outputs="3:syslog:libvirtd"
|
||||
# to log all warnings and errors to syslog under the libvirtd ident
|
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
* libvirtd.h: daemon data structure definitions
|
||||
*
|
||||
* Copyright (C) 2006-2009 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Daniel P. Berrange
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef QEMUD_INTERNAL_H__
|
||||
#define QEMUD_INTERNAL_H__
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
#include "gnutls_1_0_compat.h"
|
||||
#if HAVE_SASL
|
||||
#include <sasl/sasl.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_POLKIT0
|
||||
#include <dbus/dbus.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SYSLIMITS_H
|
||||
#include <sys/syslimits.h>
|
||||
#endif
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include "remote_protocol.h"
|
||||
#include "logging.h"
|
||||
#include "threads.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef HAVE_ANSIDECL_H
|
||||
#include <ansidecl.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
/**
|
||||
* ATTRIBUTE_UNUSED:
|
||||
*
|
||||
* Macro to flag conciously unused parameters to functions
|
||||
*/
|
||||
#ifndef ATTRIBUTE_UNUSED
|
||||
#define ATTRIBUTE_UNUSED __attribute__((__unused__))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ATTRIBUTE_FMT_PRINTF
|
||||
*
|
||||
* Macro used to check printf like functions, if compiling
|
||||
* with gcc.
|
||||
*
|
||||
* We use gnulib which guarentees we always have GNU style
|
||||
* printf format specifiers even on broken Win32 platforms
|
||||
* hence we have to force 'gnu_printf' for new GCC
|
||||
*/
|
||||
#ifndef ATTRIBUTE_FMT_PRINTF
|
||||
#if __GNUC_PREREQ (4, 4)
|
||||
#define ATTRIBUTE_FMT_PRINTF(fmtpos,argpos) __attribute__((__format__ (gnu_printf, fmtpos,argpos)))
|
||||
#else
|
||||
#define ATTRIBUTE_FMT_PRINTF(fmtpos,argpos) __attribute__((__format__ (printf, fmtpos,argpos)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ATTRIBUTE_RETURN_CHECK
|
||||
#if __GNUC_PREREQ (3, 4)
|
||||
#define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
|
||||
#else
|
||||
#define ATTRIBUTE_RETURN_CHECK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef ATTRIBUTE_UNUSED
|
||||
#define ATTRIBUTE_UNUSED
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_FMT_PRINTF
|
||||
#define ATTRIBUTE_FMT_PRINTF(...)
|
||||
#endif
|
||||
#ifndef ATTRIBUTE_RETURN_CHECK
|
||||
#define ATTRIBUTE_RETURN_CHECK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define qemudDebug DEBUG
|
||||
|
||||
/* Whether we're passing reads & writes through a sasl SSF */
|
||||
enum qemud_sasl_ssf {
|
||||
QEMUD_SASL_SSF_NONE = 0,
|
||||
QEMUD_SASL_SSF_READ = 1,
|
||||
QEMUD_SASL_SSF_WRITE = 2,
|
||||
};
|
||||
|
||||
enum qemud_sock_type {
|
||||
QEMUD_SOCK_TYPE_UNIX = 0,
|
||||
QEMUD_SOCK_TYPE_TCP = 1,
|
||||
QEMUD_SOCK_TYPE_TLS = 2,
|
||||
};
|
||||
|
||||
struct qemud_client_message {
|
||||
char buffer [REMOTE_MESSAGE_MAX + REMOTE_MESSAGE_HEADER_XDR_LEN];
|
||||
unsigned int bufferLength;
|
||||
unsigned int bufferOffset;
|
||||
|
||||
unsigned int async : 1;
|
||||
unsigned int streamTX : 1;
|
||||
|
||||
remote_message_header hdr;
|
||||
|
||||
struct qemud_client_message *next;
|
||||
};
|
||||
|
||||
struct qemud_client;
|
||||
|
||||
/* Allow for filtering of incoming messages to a custom
|
||||
* dispatch processing queue, instead of client->dx.
|
||||
*/
|
||||
typedef int (*qemud_client_filter_func)(struct qemud_client *client,
|
||||
struct qemud_client_message *msg, void *opaque);
|
||||
struct qemud_client_filter {
|
||||
qemud_client_filter_func query;
|
||||
void *opaque;
|
||||
|
||||
struct qemud_client_filter *next;
|
||||
};
|
||||
|
||||
struct qemud_client_stream {
|
||||
virStreamPtr st;
|
||||
int procedure;
|
||||
int serial;
|
||||
|
||||
unsigned int recvEOF : 1;
|
||||
unsigned int closed : 1;
|
||||
|
||||
struct qemud_client_filter filter;
|
||||
|
||||
struct qemud_client_message *rx;
|
||||
int tx;
|
||||
|
||||
struct qemud_client_stream *next;
|
||||
};
|
||||
|
||||
/* Stores the per-client connection state */
|
||||
struct qemud_client {
|
||||
virMutex lock;
|
||||
|
||||
int magic;
|
||||
|
||||
int fd;
|
||||
int watch;
|
||||
int readonly:1;
|
||||
int closing:1;
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
int type; /* qemud_sock_type */
|
||||
gnutls_session_t tlssession;
|
||||
int auth;
|
||||
int handshake : 1; /* If we're in progress for TLS handshake */
|
||||
#if HAVE_SASL
|
||||
sasl_conn_t *saslconn;
|
||||
int saslSSF;
|
||||
const char *saslDecoded;
|
||||
unsigned int saslDecodedLength;
|
||||
unsigned int saslDecodedOffset;
|
||||
const char *saslEncoded;
|
||||
unsigned int saslEncodedLength;
|
||||
unsigned int saslEncodedOffset;
|
||||
char *saslUsername;
|
||||
#endif
|
||||
|
||||
/* Count of meages in 'dx' or 'tx' queue
|
||||
* ie RPC calls in progress. Does not count
|
||||
* async events which are not used for
|
||||
* throttling calculations */
|
||||
int nrequests;
|
||||
/* Zero or one messages being received. Zero if
|
||||
* nrequests >= max_clients and throttling */
|
||||
struct qemud_client_message *rx;
|
||||
/* Zero or many messages waiting for a worker
|
||||
* to process them */
|
||||
struct qemud_client_message *dx;
|
||||
/* Zero or many messages waiting for transmit
|
||||
* back to client, including async events */
|
||||
struct qemud_client_message *tx;
|
||||
/* Filters to capture messages that would otherwise
|
||||
* end up on the 'dx' queue */
|
||||
struct qemud_client_filter *filters;
|
||||
|
||||
/* Data streams */
|
||||
struct qemud_client_stream *streams;
|
||||
|
||||
|
||||
/* This is only valid if a remote open call has been made on this
|
||||
* connection, otherwise it will be NULL. Also if remote close is
|
||||
* called, it will be set back to NULL if that succeeds.
|
||||
*/
|
||||
virConnectPtr conn;
|
||||
int refs;
|
||||
|
||||
};
|
||||
|
||||
#define QEMUD_CLIENT_MAGIC 0x7788aaee
|
||||
|
||||
|
||||
struct qemud_socket {
|
||||
int fd;
|
||||
int watch;
|
||||
int readonly;
|
||||
int type; /* qemud_sock_type */
|
||||
int auth;
|
||||
int port;
|
||||
struct qemud_socket *next;
|
||||
};
|
||||
|
||||
struct qemud_worker {
|
||||
pthread_t thread;
|
||||
int hasThread :1;
|
||||
int processingCall :1;
|
||||
int quitRequest : 1;
|
||||
|
||||
/* back-pointer to our server */
|
||||
struct qemud_server *server;
|
||||
};
|
||||
|
||||
/* Main server state */
|
||||
struct qemud_server {
|
||||
virMutex lock;
|
||||
virCond job;
|
||||
|
||||
int privileged;
|
||||
|
||||
int nworkers;
|
||||
int nactiveworkers;
|
||||
struct qemud_worker *workers;
|
||||
int nsockets;
|
||||
struct qemud_socket *sockets;
|
||||
int nclients;
|
||||
struct qemud_client **clients;
|
||||
|
||||
int sigread;
|
||||
int sigwrite;
|
||||
char *logDir;
|
||||
pthread_t eventThread;
|
||||
unsigned int hasEventThread :1;
|
||||
unsigned int quitEventThread :1;
|
||||
#ifdef HAVE_AVAHI
|
||||
struct libvirtd_mdns *mdns;
|
||||
#endif
|
||||
#if HAVE_SASL
|
||||
char **saslUsernameWhitelist;
|
||||
#endif
|
||||
#if HAVE_POLKIT0
|
||||
DBusConnection *sysbus;
|
||||
#endif
|
||||
};
|
||||
|
||||
void qemudLog(int priority, const char *fmt, ...)
|
||||
ATTRIBUTE_FMT_PRINTF(2,3);
|
||||
|
||||
|
||||
|
||||
int qemudRegisterClientEvent(struct qemud_server *server,
|
||||
struct qemud_client *client);
|
||||
void qemudUpdateClientEvent(struct qemud_client *client);
|
||||
|
||||
void qemudDispatchClientFailure(struct qemud_client *client);
|
||||
|
||||
void
|
||||
qemudClientMessageQueuePush(struct qemud_client_message **queue,
|
||||
struct qemud_client_message *msg);
|
||||
struct qemud_client_message *
|
||||
qemudClientMessageQueueServe(struct qemud_client_message **queue);
|
||||
|
||||
void
|
||||
qemudClientMessageRelease(struct qemud_client *client,
|
||||
struct qemud_client_message *msg);
|
||||
|
||||
|
||||
#if HAVE_POLKIT
|
||||
int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,116 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# the following is the LSB init header see
|
||||
# http://www.linux-foundation.org/spec//booksets/LSB-Core-generic/LSB-Core-generic.html#INITSCRCOMCONV
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: libvirtd
|
||||
# Required-Start: $network messagebus
|
||||
# Should-Start: $named
|
||||
# Should-Start: xend
|
||||
# Should-Start: hal
|
||||
# Should-Start: avahi
|
||||
# Required-Stop: $network messagebus
|
||||
# Should-Stop: $named
|
||||
# Default-Start: 3 4 5
|
||||
# Short-Description: daemon for libvirt virtualization API
|
||||
# Description: This is a daemon for managing guest instances
|
||||
# and libvirt virtual networks
|
||||
# See http://libvirt.org
|
||||
### END INIT INFO
|
||||
|
||||
# the following is chkconfig init header
|
||||
#
|
||||
# libvirtd: guest and virtual network management daemon
|
||||
#
|
||||
# chkconfig: 345 97 03
|
||||
# description: This is a daemon for managing guest instances
|
||||
# and libvirt virtual networks
|
||||
# See http://libvirt.org
|
||||
#
|
||||
# processname: libvirtd
|
||||
# pidfile: @localstatedir@/run/libvirtd.pid
|
||||
#
|
||||
|
||||
# Sanity checks.
|
||||
[ -x @sbindir@/libvirtd ] || exit 0
|
||||
|
||||
# Source function library.
|
||||
. @sysconfdir@/rc.d/init.d/functions
|
||||
|
||||
SERVICE=libvirtd
|
||||
PROCESS=libvirtd
|
||||
PIDFILE=@localstatedir@/run/$SERVICE.pid
|
||||
|
||||
LIBVIRTD_CONFIG=
|
||||
LIBVIRTD_ARGS=
|
||||
KRB5_KTNAME=/etc/libvirt/krb5.tab
|
||||
|
||||
test -f @sysconfdir@/sysconfig/libvirtd && . @sysconfdir@/sysconfig/libvirtd
|
||||
|
||||
LIBVIRTD_CONFIG_ARGS=
|
||||
if [ -n "$LIBVIRTD_CONFIG" ]
|
||||
then
|
||||
LIBVIRTD_CONFIG_ARGS="--config $LIBVIRTD_CONFIG"
|
||||
fi
|
||||
|
||||
RETVAL=0
|
||||
|
||||
start() {
|
||||
echo -n $"Starting $SERVICE daemon: "
|
||||
mkdir -p @localstatedir@/cache/libvirt
|
||||
rm -rf @localstatedir@/cache/libvirt/*
|
||||
KRB5_KTNAME=$KRB5_KTNAME daemon --pidfile $PIDFILE --check $SERVICE $PROCESS --daemon $LIBVIRTD_CONFIG_ARGS $LIBVIRTD_ARGS
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch @localstatedir@/lock/subsys/$SERVICE
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Stopping $SERVICE daemon: "
|
||||
|
||||
killproc -p $PIDFILE $PROCESS
|
||||
RETVAL=$?
|
||||
echo
|
||||
if [ $RETVAL -eq 0 ]; then
|
||||
rm -f @localstatedir@/lock/subsys/$SERVICE
|
||||
rm -f $PIDFILE
|
||||
rm -rf @localstatedir@/cache/libvirt/*
|
||||
fi
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reload() {
|
||||
echo -n $"Reloading $SERVICE configuration: "
|
||||
|
||||
killproc -p $PIDFILE $PROCESS -HUP
|
||||
RETVAL=$?
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start|stop|restart|reload)
|
||||
$1
|
||||
;;
|
||||
status)
|
||||
status -p $PIDFILE $PROCESS
|
||||
RETVAL=$?
|
||||
;;
|
||||
force-reload)
|
||||
reload
|
||||
;;
|
||||
condrestart|try-restart)
|
||||
[ -f @localstatedir@/lock/subsys/$SERVICE ] && restart || :
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
@@ -1,9 +0,0 @@
|
||||
@localstatedir@/log/libvirt/qemu/*.log @localstatedir@/log/libvirt/uml/*.log @localstatedir@/log/libvirt/lxc/*.log {
|
||||
weekly
|
||||
missingok
|
||||
rotate 4
|
||||
compress
|
||||
delaycompress
|
||||
copytruncate
|
||||
minsize 100k
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
Policy definitions for libvirt daemon
|
||||
|
||||
Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
|
||||
libvirt is licensed to you under the GNU Lesser General Public License
|
||||
version 2. See COPYING for details.
|
||||
|
||||
NOTE: If you make changes to this file, make sure to validate the file
|
||||
using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
file are instantly applied.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
<action id="org.libvirt.unix.monitor">
|
||||
<description>Monitor local virtualized systems</description>
|
||||
<message>System policy prevents monitoring of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
even if not part of a session -->
|
||||
<allow_any>yes</allow_any>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.libvirt.unix.manage">
|
||||
<description>Manage local virtualized systems</description>
|
||||
<message>System policy prevents management of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Only a program in the active host session can use libvirt in
|
||||
read-write mode for management, and we require user password -->
|
||||
<allow_any>no</allow_any>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep_session</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
@@ -1,42 +0,0 @@
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
Policy definitions for libvirt daemon
|
||||
|
||||
Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
|
||||
libvirt is licensed to you under the GNU Lesser General Public License
|
||||
version 2. See COPYING for details.
|
||||
|
||||
NOTE: If you make changes to this file, make sure to validate the file
|
||||
using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
file are instantly applied.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
<action id="org.libvirt.unix.monitor">
|
||||
<description>Monitor local virtualized systems</description>
|
||||
<message>System policy prevents monitoring of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
even if not part of a session -->
|
||||
<allow_any>yes</allow_any>
|
||||
<allow_inactive>yes</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.libvirt.unix.manage">
|
||||
<description>Manage local virtualized systems</description>
|
||||
<message>System policy prevents management of local virtualized systems</message>
|
||||
<defaults>
|
||||
<!-- Only a program in the active host session can use libvirt in
|
||||
read-write mode for management, and we require user password -->
|
||||
<allow_any>no</allow_any>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
@@ -1,28 +0,0 @@
|
||||
# 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're only using TLS, then you can turn on any mechanisms
|
||||
# you like for authentication, because TLS provides the encryption
|
||||
#
|
||||
# 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: digest-md5 gssapi
|
||||
|
||||
# MIT kerberos ignores this option & needs KRB5_KTNAME env var.
|
||||
# May be useful for other non-Linux OS though....
|
||||
keytab: /etc/libvirt/krb5.tab
|
||||
|
||||
# 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 -a libvirt' to browse it
|
||||
sasldb_path: /etc/libvirt/passwd.db
|
@@ -1,17 +0,0 @@
|
||||
# Override the default config file
|
||||
#LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf
|
||||
|
||||
# Listen for TCP/IP connections
|
||||
# NB. must setup TLS/SSL keys prior to using this
|
||||
#LIBVIRTD_ARGS="--listen"
|
||||
|
||||
# Override Kerberos service keytab for SASL/GSSAPI
|
||||
#KRB5_KTNAME=/etc/libvirt/krb5.tab
|
||||
|
||||
# Override the QEMU/SDL default audio driver probing when
|
||||
# starting virtual machines using SDL graphics
|
||||
#
|
||||
# NB these have no effect for VMs using VNC
|
||||
#QEMU_AUDIO_DRV=sdl
|
||||
#
|
||||
#SDL_AUDIODRIVER=pulse
|
508
daemon/mdns.c
508
daemon/mdns.c
@@ -1,508 +0,0 @@
|
||||
/*
|
||||
* mdns.c: advertise libvirt hypervisor connections
|
||||
*
|
||||
* Copyright (C) 2007 Daniel P. Berrange
|
||||
*
|
||||
* Derived from Avahi example service provider code.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <avahi-client/client.h>
|
||||
#include <avahi-client/publish.h>
|
||||
|
||||
#include <avahi-common/alternative.h>
|
||||
#include <avahi-common/simple-watch.h>
|
||||
#include <avahi-common/malloc.h>
|
||||
#include <avahi-common/error.h>
|
||||
#include <avahi-common/timeval.h>
|
||||
|
||||
#include "libvirtd.h"
|
||||
#include "mdns.h"
|
||||
#include "event.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define AVAHI_DEBUG(fmt, ...) DEBUG(fmt, __VA_ARGS__)
|
||||
|
||||
struct libvirtd_mdns_entry {
|
||||
char *type;
|
||||
int port;
|
||||
struct libvirtd_mdns_entry *next;
|
||||
};
|
||||
|
||||
struct libvirtd_mdns_group {
|
||||
struct libvirtd_mdns *mdns;
|
||||
AvahiEntryGroup *handle;
|
||||
char *name;
|
||||
struct libvirtd_mdns_entry *entry;
|
||||
struct libvirtd_mdns_group *next;
|
||||
};
|
||||
|
||||
struct libvirtd_mdns {
|
||||
AvahiClient *client;
|
||||
AvahiPoll *poller;
|
||||
struct libvirtd_mdns_group *group;
|
||||
};
|
||||
|
||||
/* Avahi API requires this struct names in the app :-( */
|
||||
struct AvahiWatch {
|
||||
int watch;
|
||||
int fd;
|
||||
int revents;
|
||||
AvahiWatchCallback callback;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
/* Avahi API requires this struct names in the app :-( */
|
||||
struct AvahiTimeout {
|
||||
int timer;
|
||||
AvahiTimeoutCallback callback;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
|
||||
static void libvirtd_mdns_create_services(struct libvirtd_mdns_group *group);
|
||||
|
||||
/* Called whenever the entry group state changes */
|
||||
static void libvirtd_mdns_group_callback(AvahiEntryGroup *g ATTRIBUTE_UNUSED, AvahiEntryGroupState state, void *userdata) {
|
||||
struct libvirtd_mdns_group *group = (struct libvirtd_mdns_group *)userdata;
|
||||
|
||||
switch (state) {
|
||||
case AVAHI_ENTRY_GROUP_ESTABLISHED:
|
||||
/* The entry group has been established successfully */
|
||||
AVAHI_DEBUG("Group '%s' established", group->name);
|
||||
break;
|
||||
|
||||
case AVAHI_ENTRY_GROUP_COLLISION:
|
||||
{
|
||||
char *n;
|
||||
|
||||
/* A service name collision happened. Let's pick a new name */
|
||||
n = avahi_alternative_service_name(group->name);
|
||||
VIR_FREE(group->name);
|
||||
group->name = n;
|
||||
|
||||
AVAHI_DEBUG("Group name collision, renaming service to '%s'", group->name);
|
||||
|
||||
/* And recreate the services */
|
||||
libvirtd_mdns_create_services(group);
|
||||
}
|
||||
break;
|
||||
|
||||
case AVAHI_ENTRY_GROUP_FAILURE :
|
||||
AVAHI_DEBUG("Group failure: %s", avahi_strerror(avahi_client_errno(group->mdns->client)));
|
||||
|
||||
/* Some kind of failure happened while we were registering our services */
|
||||
//avahi_simple_poll_quit(simple_poll);
|
||||
break;
|
||||
|
||||
case AVAHI_ENTRY_GROUP_UNCOMMITED:
|
||||
case AVAHI_ENTRY_GROUP_REGISTERING:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_create_services(struct libvirtd_mdns_group *group) {
|
||||
struct libvirtd_mdns *mdns = group->mdns;
|
||||
struct libvirtd_mdns_entry *entry;
|
||||
int ret;
|
||||
AVAHI_DEBUG("Adding services to '%s'", group->name);
|
||||
|
||||
/* If we've no services to advertise, just reset the group to make
|
||||
* sure it is emptied of any previously advertised services */
|
||||
if (!group->entry) {
|
||||
if (group->handle)
|
||||
avahi_entry_group_reset(group->handle);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is the first time we're called, let's create a new entry group */
|
||||
if (!group->handle) {
|
||||
AVAHI_DEBUG("Creating initial group %s", group->name);
|
||||
if (!(group->handle = avahi_entry_group_new(mdns->client, libvirtd_mdns_group_callback, group))) {
|
||||
AVAHI_DEBUG("avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(mdns->client)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entry = group->entry;
|
||||
while (entry) {
|
||||
if ((ret = avahi_entry_group_add_service(group->handle,
|
||||
AVAHI_IF_UNSPEC,
|
||||
AVAHI_PROTO_UNSPEC,
|
||||
0,
|
||||
group->name,
|
||||
entry->type,
|
||||
NULL,
|
||||
NULL,
|
||||
entry->port,
|
||||
NULL)) < 0) {
|
||||
AVAHI_DEBUG("Failed to add %s service on port %d: %s",
|
||||
entry->type, entry->port, avahi_strerror(ret));
|
||||
avahi_entry_group_reset(group->handle);
|
||||
return;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
/* Tell the server to register the service */
|
||||
if ((ret = avahi_entry_group_commit(group->handle)) < 0) {
|
||||
avahi_entry_group_reset(group->handle);
|
||||
AVAHI_DEBUG("Failed to commit entry_group: %s", avahi_strerror(ret));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void libvirtd_mdns_client_callback(AvahiClient *c, AvahiClientState state, void *userdata) {
|
||||
struct libvirtd_mdns *mdns = (struct libvirtd_mdns *)userdata;
|
||||
struct libvirtd_mdns_group *group;
|
||||
if (!mdns->client)
|
||||
mdns->client = c;
|
||||
|
||||
/* Called whenever the client or server state changes */
|
||||
switch (state) {
|
||||
case AVAHI_CLIENT_S_RUNNING:
|
||||
/* The server has startup successfully and registered its host
|
||||
* name on the network, so it's time to create our services */
|
||||
AVAHI_DEBUG("Client running %p", mdns->client);
|
||||
group = mdns->group;
|
||||
while (group) {
|
||||
libvirtd_mdns_create_services(group);
|
||||
group = group->next;
|
||||
}
|
||||
break;
|
||||
|
||||
case AVAHI_CLIENT_FAILURE:
|
||||
AVAHI_DEBUG("Client failure: %s", avahi_strerror(avahi_client_errno(c)));
|
||||
libvirtd_mdns_stop(mdns);
|
||||
libvirtd_mdns_start(mdns);
|
||||
break;
|
||||
|
||||
case AVAHI_CLIENT_S_COLLISION:
|
||||
/* Let's drop our registered services. When the server is back
|
||||
* in AVAHI_SERVER_RUNNING state we will register them
|
||||
* again with the new host name. */
|
||||
|
||||
/* Fallthrough */
|
||||
|
||||
case AVAHI_CLIENT_S_REGISTERING:
|
||||
/* The server records are now being established. This
|
||||
* might be caused by a host name change. We need to wait
|
||||
* for our own records to register until the host name is
|
||||
* properly established. */
|
||||
AVAHI_DEBUG("Client collision/connecting %p", mdns->client);
|
||||
group = mdns->group;
|
||||
while (group) {
|
||||
if (group->handle)
|
||||
avahi_entry_group_reset(group->handle);
|
||||
group = group->next;
|
||||
}
|
||||
break;
|
||||
|
||||
case AVAHI_CLIENT_CONNECTING:
|
||||
AVAHI_DEBUG("Client connecting.... %p", mdns->client);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void libvirtd_mdns_watch_dispatch(int watch, int fd, int events, void *opaque)
|
||||
{
|
||||
AvahiWatch *w = (AvahiWatch*)opaque;
|
||||
int fd_events = virEventHandleTypeToPollEvent(events);
|
||||
AVAHI_DEBUG("Dispatch watch %d FD %d Event %d", watch, fd, fd_events);
|
||||
w->revents = fd_events;
|
||||
w->callback(w, fd, fd_events, w->userdata);
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_watch_dofree(void *w)
|
||||
{
|
||||
VIR_FREE(w);
|
||||
}
|
||||
|
||||
|
||||
static AvahiWatch *libvirtd_mdns_watch_new(const AvahiPoll *api ATTRIBUTE_UNUSED,
|
||||
int fd, AvahiWatchEvent event,
|
||||
AvahiWatchCallback cb, void *userdata) {
|
||||
AvahiWatch *w;
|
||||
virEventHandleType hEvents;
|
||||
if (VIR_ALLOC(w) < 0)
|
||||
return NULL;
|
||||
|
||||
w->fd = fd;
|
||||
w->revents = 0;
|
||||
w->callback = cb;
|
||||
w->userdata = userdata;
|
||||
|
||||
AVAHI_DEBUG("New handle %p FD %d Event %d", w, w->fd, event);
|
||||
hEvents = virPollEventToEventHandleType(event);
|
||||
if ((w->watch = virEventAddHandleImpl(fd, hEvents,
|
||||
libvirtd_mdns_watch_dispatch,
|
||||
w,
|
||||
libvirtd_mdns_watch_dofree)) < 0) {
|
||||
VIR_FREE(w);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_watch_update(AvahiWatch *w, AvahiWatchEvent event)
|
||||
{
|
||||
AVAHI_DEBUG("Update handle %p FD %d Event %d", w, w->fd, event);
|
||||
virEventUpdateHandleImpl(w->watch, event);
|
||||
}
|
||||
|
||||
static AvahiWatchEvent libvirtd_mdns_watch_get_events(AvahiWatch *w)
|
||||
{
|
||||
AVAHI_DEBUG("Get handle events %p %d", w, w->fd);
|
||||
return w->revents;
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_watch_free(AvahiWatch *w)
|
||||
{
|
||||
AVAHI_DEBUG("Free handle %p %d", w, w->fd);
|
||||
virEventRemoveHandleImpl(w->watch);
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_timeout_dispatch(int timer ATTRIBUTE_UNUSED, void *opaque)
|
||||
{
|
||||
AvahiTimeout *t = (AvahiTimeout*)opaque;
|
||||
AVAHI_DEBUG("Dispatch timeout %p %d", t, timer);
|
||||
virEventUpdateTimeoutImpl(t->timer, -1);
|
||||
t->callback(t, t->userdata);
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_timeout_dofree(void *t)
|
||||
{
|
||||
VIR_FREE(t);
|
||||
}
|
||||
|
||||
static AvahiTimeout *libvirtd_mdns_timeout_new(const AvahiPoll *api ATTRIBUTE_UNUSED,
|
||||
const struct timeval *tv,
|
||||
AvahiTimeoutCallback cb,
|
||||
void *userdata)
|
||||
{
|
||||
AvahiTimeout *t;
|
||||
struct timeval now;
|
||||
long long nowms, thenms, timeout;
|
||||
AVAHI_DEBUG("Add timeout TV %p", tv);
|
||||
if (VIR_ALLOC(t) < 0)
|
||||
return NULL;
|
||||
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
VIR_FREE(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVAHI_DEBUG("Trigger timed for %d %d %d %d",
|
||||
(int)now.tv_sec, (int)now.tv_usec,
|
||||
(int)(tv ? tv->tv_sec : 0), (int)(tv ? tv->tv_usec : 0));
|
||||
nowms = (now.tv_sec * 1000ll) + (now.tv_usec / 1000ll);
|
||||
if (tv) {
|
||||
thenms = (tv->tv_sec * 1000ll) + (tv->tv_usec/1000ll);
|
||||
timeout = thenms > nowms ? nowms - thenms : 0;
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
} else {
|
||||
timeout = -1;
|
||||
}
|
||||
|
||||
t->timer = virEventAddTimeoutImpl(timeout,
|
||||
libvirtd_mdns_timeout_dispatch,
|
||||
t,
|
||||
libvirtd_mdns_timeout_dofree);
|
||||
t->callback = cb;
|
||||
t->userdata = userdata;
|
||||
|
||||
if (t->timer < 0) {
|
||||
VIR_FREE(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_timeout_update(AvahiTimeout *t, const struct timeval *tv)
|
||||
{
|
||||
struct timeval now;
|
||||
long long nowms, thenms, timeout;
|
||||
AVAHI_DEBUG("Update timeout %p TV %p", t, tv);
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
VIR_FREE(t);
|
||||
return;
|
||||
}
|
||||
|
||||
nowms = (now.tv_sec * 1000ll) + (now.tv_usec / 1000ll);
|
||||
if (tv) {
|
||||
thenms = ((tv->tv_sec * 1000ll) + (tv->tv_usec/1000ll));
|
||||
timeout = thenms > nowms ? nowms - thenms : 0;
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
} else {
|
||||
timeout = -1;
|
||||
}
|
||||
|
||||
virEventUpdateTimeoutImpl(t->timer, timeout);
|
||||
}
|
||||
|
||||
static void libvirtd_mdns_timeout_free(AvahiTimeout *t)
|
||||
{
|
||||
AVAHI_DEBUG("Free timeout %p", t);
|
||||
virEventRemoveTimeoutImpl(t->timer);
|
||||
}
|
||||
|
||||
|
||||
static AvahiPoll *libvirtd_create_poll(void)
|
||||
{
|
||||
AvahiPoll *p;
|
||||
if (VIR_ALLOC(p) < 0)
|
||||
return NULL;
|
||||
|
||||
p->userdata = NULL;
|
||||
|
||||
p->watch_new = libvirtd_mdns_watch_new;
|
||||
p->watch_update = libvirtd_mdns_watch_update;
|
||||
p->watch_get_events = libvirtd_mdns_watch_get_events;
|
||||
p->watch_free = libvirtd_mdns_watch_free;
|
||||
|
||||
p->timeout_new = libvirtd_mdns_timeout_new;
|
||||
p->timeout_update = libvirtd_mdns_timeout_update;
|
||||
p->timeout_free = libvirtd_mdns_timeout_free;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
struct libvirtd_mdns *libvirtd_mdns_new(void)
|
||||
{
|
||||
struct libvirtd_mdns *mdns;
|
||||
if (VIR_ALLOC(mdns) < 0)
|
||||
return NULL;
|
||||
|
||||
/* Allocate main loop object */
|
||||
if (!(mdns->poller = libvirtd_create_poll())) {
|
||||
VIR_FREE(mdns);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mdns;
|
||||
}
|
||||
|
||||
int libvirtd_mdns_start(struct libvirtd_mdns *mdns)
|
||||
{
|
||||
int error;
|
||||
AVAHI_DEBUG("Starting client %p", mdns);
|
||||
mdns->client = avahi_client_new(mdns->poller, AVAHI_CLIENT_NO_FAIL, libvirtd_mdns_client_callback, mdns, &error);
|
||||
|
||||
if (!mdns->client) {
|
||||
AVAHI_DEBUG("Failed to create mDNS client: %s", avahi_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct libvirtd_mdns_group *libvirtd_mdns_add_group(struct libvirtd_mdns *mdns, const char *name) {
|
||||
struct libvirtd_mdns_group *group;
|
||||
|
||||
AVAHI_DEBUG("Adding group '%s'", name);
|
||||
if (VIR_ALLOC(group) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!(group->name = strdup(name))) {
|
||||
VIR_FREE(group);
|
||||
return NULL;
|
||||
}
|
||||
group->mdns = mdns;
|
||||
group->next = mdns->group;
|
||||
mdns->group = group;
|
||||
return group;
|
||||
}
|
||||
|
||||
void libvirtd_mdns_remove_group(struct libvirtd_mdns *mdns, struct libvirtd_mdns_group *group) {
|
||||
struct libvirtd_mdns_group *tmp = mdns->group, *prev = NULL;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp == group) {
|
||||
VIR_FREE(group->name);
|
||||
if (prev)
|
||||
prev->next = group->next;
|
||||
else
|
||||
group->mdns->group = group->next;
|
||||
VIR_FREE(group);
|
||||
return;
|
||||
}
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
struct libvirtd_mdns_entry *libvirtd_mdns_add_entry(struct libvirtd_mdns_group *group, const char *type, int port) {
|
||||
struct libvirtd_mdns_entry *entry;
|
||||
|
||||
AVAHI_DEBUG("Adding entry %s %d to group %s", type, port, group->name);
|
||||
if (VIR_ALLOC(entry) < 0)
|
||||
return NULL;
|
||||
|
||||
entry->port = port;
|
||||
if (!(entry->type = strdup(type))) {
|
||||
VIR_FREE(entry);
|
||||
return NULL;
|
||||
}
|
||||
entry->next = group->entry;
|
||||
group->entry = entry;
|
||||
return entry;
|
||||
}
|
||||
|
||||
void libvirtd_mdns_remove_entry(struct libvirtd_mdns_group *group, struct libvirtd_mdns_entry *entry) {
|
||||
struct libvirtd_mdns_entry *tmp = group->entry, *prev = NULL;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp == entry) {
|
||||
VIR_FREE(entry->type);
|
||||
if (prev)
|
||||
prev->next = entry->next;
|
||||
else
|
||||
group->entry = entry->next;
|
||||
return;
|
||||
}
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void libvirtd_mdns_stop(struct libvirtd_mdns *mdns)
|
||||
{
|
||||
struct libvirtd_mdns_group *group = mdns->group;
|
||||
while (group) {
|
||||
if (group->handle) {
|
||||
avahi_entry_group_free(group->handle);
|
||||
group->handle = NULL;
|
||||
}
|
||||
group = group->next;
|
||||
}
|
||||
if (mdns->client)
|
||||
avahi_client_free(mdns->client);
|
||||
mdns->client = NULL;
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* mdns.c: advertise libvirt hypervisor connections
|
||||
*
|
||||
* Copyright (C) 2007 Daniel P. Berrange
|
||||
*
|
||||
* Derived from Avahi example service provider code.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef __VIRTD_MDNS_H__
|
||||
#define __VIRTD_MDNS_H__
|
||||
|
||||
struct libvirtd_mdns;
|
||||
struct libvirtd_mdns_group;
|
||||
struct libvirtd_mdns_entry;
|
||||
|
||||
/**
|
||||
* Prepares a new mdns manager object for use
|
||||
*/
|
||||
struct libvirtd_mdns *libvirtd_mdns_new(void);
|
||||
|
||||
/**
|
||||
* Starts the mdns client, advertising any groups/entries currently registered
|
||||
*
|
||||
* @mdns: manager to start advertising
|
||||
*
|
||||
* Starts the mdns client. Services may not be immediately visible, since
|
||||
* it may asynchronously wait for the mdns service to startup
|
||||
*
|
||||
* returns -1 upon failure, 0 upon success.
|
||||
*/
|
||||
int libvirtd_mdns_start(struct libvirtd_mdns *mdns);
|
||||
|
||||
/**
|
||||
* Stops the mdns client, removing any advertisements
|
||||
*
|
||||
* @mdns: manager to start advertising
|
||||
*
|
||||
*/
|
||||
void libvirtd_mdns_stop(struct libvirtd_mdns *mdns);
|
||||
|
||||
/**
|
||||
* Adds a group container for advertisement
|
||||
*
|
||||
* @mdns manager to attach the group to
|
||||
* @name unique human readable service name
|
||||
*
|
||||
* returns the group record, or NULL upon failure
|
||||
*/
|
||||
struct libvirtd_mdns_group *libvirtd_mdns_add_group(struct libvirtd_mdns *mdns, const char *name);
|
||||
|
||||
/**
|
||||
* Removes a group container from advertisement
|
||||
*
|
||||
* @mdns amanger to detach group from
|
||||
* @group group to remove
|
||||
*/
|
||||
void libvirtd_mdns_remove_group(struct libvirtd_mdns *mdns, struct libvirtd_mdns_group *group);
|
||||
|
||||
/**
|
||||
* Adds a service entry in a group
|
||||
*
|
||||
* @group group to attach the entry to
|
||||
* @type service type string
|
||||
* @port tcp port number
|
||||
*
|
||||
* returns the service record, or NULL upon failure
|
||||
*/
|
||||
struct libvirtd_mdns_entry *libvirtd_mdns_add_entry(struct libvirtd_mdns_group *group, const char *type, int port);
|
||||
|
||||
/**
|
||||
* Removes a service entry from a group
|
||||
*
|
||||
* @group group to detach service entry from
|
||||
* @entry service entry to remove
|
||||
*/
|
||||
void libvirtd_mdns_remove_entry(struct libvirtd_mdns_group *group, struct libvirtd_mdns_entry *entry);
|
||||
|
||||
#endif /* __VIRTD_MDNS_H__ */
|
5410
daemon/remote.c
5410
daemon/remote.c
File diff suppressed because it is too large
Load Diff
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* remote.h: handlers for RPC method calls
|
||||
*
|
||||
* Copyright (C) 2007, 2008, 2009 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Richard W.M. Jones <rjones@redhat.com>
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __LIBVIRTD_REMOTE_H__
|
||||
#define __LIBVIRTD_REMOTE_H__
|
||||
|
||||
|
||||
#include "libvirtd.h"
|
||||
|
||||
typedef union {
|
||||
#include "remote_dispatch_args.h"
|
||||
} dispatch_args;
|
||||
|
||||
typedef union {
|
||||
#include "remote_dispatch_ret.h"
|
||||
} dispatch_ret;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* When the RPC handler is called:
|
||||
*
|
||||
* - Server object is unlocked
|
||||
* - Client object is unlocked
|
||||
*
|
||||
* Both must be locked before use. Server lock must
|
||||
* be held before attempting to lock client.
|
||||
*
|
||||
* Without any locking, it is safe to use:
|
||||
*
|
||||
* 'conn', 'rerr', 'args and 'ret'
|
||||
*/
|
||||
typedef int (*dispatch_fn) (struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
virConnectPtr conn,
|
||||
remote_message_header *hdr,
|
||||
remote_error *err,
|
||||
dispatch_args *args,
|
||||
dispatch_ret *ret);
|
||||
|
||||
typedef struct {
|
||||
dispatch_fn fn;
|
||||
xdrproc_t args_filter;
|
||||
xdrproc_t ret_filter;
|
||||
} dispatch_data;
|
||||
|
||||
|
||||
const dispatch_data const *remoteGetDispatchData(int proc);
|
||||
|
||||
|
||||
|
||||
#endif /* __LIBVIRTD_REMOTE_H__ */
|
@@ -1,137 +0,0 @@
|
||||
/* Automatically generated by remote_generate_stubs.pl.
|
||||
* Do not edit this file. Any changes you make will be lost.
|
||||
*/
|
||||
|
||||
remote_open_args val_remote_open_args;
|
||||
remote_get_max_vcpus_args val_remote_get_max_vcpus_args;
|
||||
remote_domain_attach_device_args val_remote_domain_attach_device_args;
|
||||
remote_domain_create_args val_remote_domain_create_args;
|
||||
remote_domain_create_xml_args val_remote_domain_create_xml_args;
|
||||
remote_domain_define_xml_args val_remote_domain_define_xml_args;
|
||||
remote_domain_destroy_args val_remote_domain_destroy_args;
|
||||
remote_domain_detach_device_args val_remote_domain_detach_device_args;
|
||||
remote_domain_dump_xml_args val_remote_domain_dump_xml_args;
|
||||
remote_domain_get_autostart_args val_remote_domain_get_autostart_args;
|
||||
remote_domain_get_info_args val_remote_domain_get_info_args;
|
||||
remote_domain_get_max_memory_args val_remote_domain_get_max_memory_args;
|
||||
remote_domain_get_max_vcpus_args val_remote_domain_get_max_vcpus_args;
|
||||
remote_domain_get_os_type_args val_remote_domain_get_os_type_args;
|
||||
remote_domain_get_vcpus_args val_remote_domain_get_vcpus_args;
|
||||
remote_list_defined_domains_args val_remote_list_defined_domains_args;
|
||||
remote_domain_lookup_by_id_args val_remote_domain_lookup_by_id_args;
|
||||
remote_domain_lookup_by_name_args val_remote_domain_lookup_by_name_args;
|
||||
remote_domain_lookup_by_uuid_args val_remote_domain_lookup_by_uuid_args;
|
||||
remote_domain_pin_vcpu_args val_remote_domain_pin_vcpu_args;
|
||||
remote_domain_reboot_args val_remote_domain_reboot_args;
|
||||
remote_domain_resume_args val_remote_domain_resume_args;
|
||||
remote_domain_set_autostart_args val_remote_domain_set_autostart_args;
|
||||
remote_domain_set_max_memory_args val_remote_domain_set_max_memory_args;
|
||||
remote_domain_set_memory_args val_remote_domain_set_memory_args;
|
||||
remote_domain_set_vcpus_args val_remote_domain_set_vcpus_args;
|
||||
remote_domain_shutdown_args val_remote_domain_shutdown_args;
|
||||
remote_domain_suspend_args val_remote_domain_suspend_args;
|
||||
remote_domain_undefine_args val_remote_domain_undefine_args;
|
||||
remote_list_defined_networks_args val_remote_list_defined_networks_args;
|
||||
remote_list_domains_args val_remote_list_domains_args;
|
||||
remote_list_networks_args val_remote_list_networks_args;
|
||||
remote_network_create_args val_remote_network_create_args;
|
||||
remote_network_create_xml_args val_remote_network_create_xml_args;
|
||||
remote_network_define_xml_args val_remote_network_define_xml_args;
|
||||
remote_network_destroy_args val_remote_network_destroy_args;
|
||||
remote_network_dump_xml_args val_remote_network_dump_xml_args;
|
||||
remote_network_get_autostart_args val_remote_network_get_autostart_args;
|
||||
remote_network_get_bridge_name_args val_remote_network_get_bridge_name_args;
|
||||
remote_network_lookup_by_name_args val_remote_network_lookup_by_name_args;
|
||||
remote_network_lookup_by_uuid_args val_remote_network_lookup_by_uuid_args;
|
||||
remote_network_set_autostart_args val_remote_network_set_autostart_args;
|
||||
remote_network_undefine_args val_remote_network_undefine_args;
|
||||
remote_domain_core_dump_args val_remote_domain_core_dump_args;
|
||||
remote_domain_restore_args val_remote_domain_restore_args;
|
||||
remote_domain_save_args val_remote_domain_save_args;
|
||||
remote_domain_get_scheduler_type_args val_remote_domain_get_scheduler_type_args;
|
||||
remote_domain_get_scheduler_parameters_args val_remote_domain_get_scheduler_parameters_args;
|
||||
remote_domain_set_scheduler_parameters_args val_remote_domain_set_scheduler_parameters_args;
|
||||
remote_supports_feature_args val_remote_supports_feature_args;
|
||||
remote_domain_migrate_prepare_args val_remote_domain_migrate_prepare_args;
|
||||
remote_domain_migrate_perform_args val_remote_domain_migrate_perform_args;
|
||||
remote_domain_migrate_finish_args val_remote_domain_migrate_finish_args;
|
||||
remote_domain_block_stats_args val_remote_domain_block_stats_args;
|
||||
remote_domain_interface_stats_args val_remote_domain_interface_stats_args;
|
||||
remote_auth_sasl_start_args val_remote_auth_sasl_start_args;
|
||||
remote_auth_sasl_step_args val_remote_auth_sasl_step_args;
|
||||
remote_list_storage_pools_args val_remote_list_storage_pools_args;
|
||||
remote_list_defined_storage_pools_args val_remote_list_defined_storage_pools_args;
|
||||
remote_find_storage_pool_sources_args val_remote_find_storage_pool_sources_args;
|
||||
remote_storage_pool_create_xml_args val_remote_storage_pool_create_xml_args;
|
||||
remote_storage_pool_define_xml_args val_remote_storage_pool_define_xml_args;
|
||||
remote_storage_pool_create_args val_remote_storage_pool_create_args;
|
||||
remote_storage_pool_build_args val_remote_storage_pool_build_args;
|
||||
remote_storage_pool_destroy_args val_remote_storage_pool_destroy_args;
|
||||
remote_storage_pool_delete_args val_remote_storage_pool_delete_args;
|
||||
remote_storage_pool_undefine_args val_remote_storage_pool_undefine_args;
|
||||
remote_storage_pool_refresh_args val_remote_storage_pool_refresh_args;
|
||||
remote_storage_pool_lookup_by_name_args val_remote_storage_pool_lookup_by_name_args;
|
||||
remote_storage_pool_lookup_by_uuid_args val_remote_storage_pool_lookup_by_uuid_args;
|
||||
remote_storage_pool_lookup_by_volume_args val_remote_storage_pool_lookup_by_volume_args;
|
||||
remote_storage_pool_get_info_args val_remote_storage_pool_get_info_args;
|
||||
remote_storage_pool_dump_xml_args val_remote_storage_pool_dump_xml_args;
|
||||
remote_storage_pool_get_autostart_args val_remote_storage_pool_get_autostart_args;
|
||||
remote_storage_pool_set_autostart_args val_remote_storage_pool_set_autostart_args;
|
||||
remote_storage_pool_num_of_volumes_args val_remote_storage_pool_num_of_volumes_args;
|
||||
remote_storage_pool_list_volumes_args val_remote_storage_pool_list_volumes_args;
|
||||
remote_storage_vol_create_xml_args val_remote_storage_vol_create_xml_args;
|
||||
remote_storage_vol_delete_args val_remote_storage_vol_delete_args;
|
||||
remote_storage_vol_lookup_by_name_args val_remote_storage_vol_lookup_by_name_args;
|
||||
remote_storage_vol_lookup_by_key_args val_remote_storage_vol_lookup_by_key_args;
|
||||
remote_storage_vol_lookup_by_path_args val_remote_storage_vol_lookup_by_path_args;
|
||||
remote_storage_vol_get_info_args val_remote_storage_vol_get_info_args;
|
||||
remote_storage_vol_dump_xml_args val_remote_storage_vol_dump_xml_args;
|
||||
remote_storage_vol_get_path_args val_remote_storage_vol_get_path_args;
|
||||
remote_node_get_cells_free_memory_args val_remote_node_get_cells_free_memory_args;
|
||||
remote_domain_block_peek_args val_remote_domain_block_peek_args;
|
||||
remote_domain_memory_peek_args val_remote_domain_memory_peek_args;
|
||||
remote_domain_migrate_prepare2_args val_remote_domain_migrate_prepare2_args;
|
||||
remote_domain_migrate_finish2_args val_remote_domain_migrate_finish2_args;
|
||||
remote_node_num_of_devices_args val_remote_node_num_of_devices_args;
|
||||
remote_node_list_devices_args val_remote_node_list_devices_args;
|
||||
remote_node_device_lookup_by_name_args val_remote_node_device_lookup_by_name_args;
|
||||
remote_node_device_dump_xml_args val_remote_node_device_dump_xml_args;
|
||||
remote_node_device_get_parent_args val_remote_node_device_get_parent_args;
|
||||
remote_node_device_num_of_caps_args val_remote_node_device_num_of_caps_args;
|
||||
remote_node_device_list_caps_args val_remote_node_device_list_caps_args;
|
||||
remote_node_device_dettach_args val_remote_node_device_dettach_args;
|
||||
remote_node_device_re_attach_args val_remote_node_device_re_attach_args;
|
||||
remote_node_device_reset_args val_remote_node_device_reset_args;
|
||||
remote_domain_get_security_label_args val_remote_domain_get_security_label_args;
|
||||
remote_node_device_create_xml_args val_remote_node_device_create_xml_args;
|
||||
remote_node_device_destroy_args val_remote_node_device_destroy_args;
|
||||
remote_storage_vol_create_xml_from_args val_remote_storage_vol_create_xml_from_args;
|
||||
remote_list_interfaces_args val_remote_list_interfaces_args;
|
||||
remote_interface_lookup_by_name_args val_remote_interface_lookup_by_name_args;
|
||||
remote_interface_lookup_by_mac_string_args val_remote_interface_lookup_by_mac_string_args;
|
||||
remote_interface_get_xml_desc_args val_remote_interface_get_xml_desc_args;
|
||||
remote_interface_define_xml_args val_remote_interface_define_xml_args;
|
||||
remote_interface_undefine_args val_remote_interface_undefine_args;
|
||||
remote_interface_create_args val_remote_interface_create_args;
|
||||
remote_interface_destroy_args val_remote_interface_destroy_args;
|
||||
remote_domain_xml_from_native_args val_remote_domain_xml_from_native_args;
|
||||
remote_domain_xml_to_native_args val_remote_domain_xml_to_native_args;
|
||||
remote_list_defined_interfaces_args val_remote_list_defined_interfaces_args;
|
||||
remote_list_secrets_args val_remote_list_secrets_args;
|
||||
remote_secret_lookup_by_uuid_args val_remote_secret_lookup_by_uuid_args;
|
||||
remote_secret_define_xml_args val_remote_secret_define_xml_args;
|
||||
remote_secret_get_xml_desc_args val_remote_secret_get_xml_desc_args;
|
||||
remote_secret_set_value_args val_remote_secret_set_value_args;
|
||||
remote_secret_get_value_args val_remote_secret_get_value_args;
|
||||
remote_secret_undefine_args val_remote_secret_undefine_args;
|
||||
remote_secret_lookup_by_usage_args val_remote_secret_lookup_by_usage_args;
|
||||
remote_domain_migrate_prepare_tunnel_args val_remote_domain_migrate_prepare_tunnel_args;
|
||||
remote_domain_is_active_args val_remote_domain_is_active_args;
|
||||
remote_domain_is_persistent_args val_remote_domain_is_persistent_args;
|
||||
remote_network_is_active_args val_remote_network_is_active_args;
|
||||
remote_network_is_persistent_args val_remote_network_is_persistent_args;
|
||||
remote_storage_pool_is_active_args val_remote_storage_pool_is_active_args;
|
||||
remote_storage_pool_is_persistent_args val_remote_storage_pool_is_persistent_args;
|
||||
remote_interface_is_active_args val_remote_interface_is_active_args;
|
||||
remote_cpu_compare_args val_remote_cpu_compare_args;
|
||||
remote_domain_memory_stats_args val_remote_domain_memory_stats_args;
|
File diff suppressed because it is too large
Load Diff
@@ -1,119 +0,0 @@
|
||||
/* Automatically generated by remote_generate_stubs.pl.
|
||||
* Do not edit this file. Any changes you make will be lost.
|
||||
*/
|
||||
|
||||
remote_get_type_ret val_remote_get_type_ret;
|
||||
remote_get_version_ret val_remote_get_version_ret;
|
||||
remote_get_max_vcpus_ret val_remote_get_max_vcpus_ret;
|
||||
remote_node_get_info_ret val_remote_node_get_info_ret;
|
||||
remote_get_capabilities_ret val_remote_get_capabilities_ret;
|
||||
remote_domain_create_xml_ret val_remote_domain_create_xml_ret;
|
||||
remote_domain_define_xml_ret val_remote_domain_define_xml_ret;
|
||||
remote_domain_dump_xml_ret val_remote_domain_dump_xml_ret;
|
||||
remote_domain_get_autostart_ret val_remote_domain_get_autostart_ret;
|
||||
remote_domain_get_info_ret val_remote_domain_get_info_ret;
|
||||
remote_domain_get_max_memory_ret val_remote_domain_get_max_memory_ret;
|
||||
remote_domain_get_max_vcpus_ret val_remote_domain_get_max_vcpus_ret;
|
||||
remote_domain_get_os_type_ret val_remote_domain_get_os_type_ret;
|
||||
remote_domain_get_vcpus_ret val_remote_domain_get_vcpus_ret;
|
||||
remote_list_defined_domains_ret val_remote_list_defined_domains_ret;
|
||||
remote_domain_lookup_by_id_ret val_remote_domain_lookup_by_id_ret;
|
||||
remote_domain_lookup_by_name_ret val_remote_domain_lookup_by_name_ret;
|
||||
remote_domain_lookup_by_uuid_ret val_remote_domain_lookup_by_uuid_ret;
|
||||
remote_num_of_defined_domains_ret val_remote_num_of_defined_domains_ret;
|
||||
remote_list_defined_networks_ret val_remote_list_defined_networks_ret;
|
||||
remote_list_domains_ret val_remote_list_domains_ret;
|
||||
remote_list_networks_ret val_remote_list_networks_ret;
|
||||
remote_network_create_xml_ret val_remote_network_create_xml_ret;
|
||||
remote_network_define_xml_ret val_remote_network_define_xml_ret;
|
||||
remote_network_dump_xml_ret val_remote_network_dump_xml_ret;
|
||||
remote_network_get_autostart_ret val_remote_network_get_autostart_ret;
|
||||
remote_network_get_bridge_name_ret val_remote_network_get_bridge_name_ret;
|
||||
remote_network_lookup_by_name_ret val_remote_network_lookup_by_name_ret;
|
||||
remote_network_lookup_by_uuid_ret val_remote_network_lookup_by_uuid_ret;
|
||||
remote_num_of_defined_networks_ret val_remote_num_of_defined_networks_ret;
|
||||
remote_num_of_domains_ret val_remote_num_of_domains_ret;
|
||||
remote_num_of_networks_ret val_remote_num_of_networks_ret;
|
||||
remote_domain_get_scheduler_type_ret val_remote_domain_get_scheduler_type_ret;
|
||||
remote_domain_get_scheduler_parameters_ret val_remote_domain_get_scheduler_parameters_ret;
|
||||
remote_get_hostname_ret val_remote_get_hostname_ret;
|
||||
remote_supports_feature_ret val_remote_supports_feature_ret;
|
||||
remote_domain_migrate_prepare_ret val_remote_domain_migrate_prepare_ret;
|
||||
remote_domain_migrate_finish_ret val_remote_domain_migrate_finish_ret;
|
||||
remote_domain_block_stats_ret val_remote_domain_block_stats_ret;
|
||||
remote_domain_interface_stats_ret val_remote_domain_interface_stats_ret;
|
||||
remote_auth_list_ret val_remote_auth_list_ret;
|
||||
remote_auth_sasl_init_ret val_remote_auth_sasl_init_ret;
|
||||
remote_auth_sasl_start_ret val_remote_auth_sasl_start_ret;
|
||||
remote_auth_sasl_step_ret val_remote_auth_sasl_step_ret;
|
||||
remote_auth_polkit_ret val_remote_auth_polkit_ret;
|
||||
remote_num_of_storage_pools_ret val_remote_num_of_storage_pools_ret;
|
||||
remote_list_storage_pools_ret val_remote_list_storage_pools_ret;
|
||||
remote_num_of_defined_storage_pools_ret val_remote_num_of_defined_storage_pools_ret;
|
||||
remote_list_defined_storage_pools_ret val_remote_list_defined_storage_pools_ret;
|
||||
remote_find_storage_pool_sources_ret val_remote_find_storage_pool_sources_ret;
|
||||
remote_storage_pool_create_xml_ret val_remote_storage_pool_create_xml_ret;
|
||||
remote_storage_pool_define_xml_ret val_remote_storage_pool_define_xml_ret;
|
||||
remote_storage_pool_lookup_by_name_ret val_remote_storage_pool_lookup_by_name_ret;
|
||||
remote_storage_pool_lookup_by_uuid_ret val_remote_storage_pool_lookup_by_uuid_ret;
|
||||
remote_storage_pool_lookup_by_volume_ret val_remote_storage_pool_lookup_by_volume_ret;
|
||||
remote_storage_pool_get_info_ret val_remote_storage_pool_get_info_ret;
|
||||
remote_storage_pool_dump_xml_ret val_remote_storage_pool_dump_xml_ret;
|
||||
remote_storage_pool_get_autostart_ret val_remote_storage_pool_get_autostart_ret;
|
||||
remote_storage_pool_num_of_volumes_ret val_remote_storage_pool_num_of_volumes_ret;
|
||||
remote_storage_pool_list_volumes_ret val_remote_storage_pool_list_volumes_ret;
|
||||
remote_storage_vol_create_xml_ret val_remote_storage_vol_create_xml_ret;
|
||||
remote_storage_vol_lookup_by_name_ret val_remote_storage_vol_lookup_by_name_ret;
|
||||
remote_storage_vol_lookup_by_key_ret val_remote_storage_vol_lookup_by_key_ret;
|
||||
remote_storage_vol_lookup_by_path_ret val_remote_storage_vol_lookup_by_path_ret;
|
||||
remote_storage_vol_get_info_ret val_remote_storage_vol_get_info_ret;
|
||||
remote_storage_vol_dump_xml_ret val_remote_storage_vol_dump_xml_ret;
|
||||
remote_storage_vol_get_path_ret val_remote_storage_vol_get_path_ret;
|
||||
remote_node_get_cells_free_memory_ret val_remote_node_get_cells_free_memory_ret;
|
||||
remote_node_get_free_memory_ret val_remote_node_get_free_memory_ret;
|
||||
remote_domain_block_peek_ret val_remote_domain_block_peek_ret;
|
||||
remote_domain_memory_peek_ret val_remote_domain_memory_peek_ret;
|
||||
remote_domain_events_register_ret val_remote_domain_events_register_ret;
|
||||
remote_domain_events_deregister_ret val_remote_domain_events_deregister_ret;
|
||||
remote_domain_migrate_prepare2_ret val_remote_domain_migrate_prepare2_ret;
|
||||
remote_domain_migrate_finish2_ret val_remote_domain_migrate_finish2_ret;
|
||||
remote_get_uri_ret val_remote_get_uri_ret;
|
||||
remote_node_num_of_devices_ret val_remote_node_num_of_devices_ret;
|
||||
remote_node_list_devices_ret val_remote_node_list_devices_ret;
|
||||
remote_node_device_lookup_by_name_ret val_remote_node_device_lookup_by_name_ret;
|
||||
remote_node_device_dump_xml_ret val_remote_node_device_dump_xml_ret;
|
||||
remote_node_device_get_parent_ret val_remote_node_device_get_parent_ret;
|
||||
remote_node_device_num_of_caps_ret val_remote_node_device_num_of_caps_ret;
|
||||
remote_node_device_list_caps_ret val_remote_node_device_list_caps_ret;
|
||||
remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret;
|
||||
remote_node_get_security_model_ret val_remote_node_get_security_model_ret;
|
||||
remote_node_device_create_xml_ret val_remote_node_device_create_xml_ret;
|
||||
remote_storage_vol_create_xml_from_ret val_remote_storage_vol_create_xml_from_ret;
|
||||
remote_num_of_interfaces_ret val_remote_num_of_interfaces_ret;
|
||||
remote_list_interfaces_ret val_remote_list_interfaces_ret;
|
||||
remote_interface_lookup_by_name_ret val_remote_interface_lookup_by_name_ret;
|
||||
remote_interface_lookup_by_mac_string_ret val_remote_interface_lookup_by_mac_string_ret;
|
||||
remote_interface_get_xml_desc_ret val_remote_interface_get_xml_desc_ret;
|
||||
remote_interface_define_xml_ret val_remote_interface_define_xml_ret;
|
||||
remote_domain_xml_from_native_ret val_remote_domain_xml_from_native_ret;
|
||||
remote_domain_xml_to_native_ret val_remote_domain_xml_to_native_ret;
|
||||
remote_num_of_defined_interfaces_ret val_remote_num_of_defined_interfaces_ret;
|
||||
remote_list_defined_interfaces_ret val_remote_list_defined_interfaces_ret;
|
||||
remote_num_of_secrets_ret val_remote_num_of_secrets_ret;
|
||||
remote_list_secrets_ret val_remote_list_secrets_ret;
|
||||
remote_secret_lookup_by_uuid_ret val_remote_secret_lookup_by_uuid_ret;
|
||||
remote_secret_define_xml_ret val_remote_secret_define_xml_ret;
|
||||
remote_secret_get_xml_desc_ret val_remote_secret_get_xml_desc_ret;
|
||||
remote_secret_get_value_ret val_remote_secret_get_value_ret;
|
||||
remote_secret_lookup_by_usage_ret val_remote_secret_lookup_by_usage_ret;
|
||||
remote_is_secure_ret val_remote_is_secure_ret;
|
||||
remote_domain_is_active_ret val_remote_domain_is_active_ret;
|
||||
remote_domain_is_persistent_ret val_remote_domain_is_persistent_ret;
|
||||
remote_network_is_active_ret val_remote_network_is_active_ret;
|
||||
remote_network_is_persistent_ret val_remote_network_is_persistent_ret;
|
||||
remote_storage_pool_is_active_ret val_remote_storage_pool_is_active_ret;
|
||||
remote_storage_pool_is_persistent_ret val_remote_storage_pool_is_persistent_ret;
|
||||
remote_interface_is_active_ret val_remote_interface_is_active_ret;
|
||||
remote_get_lib_version_ret val_remote_get_lib_version_ret;
|
||||
remote_cpu_compare_ret val_remote_cpu_compare_ret;
|
||||
remote_domain_memory_stats_ret val_remote_domain_memory_stats_ret;
|
@@ -1,804 +0,0 @@
|
||||
/* Automatically generated by remote_generate_stubs.pl.
|
||||
* Do not edit this file. Any changes you make will be lost.
|
||||
*/
|
||||
|
||||
{ /* (unused) => 0 */
|
||||
.fn = NULL,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* Open => 1 */
|
||||
.fn = (dispatch_fn) remoteDispatchOpen,
|
||||
.args_filter = (xdrproc_t) xdr_remote_open_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* Close => 2 */
|
||||
.fn = (dispatch_fn) remoteDispatchClose,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* GetType => 3 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetType,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_type_ret,
|
||||
},
|
||||
{ /* GetVersion => 4 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetVersion,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_version_ret,
|
||||
},
|
||||
{ /* GetMaxVcpus => 5 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetMaxVcpus,
|
||||
.args_filter = (xdrproc_t) xdr_remote_get_max_vcpus_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_max_vcpus_ret,
|
||||
},
|
||||
{ /* NodeGetInfo => 6 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeGetInfo,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_get_info_ret,
|
||||
},
|
||||
{ /* GetCapabilities => 7 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetCapabilities,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_capabilities_ret,
|
||||
},
|
||||
{ /* DomainAttachDevice => 8 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainAttachDevice,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_attach_device_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainCreate => 9 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainCreate,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_create_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainCreateXml => 10 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainCreateXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_create_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_create_xml_ret,
|
||||
},
|
||||
{ /* DomainDefineXml => 11 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainDefineXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_define_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_define_xml_ret,
|
||||
},
|
||||
{ /* DomainDestroy => 12 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainDestroy,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_destroy_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainDetachDevice => 13 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainDetachDevice,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_detach_device_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainDumpXml => 14 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainDumpXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_dump_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_dump_xml_ret,
|
||||
},
|
||||
{ /* DomainGetAutostart => 15 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetAutostart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_autostart_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_autostart_ret,
|
||||
},
|
||||
{ /* DomainGetInfo => 16 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetInfo,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_info_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_info_ret,
|
||||
},
|
||||
{ /* DomainGetMaxMemory => 17 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetMaxMemory,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_max_memory_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_max_memory_ret,
|
||||
},
|
||||
{ /* DomainGetMaxVcpus => 18 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetMaxVcpus,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_max_vcpus_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_max_vcpus_ret,
|
||||
},
|
||||
{ /* DomainGetOsType => 19 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetOsType,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_os_type_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_os_type_ret,
|
||||
},
|
||||
{ /* DomainGetVcpus => 20 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetVcpus,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_ret,
|
||||
},
|
||||
{ /* ListDefinedDomains => 21 */
|
||||
.fn = (dispatch_fn) remoteDispatchListDefinedDomains,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_defined_domains_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_defined_domains_ret,
|
||||
},
|
||||
{ /* DomainLookupById => 22 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainLookupById,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_lookup_by_id_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_lookup_by_id_ret,
|
||||
},
|
||||
{ /* DomainLookupByName => 23 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainLookupByName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_lookup_by_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_lookup_by_name_ret,
|
||||
},
|
||||
{ /* DomainLookupByUuid => 24 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainLookupByUuid,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_lookup_by_uuid_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_lookup_by_uuid_ret,
|
||||
},
|
||||
{ /* NumOfDefinedDomains => 25 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfDefinedDomains,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_defined_domains_ret,
|
||||
},
|
||||
{ /* DomainPinVcpu => 26 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainPinVcpu,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_pin_vcpu_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainReboot => 27 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainReboot,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_reboot_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainResume => 28 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainResume,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_resume_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainSetAutostart => 29 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSetAutostart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_set_autostart_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainSetMaxMemory => 30 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSetMaxMemory,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_set_max_memory_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainSetMemory => 31 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSetMemory,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_set_memory_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainSetVcpus => 32 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSetVcpus,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_set_vcpus_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainShutdown => 33 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainShutdown,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_shutdown_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainSuspend => 34 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSuspend,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_suspend_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainUndefine => 35 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainUndefine,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_undefine_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* ListDefinedNetworks => 36 */
|
||||
.fn = (dispatch_fn) remoteDispatchListDefinedNetworks,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_defined_networks_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_defined_networks_ret,
|
||||
},
|
||||
{ /* ListDomains => 37 */
|
||||
.fn = (dispatch_fn) remoteDispatchListDomains,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_domains_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_domains_ret,
|
||||
},
|
||||
{ /* ListNetworks => 38 */
|
||||
.fn = (dispatch_fn) remoteDispatchListNetworks,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_networks_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_networks_ret,
|
||||
},
|
||||
{ /* NetworkCreate => 39 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkCreate,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_create_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* NetworkCreateXml => 40 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkCreateXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_create_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_create_xml_ret,
|
||||
},
|
||||
{ /* NetworkDefineXml => 41 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkDefineXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_define_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_define_xml_ret,
|
||||
},
|
||||
{ /* NetworkDestroy => 42 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkDestroy,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_destroy_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* NetworkDumpXml => 43 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkDumpXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_dump_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_dump_xml_ret,
|
||||
},
|
||||
{ /* NetworkGetAutostart => 44 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkGetAutostart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_get_autostart_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_get_autostart_ret,
|
||||
},
|
||||
{ /* NetworkGetBridgeName => 45 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkGetBridgeName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_get_bridge_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_get_bridge_name_ret,
|
||||
},
|
||||
{ /* NetworkLookupByName => 46 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkLookupByName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_lookup_by_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_lookup_by_name_ret,
|
||||
},
|
||||
{ /* NetworkLookupByUuid => 47 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkLookupByUuid,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_lookup_by_uuid_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_lookup_by_uuid_ret,
|
||||
},
|
||||
{ /* NetworkSetAutostart => 48 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkSetAutostart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_set_autostart_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* NetworkUndefine => 49 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkUndefine,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_undefine_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* NumOfDefinedNetworks => 50 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfDefinedNetworks,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_defined_networks_ret,
|
||||
},
|
||||
{ /* NumOfDomains => 51 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfDomains,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_domains_ret,
|
||||
},
|
||||
{ /* NumOfNetworks => 52 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfNetworks,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_networks_ret,
|
||||
},
|
||||
{ /* DomainCoreDump => 53 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainCoreDump,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_core_dump_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainRestore => 54 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainRestore,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_restore_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainSave => 55 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSave,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_save_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainGetSchedulerType => 56 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetSchedulerType,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_type_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_type_ret,
|
||||
},
|
||||
{ /* DomainGetSchedulerParameters => 57 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetSchedulerParameters,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_scheduler_parameters_ret,
|
||||
},
|
||||
{ /* DomainSetSchedulerParameters => 58 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainSetSchedulerParameters,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_set_scheduler_parameters_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* GetHostname => 59 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetHostname,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_hostname_ret,
|
||||
},
|
||||
{ /* SupportsFeature => 60 */
|
||||
.fn = (dispatch_fn) remoteDispatchSupportsFeature,
|
||||
.args_filter = (xdrproc_t) xdr_remote_supports_feature_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_supports_feature_ret,
|
||||
},
|
||||
{ /* DomainMigratePrepare => 61 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMigratePrepare,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare_ret,
|
||||
},
|
||||
{ /* DomainMigratePerform => 62 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMigratePerform,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_migrate_perform_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainMigrateFinish => 63 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMigrateFinish,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_migrate_finish_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_migrate_finish_ret,
|
||||
},
|
||||
{ /* DomainBlockStats => 64 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainBlockStats,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_block_stats_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_block_stats_ret,
|
||||
},
|
||||
{ /* DomainInterfaceStats => 65 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainInterfaceStats,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_interface_stats_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_interface_stats_ret,
|
||||
},
|
||||
{ /* AuthList => 66 */
|
||||
.fn = (dispatch_fn) remoteDispatchAuthList,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_auth_list_ret,
|
||||
},
|
||||
{ /* AuthSaslInit => 67 */
|
||||
.fn = (dispatch_fn) remoteDispatchAuthSaslInit,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_auth_sasl_init_ret,
|
||||
},
|
||||
{ /* AuthSaslStart => 68 */
|
||||
.fn = (dispatch_fn) remoteDispatchAuthSaslStart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_auth_sasl_start_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_auth_sasl_start_ret,
|
||||
},
|
||||
{ /* AuthSaslStep => 69 */
|
||||
.fn = (dispatch_fn) remoteDispatchAuthSaslStep,
|
||||
.args_filter = (xdrproc_t) xdr_remote_auth_sasl_step_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_auth_sasl_step_ret,
|
||||
},
|
||||
{ /* AuthPolkit => 70 */
|
||||
.fn = (dispatch_fn) remoteDispatchAuthPolkit,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_auth_polkit_ret,
|
||||
},
|
||||
{ /* NumOfStoragePools => 71 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfStoragePools,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_storage_pools_ret,
|
||||
},
|
||||
{ /* ListStoragePools => 72 */
|
||||
.fn = (dispatch_fn) remoteDispatchListStoragePools,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_storage_pools_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_storage_pools_ret,
|
||||
},
|
||||
{ /* NumOfDefinedStoragePools => 73 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfDefinedStoragePools,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_defined_storage_pools_ret,
|
||||
},
|
||||
{ /* ListDefinedStoragePools => 74 */
|
||||
.fn = (dispatch_fn) remoteDispatchListDefinedStoragePools,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_defined_storage_pools_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_defined_storage_pools_ret,
|
||||
},
|
||||
{ /* FindStoragePoolSources => 75 */
|
||||
.fn = (dispatch_fn) remoteDispatchFindStoragePoolSources,
|
||||
.args_filter = (xdrproc_t) xdr_remote_find_storage_pool_sources_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_find_storage_pool_sources_ret,
|
||||
},
|
||||
{ /* StoragePoolCreateXml => 76 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolCreateXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_create_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_create_xml_ret,
|
||||
},
|
||||
{ /* StoragePoolDefineXml => 77 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolDefineXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_define_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_define_xml_ret,
|
||||
},
|
||||
{ /* StoragePoolCreate => 78 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolCreate,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_create_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolBuild => 79 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolBuild,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_build_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolDestroy => 80 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolDestroy,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_destroy_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolDelete => 81 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolDelete,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_delete_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolUndefine => 82 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolUndefine,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_undefine_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolRefresh => 83 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolRefresh,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_refresh_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolLookupByName => 84 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolLookupByName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_lookup_by_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_lookup_by_name_ret,
|
||||
},
|
||||
{ /* StoragePoolLookupByUuid => 85 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolLookupByUuid,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_lookup_by_uuid_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_lookup_by_uuid_ret,
|
||||
},
|
||||
{ /* StoragePoolLookupByVolume => 86 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolLookupByVolume,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_lookup_by_volume_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_lookup_by_volume_ret,
|
||||
},
|
||||
{ /* StoragePoolGetInfo => 87 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolGetInfo,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_get_info_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_get_info_ret,
|
||||
},
|
||||
{ /* StoragePoolDumpXml => 88 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolDumpXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_dump_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_dump_xml_ret,
|
||||
},
|
||||
{ /* StoragePoolGetAutostart => 89 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolGetAutostart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_get_autostart_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_get_autostart_ret,
|
||||
},
|
||||
{ /* StoragePoolSetAutostart => 90 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolSetAutostart,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_set_autostart_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StoragePoolNumOfVolumes => 91 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolNumOfVolumes,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_num_of_volumes_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_num_of_volumes_ret,
|
||||
},
|
||||
{ /* StoragePoolListVolumes => 92 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolListVolumes,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_list_volumes_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_list_volumes_ret,
|
||||
},
|
||||
{ /* StorageVolCreateXml => 93 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolCreateXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_create_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_create_xml_ret,
|
||||
},
|
||||
{ /* StorageVolDelete => 94 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolDelete,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_delete_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StorageVolLookupByName => 95 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolLookupByName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_lookup_by_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_lookup_by_name_ret,
|
||||
},
|
||||
{ /* StorageVolLookupByKey => 96 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolLookupByKey,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_lookup_by_key_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_lookup_by_key_ret,
|
||||
},
|
||||
{ /* StorageVolLookupByPath => 97 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolLookupByPath,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_lookup_by_path_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_lookup_by_path_ret,
|
||||
},
|
||||
{ /* StorageVolGetInfo => 98 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolGetInfo,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_get_info_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_get_info_ret,
|
||||
},
|
||||
{ /* StorageVolDumpXml => 99 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolDumpXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_dump_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_dump_xml_ret,
|
||||
},
|
||||
{ /* StorageVolGetPath => 100 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolGetPath,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_get_path_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_get_path_ret,
|
||||
},
|
||||
{ /* NodeGetCellsFreeMemory => 101 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeGetCellsFreeMemory,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_get_cells_free_memory_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_get_cells_free_memory_ret,
|
||||
},
|
||||
{ /* NodeGetFreeMemory => 102 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeGetFreeMemory,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_get_free_memory_ret,
|
||||
},
|
||||
{ /* DomainBlockPeek => 103 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainBlockPeek,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_block_peek_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_block_peek_ret,
|
||||
},
|
||||
{ /* DomainMemoryPeek => 104 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMemoryPeek,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_memory_peek_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_memory_peek_ret,
|
||||
},
|
||||
{ /* DomainEventsRegister => 105 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainEventsRegister,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_events_register_ret,
|
||||
},
|
||||
{ /* DomainEventsDeregister => 106 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainEventsDeregister,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_events_deregister_ret,
|
||||
},
|
||||
{ /* Async event DomainEvent => 107 */
|
||||
.fn = NULL,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainMigratePrepare2 => 108 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMigratePrepare2,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare2_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare2_ret,
|
||||
},
|
||||
{ /* DomainMigrateFinish2 => 109 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMigrateFinish2,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_migrate_finish2_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_migrate_finish2_ret,
|
||||
},
|
||||
{ /* GetUri => 110 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetUri,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_uri_ret,
|
||||
},
|
||||
{ /* NodeNumOfDevices => 111 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeNumOfDevices,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_num_of_devices_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_num_of_devices_ret,
|
||||
},
|
||||
{ /* NodeListDevices => 112 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeListDevices,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_list_devices_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_list_devices_ret,
|
||||
},
|
||||
{ /* NodeDeviceLookupByName => 113 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceLookupByName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_lookup_by_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_device_lookup_by_name_ret,
|
||||
},
|
||||
{ /* NodeDeviceDumpXml => 114 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceDumpXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_dump_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_device_dump_xml_ret,
|
||||
},
|
||||
{ /* NodeDeviceGetParent => 115 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceGetParent,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_get_parent_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_device_get_parent_ret,
|
||||
},
|
||||
{ /* NodeDeviceNumOfCaps => 116 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceNumOfCaps,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_num_of_caps_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_device_num_of_caps_ret,
|
||||
},
|
||||
{ /* NodeDeviceListCaps => 117 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceListCaps,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_list_caps_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_device_list_caps_ret,
|
||||
},
|
||||
{ /* NodeDeviceDettach => 118 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceDettach,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_dettach_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* NodeDeviceReAttach => 119 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceReAttach,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_re_attach_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* NodeDeviceReset => 120 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceReset,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_reset_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainGetSecurityLabel => 121 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainGetSecurityLabel,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_get_security_label_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_get_security_label_ret,
|
||||
},
|
||||
{ /* NodeGetSecurityModel => 122 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret,
|
||||
},
|
||||
{ /* NodeDeviceCreateXml => 123 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceCreateXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_create_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_node_device_create_xml_ret,
|
||||
},
|
||||
{ /* NodeDeviceDestroy => 124 */
|
||||
.fn = (dispatch_fn) remoteDispatchNodeDeviceDestroy,
|
||||
.args_filter = (xdrproc_t) xdr_remote_node_device_destroy_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* StorageVolCreateXmlFrom => 125 */
|
||||
.fn = (dispatch_fn) remoteDispatchStorageVolCreateXmlFrom,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_vol_create_xml_from_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_vol_create_xml_from_ret,
|
||||
},
|
||||
{ /* NumOfInterfaces => 126 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfInterfaces,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_interfaces_ret,
|
||||
},
|
||||
{ /* ListInterfaces => 127 */
|
||||
.fn = (dispatch_fn) remoteDispatchListInterfaces,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_interfaces_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_interfaces_ret,
|
||||
},
|
||||
{ /* InterfaceLookupByName => 128 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceLookupByName,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_lookup_by_name_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_interface_lookup_by_name_ret,
|
||||
},
|
||||
{ /* InterfaceLookupByMacString => 129 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceLookupByMacString,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_lookup_by_mac_string_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_interface_lookup_by_mac_string_ret,
|
||||
},
|
||||
{ /* InterfaceGetXmlDesc => 130 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceGetXmlDesc,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_get_xml_desc_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_interface_get_xml_desc_ret,
|
||||
},
|
||||
{ /* InterfaceDefineXml => 131 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceDefineXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_define_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_interface_define_xml_ret,
|
||||
},
|
||||
{ /* InterfaceUndefine => 132 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceUndefine,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_undefine_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* InterfaceCreate => 133 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceCreate,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_create_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* InterfaceDestroy => 134 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceDestroy,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_destroy_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* DomainXmlFromNative => 135 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainXmlFromNative,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_xml_from_native_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_xml_from_native_ret,
|
||||
},
|
||||
{ /* DomainXmlToNative => 136 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainXmlToNative,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_xml_to_native_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_xml_to_native_ret,
|
||||
},
|
||||
{ /* NumOfDefinedInterfaces => 137 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfDefinedInterfaces,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_defined_interfaces_ret,
|
||||
},
|
||||
{ /* ListDefinedInterfaces => 138 */
|
||||
.fn = (dispatch_fn) remoteDispatchListDefinedInterfaces,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_defined_interfaces_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_defined_interfaces_ret,
|
||||
},
|
||||
{ /* NumOfSecrets => 139 */
|
||||
.fn = (dispatch_fn) remoteDispatchNumOfSecrets,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_num_of_secrets_ret,
|
||||
},
|
||||
{ /* ListSecrets => 140 */
|
||||
.fn = (dispatch_fn) remoteDispatchListSecrets,
|
||||
.args_filter = (xdrproc_t) xdr_remote_list_secrets_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_list_secrets_ret,
|
||||
},
|
||||
{ /* SecretLookupByUuid => 141 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretLookupByUuid,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_lookup_by_uuid_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_secret_lookup_by_uuid_ret,
|
||||
},
|
||||
{ /* SecretDefineXml => 142 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretDefineXml,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_define_xml_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_secret_define_xml_ret,
|
||||
},
|
||||
{ /* SecretGetXmlDesc => 143 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretGetXmlDesc,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_get_xml_desc_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_secret_get_xml_desc_ret,
|
||||
},
|
||||
{ /* SecretSetValue => 144 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretSetValue,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_set_value_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* SecretGetValue => 145 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretGetValue,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_get_value_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_secret_get_value_ret,
|
||||
},
|
||||
{ /* SecretUndefine => 146 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretUndefine,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_undefine_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* SecretLookupByUsage => 147 */
|
||||
.fn = (dispatch_fn) remoteDispatchSecretLookupByUsage,
|
||||
.args_filter = (xdrproc_t) xdr_remote_secret_lookup_by_usage_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_secret_lookup_by_usage_ret,
|
||||
},
|
||||
{ /* DomainMigratePrepareTunnel => 148 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMigratePrepareTunnel,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* IsSecure => 149 */
|
||||
.fn = (dispatch_fn) remoteDispatchIsSecure,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_is_secure_ret,
|
||||
},
|
||||
{ /* DomainIsActive => 150 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainIsActive,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_is_active_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_is_active_ret,
|
||||
},
|
||||
{ /* DomainIsPersistent => 151 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainIsPersistent,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_is_persistent_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_is_persistent_ret,
|
||||
},
|
||||
{ /* NetworkIsActive => 152 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkIsActive,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_is_active_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_is_active_ret,
|
||||
},
|
||||
{ /* NetworkIsPersistent => 153 */
|
||||
.fn = (dispatch_fn) remoteDispatchNetworkIsPersistent,
|
||||
.args_filter = (xdrproc_t) xdr_remote_network_is_persistent_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_network_is_persistent_ret,
|
||||
},
|
||||
{ /* StoragePoolIsActive => 154 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolIsActive,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_is_active_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_is_active_ret,
|
||||
},
|
||||
{ /* StoragePoolIsPersistent => 155 */
|
||||
.fn = (dispatch_fn) remoteDispatchStoragePoolIsPersistent,
|
||||
.args_filter = (xdrproc_t) xdr_remote_storage_pool_is_persistent_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_storage_pool_is_persistent_ret,
|
||||
},
|
||||
{ /* InterfaceIsActive => 156 */
|
||||
.fn = (dispatch_fn) remoteDispatchInterfaceIsActive,
|
||||
.args_filter = (xdrproc_t) xdr_remote_interface_is_active_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_interface_is_active_ret,
|
||||
},
|
||||
{ /* GetLibVersion => 157 */
|
||||
.fn = (dispatch_fn) remoteDispatchGetLibVersion,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_get_lib_version_ret,
|
||||
},
|
||||
{ /* CpuCompare => 158 */
|
||||
.fn = (dispatch_fn) remoteDispatchCpuCompare,
|
||||
.args_filter = (xdrproc_t) xdr_remote_cpu_compare_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_cpu_compare_ret,
|
||||
},
|
||||
{ /* DomainMemoryStats => 159 */
|
||||
.fn = (dispatch_fn) remoteDispatchDomainMemoryStats,
|
||||
.args_filter = (xdrproc_t) xdr_remote_domain_memory_stats_args,
|
||||
.ret_filter = (xdrproc_t) xdr_remote_domain_memory_stats_ret,
|
||||
},
|
@@ -1,179 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# This script parses remote_protocol.x and produces lots of boilerplate
|
||||
# code for both ends of the remote connection.
|
||||
#
|
||||
# By Richard Jones <rjones@redhat.com>
|
||||
|
||||
use strict;
|
||||
|
||||
use Getopt::Std;
|
||||
|
||||
# Command line options.
|
||||
our ($opt_p, $opt_t, $opt_a, $opt_r, $opt_d);
|
||||
getopts ('ptard');
|
||||
|
||||
# Convert name_of_call to NameOfCall.
|
||||
sub name_to_ProcName {
|
||||
my $name = shift;
|
||||
my @elems = split /_/, $name;
|
||||
@elems = map ucfirst, @elems;
|
||||
join "", @elems
|
||||
}
|
||||
|
||||
# Read the input file (usually remote_protocol.x) and form an
|
||||
# opinion about the name, args and return type of each RPC.
|
||||
my ($name, $ProcName, $id, %calls, @calls);
|
||||
|
||||
# REMOTE_PROC_CLOSE has no args or ret.
|
||||
$calls{close} = {
|
||||
name => "close",
|
||||
ProcName => "Close",
|
||||
UC_NAME => "CLOSE",
|
||||
args => "void",
|
||||
ret => "void",
|
||||
};
|
||||
|
||||
while (<>) {
|
||||
if (/^struct remote_(.*)_args/) {
|
||||
$name = $1;
|
||||
$ProcName = name_to_ProcName ($name);
|
||||
|
||||
die "duplicate definition of remote_${name}_args"
|
||||
if exists $calls{$name};
|
||||
|
||||
$calls{$name} = {
|
||||
name => $name,
|
||||
ProcName => $ProcName,
|
||||
UC_NAME => uc $name,
|
||||
args => "remote_${name}_args",
|
||||
ret => "void",
|
||||
};
|
||||
|
||||
} elsif (/^struct remote_(.*)_ret/) {
|
||||
$name = $1;
|
||||
$ProcName = name_to_ProcName ($name);
|
||||
|
||||
if (exists $calls{$name}) {
|
||||
$calls{$name}->{ret} = "remote_${name}_ret";
|
||||
} else {
|
||||
$calls{$name} = {
|
||||
name => $name,
|
||||
ProcName => $ProcName,
|
||||
UC_NAME => uc $name,
|
||||
args => "void",
|
||||
ret => "remote_${name}_ret"
|
||||
}
|
||||
}
|
||||
} elsif (/^struct remote_(.*)_msg/) {
|
||||
$name = $1;
|
||||
$ProcName = name_to_ProcName ($name);
|
||||
|
||||
$calls{$name} = {
|
||||
name => $name,
|
||||
ProcName => $ProcName,
|
||||
UC_NAME => uc $name,
|
||||
msg => "remote_${name}_msg"
|
||||
}
|
||||
} elsif (/^\s*REMOTE_PROC_(.*?)\s+=\s+(\d+),?$/) {
|
||||
$name = lc $1;
|
||||
$id = $2;
|
||||
$ProcName = name_to_ProcName ($name);
|
||||
|
||||
$calls[$id] = $calls{$name};
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Output
|
||||
|
||||
print <<__EOF__;
|
||||
/* Automatically generated by remote_generate_stubs.pl.
|
||||
* Do not edit this file. Any changes you make will be lost.
|
||||
*/
|
||||
|
||||
__EOF__
|
||||
|
||||
# Debugging.
|
||||
if ($opt_d) {
|
||||
my @keys = sort (keys %calls);
|
||||
foreach (@keys) {
|
||||
print "$_:\n";
|
||||
print " name $calls{$_}->{name} ($calls{$_}->{ProcName})\n";
|
||||
print " $calls{$_}->{args} -> $calls{$_}->{ret}\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Prototypes for dispatch functions ("remote_dispatch_prototypes.h").
|
||||
elsif ($opt_p) {
|
||||
my @keys = sort (keys %calls);
|
||||
foreach (@keys) {
|
||||
# Skip things which are REMOTE_MESSAGE
|
||||
next if $calls{$_}->{msg};
|
||||
|
||||
print "static int remoteDispatch$calls{$_}->{ProcName}(\n";
|
||||
print " struct qemud_server *server,\n";
|
||||
print " struct qemud_client *client,\n";
|
||||
print " virConnectPtr conn,\n";
|
||||
print " remote_message_header *hdr,\n";
|
||||
print " remote_error *err,\n";
|
||||
print " $calls{$_}->{args} *args,\n";
|
||||
print " $calls{$_}->{ret} *ret);\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Union of all arg types
|
||||
# ("remote_dispatch_args.h").
|
||||
elsif ($opt_a) {
|
||||
for ($id = 0 ; $id <= $#calls ; $id++) {
|
||||
if (defined $calls[$id] &&
|
||||
!$calls[$id]->{msg} &&
|
||||
$calls[$id]->{args} ne "void") {
|
||||
print " $calls[$id]->{args} val_$calls[$id]->{args};\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Union of all arg types
|
||||
# ("remote_dispatch_ret.h").
|
||||
elsif ($opt_r) {
|
||||
for ($id = 0 ; $id <= $#calls ; $id++) {
|
||||
if (defined $calls[$id] &&
|
||||
!$calls[$id]->{msg} &&
|
||||
$calls[$id]->{ret} ne "void") {
|
||||
print " $calls[$id]->{ret} val_$calls[$id]->{ret};\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Inside the switch statement, prepare the 'fn', 'args_filter', etc
|
||||
# ("remote_dispatch_table.h").
|
||||
elsif ($opt_t) {
|
||||
for ($id = 0 ; $id <= $#calls ; $id++) {
|
||||
if (defined $calls[$id] && !$calls[$id]->{msg}) {
|
||||
print "{ /* $calls[$id]->{ProcName} => $id */\n";
|
||||
print " .fn = (dispatch_fn) remoteDispatch$calls[$id]->{ProcName},\n";
|
||||
if ($calls[$id]->{args} ne "void") {
|
||||
print " .args_filter = (xdrproc_t) xdr_$calls[$id]->{args},\n";
|
||||
} else {
|
||||
print " .args_filter = (xdrproc_t) xdr_void,\n";
|
||||
}
|
||||
if ($calls[$id]->{ret} ne "void") {
|
||||
print " .ret_filter = (xdrproc_t) xdr_$calls[$id]->{ret},\n";
|
||||
} else {
|
||||
print " .ret_filter = (xdrproc_t) xdr_void,\n";
|
||||
}
|
||||
print "},\n";
|
||||
} else {
|
||||
if ($calls[$id]->{msg}) {
|
||||
print "{ /* Async event $calls[$id]->{ProcName} => $id */\n";
|
||||
} else {
|
||||
print "{ /* (unused) => $id */\n";
|
||||
}
|
||||
print " .fn = NULL,\n";
|
||||
print " .args_filter = (xdrproc_t) xdr_void,\n";
|
||||
print " .ret_filter = (xdrproc_t) xdr_void,\n";
|
||||
print "},\n";
|
||||
}
|
||||
}
|
||||
}
|
607
daemon/stream.c
607
daemon/stream.c
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
* stream.c: APIs for managing client streams
|
||||
*
|
||||
* Copyright (C) 2009 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "stream.h"
|
||||
#include "memory.h"
|
||||
#include "dispatch.h"
|
||||
#include "logging.h"
|
||||
|
||||
static int
|
||||
remoteStreamHandleWrite(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream);
|
||||
static int
|
||||
remoteStreamHandleRead(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream);
|
||||
static int
|
||||
remoteStreamHandleFinish(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
struct qemud_client_message *msg);
|
||||
static int
|
||||
remoteStreamHandleAbort(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
struct qemud_client_message *msg);
|
||||
|
||||
|
||||
|
||||
static void
|
||||
remoteStreamUpdateEvents(struct qemud_client_stream *stream)
|
||||
{
|
||||
int newEvents = 0;
|
||||
if (stream->rx)
|
||||
newEvents |= VIR_STREAM_EVENT_WRITABLE;
|
||||
if (stream->tx && !stream->recvEOF)
|
||||
newEvents |= VIR_STREAM_EVENT_READABLE;
|
||||
|
||||
virStreamEventUpdateCallback(stream->st, newEvents);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback that gets invoked when a stream becomes writable/readable
|
||||
*/
|
||||
static void
|
||||
remoteStreamEvent(virStreamPtr st, int events, void *opaque)
|
||||
{
|
||||
struct qemud_client *client = opaque;
|
||||
struct qemud_client_stream *stream;
|
||||
|
||||
/* XXX sub-optimal - we really should be taking the server lock
|
||||
* first, but we have no handle to the server object
|
||||
* We're lucky to get away with it for now, due to this callback
|
||||
* executing in the main thread, but this should really be fixed
|
||||
*/
|
||||
virMutexLock(&client->lock);
|
||||
|
||||
stream = remoteFindClientStream(client, st);
|
||||
|
||||
if (!stream) {
|
||||
VIR_WARN("event for client=%p stream st=%p, but missing stream state", client, st);
|
||||
virStreamEventRemoveCallback(st);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DEBUG("st=%p events=%d", st, events);
|
||||
|
||||
if (events & VIR_STREAM_EVENT_WRITABLE) {
|
||||
if (remoteStreamHandleWrite(client, stream) < 0) {
|
||||
remoteRemoveClientStream(client, stream);
|
||||
qemudDispatchClientFailure(client);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->recvEOF &&
|
||||
(events & (VIR_STREAM_EVENT_READABLE | VIR_STREAM_EVENT_HANGUP))) {
|
||||
events = events & ~(VIR_STREAM_EVENT_READABLE | VIR_STREAM_EVENT_HANGUP);
|
||||
if (remoteStreamHandleRead(client, stream) < 0) {
|
||||
remoteRemoveClientStream(client, stream);
|
||||
qemudDispatchClientFailure(client);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->closed &&
|
||||
(events & (VIR_STREAM_EVENT_ERROR | VIR_STREAM_EVENT_HANGUP))) {
|
||||
int ret;
|
||||
remote_error rerr;
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
stream->closed = 1;
|
||||
virStreamAbort(stream->st);
|
||||
if (events & VIR_STREAM_EVENT_HANGUP)
|
||||
remoteDispatchFormatError(&rerr, "%s", _("stream had unexpected termination"));
|
||||
else
|
||||
remoteDispatchFormatError(&rerr, "%s", _("stream had I/O failure"));
|
||||
ret = remoteSerializeStreamError(client, &rerr, stream->procedure, stream->serial);
|
||||
remoteRemoveClientStream(client, stream);
|
||||
if (ret < 0)
|
||||
qemudDispatchClientFailure(client);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (stream->closed) {
|
||||
remoteRemoveClientStream(client, stream);
|
||||
} else {
|
||||
remoteStreamUpdateEvents(stream);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
virMutexUnlock(&client->lock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client object
|
||||
*
|
||||
* Invoked by the main loop when filtering incoming messages.
|
||||
*
|
||||
* Returns 1 if the message was processed, 0 if skipped,
|
||||
* -1 on fatal client error
|
||||
*/
|
||||
static int
|
||||
remoteStreamFilter(struct qemud_client *client,
|
||||
struct qemud_client_message *msg, void *opaque)
|
||||
{
|
||||
struct qemud_client_stream *stream = opaque;
|
||||
|
||||
if (msg->hdr.serial == stream->serial &&
|
||||
msg->hdr.proc == stream->procedure &&
|
||||
msg->hdr.type == REMOTE_STREAM) {
|
||||
DEBUG("Incoming rx=%p serial=%d proc=%d status=%d",
|
||||
stream->rx, msg->hdr.proc, msg->hdr.serial, msg->hdr.status);
|
||||
|
||||
/* If there are queued packets, we need to queue all further
|
||||
* messages, since they must be processed strictly in order.
|
||||
* If there are no queued packets, then OK/ERROR messages
|
||||
* should be processed immediately. Data packets are still
|
||||
* queued to only be processed when the stream is marked as
|
||||
* writable.
|
||||
*/
|
||||
if (stream->rx) {
|
||||
qemudClientMessageQueuePush(&stream->rx, msg);
|
||||
remoteStreamUpdateEvents(stream);
|
||||
} else {
|
||||
int ret = 0;
|
||||
switch (msg->hdr.status) {
|
||||
case REMOTE_OK:
|
||||
ret = remoteStreamHandleFinish(client, stream, msg);
|
||||
if (ret == 0)
|
||||
qemudClientMessageRelease(client, msg);
|
||||
break;
|
||||
|
||||
case REMOTE_CONTINUE:
|
||||
qemudClientMessageQueuePush(&stream->rx, msg);
|
||||
remoteStreamUpdateEvents(stream);
|
||||
break;
|
||||
|
||||
case REMOTE_ERROR:
|
||||
default:
|
||||
ret = remoteStreamHandleAbort(client, stream, msg);
|
||||
if (ret == 0)
|
||||
qemudClientMessageRelease(client, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @conn: a connection object to associate the stream with
|
||||
* @hdr: the method call to associate with the stram
|
||||
*
|
||||
* Creates a new stream for this conn
|
||||
*
|
||||
* Returns a new stream object, or NULL upon OOM
|
||||
*/
|
||||
struct qemud_client_stream *
|
||||
remoteCreateClientStream(virConnectPtr conn,
|
||||
remote_message_header *hdr)
|
||||
{
|
||||
struct qemud_client_stream *stream;
|
||||
|
||||
DEBUG("proc=%d serial=%d", hdr->proc, hdr->serial);
|
||||
|
||||
if (VIR_ALLOC(stream) < 0)
|
||||
return NULL;
|
||||
|
||||
stream->procedure = hdr->proc;
|
||||
stream->serial = hdr->serial;
|
||||
|
||||
stream->st = virStreamNew(conn, VIR_STREAM_NONBLOCK);
|
||||
if (!stream->st) {
|
||||
VIR_FREE(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream->filter.query = remoteStreamFilter;
|
||||
stream->filter.opaque = stream;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*
|
||||
* @stream: an unused client stream
|
||||
*
|
||||
* Frees the memory associated with this inactive client
|
||||
* stream
|
||||
*/
|
||||
void remoteFreeClientStream(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream)
|
||||
{
|
||||
struct qemud_client_message *msg;
|
||||
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
DEBUG("proc=%d serial=%d", stream->procedure, stream->serial);
|
||||
|
||||
msg = stream->rx;
|
||||
while (msg) {
|
||||
struct qemud_client_message *tmp = msg->next;
|
||||
qemudClientMessageRelease(client, msg);
|
||||
msg = tmp;
|
||||
}
|
||||
|
||||
virStreamFree(stream->st);
|
||||
VIR_FREE(stream);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client to add the stream to
|
||||
* @stream: a stream to add
|
||||
*/
|
||||
int remoteAddClientStream(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
int transmit)
|
||||
{
|
||||
struct qemud_client_stream *tmp = client->streams;
|
||||
|
||||
DEBUG("client=%p proc=%d serial=%d", client, stream->procedure, stream->serial);
|
||||
|
||||
if (virStreamEventAddCallback(stream->st, 0,
|
||||
remoteStreamEvent, client, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
if (tmp) {
|
||||
while (tmp->next)
|
||||
tmp = tmp->next;
|
||||
tmp->next = stream;
|
||||
} else {
|
||||
client->streams = stream;
|
||||
}
|
||||
|
||||
stream->filter.next = client->filters;
|
||||
client->filters = &stream->filter;
|
||||
|
||||
if (transmit)
|
||||
stream->tx = 1;
|
||||
|
||||
remoteStreamUpdateEvents(stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client object
|
||||
* @procedure: procedure associated with the stream
|
||||
* @serial: serial number associated with the stream
|
||||
*
|
||||
* Finds a existing active stream
|
||||
*
|
||||
* Returns a stream object matching the procedure+serial number, or NULL
|
||||
*/
|
||||
struct qemud_client_stream *
|
||||
remoteFindClientStream(struct qemud_client *client,
|
||||
virStreamPtr st)
|
||||
{
|
||||
struct qemud_client_stream *stream = client->streams;
|
||||
|
||||
while (stream) {
|
||||
if (stream->st == st)
|
||||
return stream;
|
||||
stream = stream->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @client: a locked client object
|
||||
* @stream: an inactive, closed stream object
|
||||
*
|
||||
* Removes a stream from the list of active streams for the client
|
||||
*
|
||||
* Returns 0 if the stream was removd, -1 if it doesn't exist
|
||||
*/
|
||||
int
|
||||
remoteRemoveClientStream(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream)
|
||||
{
|
||||
DEBUG("client=%p proc=%d serial=%d", client, stream->procedure, stream->serial);
|
||||
|
||||
struct qemud_client_stream *curr = client->streams;
|
||||
struct qemud_client_stream *prev = NULL;
|
||||
struct qemud_client_filter *filter = NULL;
|
||||
|
||||
if (client->filters == &stream->filter) {
|
||||
client->filters = client->filters->next;
|
||||
} else {
|
||||
filter = client->filters;
|
||||
while (filter) {
|
||||
if (filter->next == &stream->filter) {
|
||||
filter->next = filter->next->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->closed)
|
||||
virStreamAbort(stream->st);
|
||||
|
||||
while (curr) {
|
||||
if (curr == stream) {
|
||||
if (prev)
|
||||
prev->next = curr->next;
|
||||
else
|
||||
client->streams = curr->next;
|
||||
remoteFreeClientStream(client, stream);
|
||||
return 0;
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* -1 if fatal error occurred
|
||||
* 0 if message was fully processed
|
||||
* 1 if message is still being processed
|
||||
*/
|
||||
static int
|
||||
remoteStreamHandleWriteData(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
struct qemud_client_message *msg)
|
||||
{
|
||||
remote_error rerr;
|
||||
int ret;
|
||||
|
||||
DEBUG("stream=%p proc=%d serial=%d len=%d offset=%d",
|
||||
stream, msg->hdr.proc, msg->hdr.serial, msg->bufferLength, msg->bufferOffset);
|
||||
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
|
||||
ret = virStreamSend(stream->st,
|
||||
msg->buffer + msg->bufferOffset,
|
||||
msg->bufferLength - msg->bufferOffset);
|
||||
|
||||
if (ret > 0) {
|
||||
msg->bufferOffset += ret;
|
||||
|
||||
/* Partial write, so indicate we have more todo later */
|
||||
if (msg->bufferOffset < msg->bufferLength)
|
||||
return 1;
|
||||
} else if (ret == -2) {
|
||||
/* Blocking, so indicate we have more todo later */
|
||||
return 1;
|
||||
} else {
|
||||
VIR_INFO0("Stream send failed");
|
||||
stream->closed = 1;
|
||||
remoteDispatchConnError(&rerr, client->conn);
|
||||
return remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process an finish handshake from the client.
|
||||
*
|
||||
* Returns a REMOTE_OK confirmation if successful, or a REMOTE_ERROR
|
||||
* if there was a stream error
|
||||
*
|
||||
* Returns 0 if successfully sent RPC reply, -1 upon fatal error
|
||||
*/
|
||||
static int
|
||||
remoteStreamHandleFinish(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
struct qemud_client_message *msg)
|
||||
{
|
||||
remote_error rerr;
|
||||
int ret;
|
||||
|
||||
DEBUG("stream=%p proc=%d serial=%d",
|
||||
stream, msg->hdr.proc, msg->hdr.serial);
|
||||
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
|
||||
stream->closed = 1;
|
||||
ret = virStreamFinish(stream->st);
|
||||
|
||||
if (ret < 0) {
|
||||
remoteDispatchConnError(&rerr, client->conn);
|
||||
return remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
||||
} else {
|
||||
/* Send zero-length confirm */
|
||||
if (remoteSendStreamData(client, stream, NULL, 0) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process an abort request from the client.
|
||||
*
|
||||
* Returns 0 if successfully aborted, -1 upon error
|
||||
*/
|
||||
static int
|
||||
remoteStreamHandleAbort(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
struct qemud_client_message *msg)
|
||||
{
|
||||
remote_error rerr;
|
||||
|
||||
DEBUG("stream=%p proc=%d serial=%d",
|
||||
stream, msg->hdr.proc, msg->hdr.serial);
|
||||
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
|
||||
stream->closed = 1;
|
||||
virStreamAbort(stream->st);
|
||||
|
||||
if (msg->hdr.status == REMOTE_ERROR)
|
||||
remoteDispatchFormatError(&rerr, "%s", _("stream aborted at client request"));
|
||||
else {
|
||||
VIR_WARN("unexpected stream status %d", msg->hdr.status);
|
||||
remoteDispatchFormatError(&rerr, _("stream aborted with unexpected status %d"),
|
||||
msg->hdr.status);
|
||||
}
|
||||
|
||||
return remoteSerializeReplyError(client, &rerr, &msg->hdr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Called when the stream is signalled has being able to accept
|
||||
* data writes. Will process all pending incoming messages
|
||||
* until they're all gone, or I/O blocks
|
||||
*
|
||||
* Returns 0 on success, or -1 upon fatal error
|
||||
*/
|
||||
static int
|
||||
remoteStreamHandleWrite(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream)
|
||||
{
|
||||
struct qemud_client_message *msg, *tmp;
|
||||
|
||||
DEBUG("stream=%p", stream);
|
||||
|
||||
msg = stream->rx;
|
||||
while (msg && !stream->closed) {
|
||||
int ret;
|
||||
switch (msg->hdr.status) {
|
||||
case REMOTE_OK:
|
||||
ret = remoteStreamHandleFinish(client, stream, msg);
|
||||
break;
|
||||
|
||||
case REMOTE_CONTINUE:
|
||||
ret = remoteStreamHandleWriteData(client, stream, msg);
|
||||
break;
|
||||
|
||||
case REMOTE_ERROR:
|
||||
default:
|
||||
ret = remoteStreamHandleAbort(client, stream, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
qemudClientMessageQueueServe(&stream->rx);
|
||||
else if (ret < 0)
|
||||
return -1;
|
||||
else
|
||||
break; /* still processing data */
|
||||
|
||||
tmp = msg->next;
|
||||
qemudClientMessageRelease(client, msg);
|
||||
msg = tmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Invoked when a stream is signalled as having data
|
||||
* available to read. This reads upto one message
|
||||
* worth of data, and then queues that for transmission
|
||||
* to the client.
|
||||
*
|
||||
* Returns 0 if data was queued for TX, or a error RPC
|
||||
* was sent, or -1 on fatal error, indicating client should
|
||||
* be killed
|
||||
*/
|
||||
static int
|
||||
remoteStreamHandleRead(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream)
|
||||
{
|
||||
char *buffer;
|
||||
size_t bufferLen = REMOTE_MESSAGE_PAYLOAD_MAX;
|
||||
int ret;
|
||||
|
||||
DEBUG("stream=%p", stream);
|
||||
|
||||
/* Shouldn't ever be called unless we're marked able to
|
||||
* transmit, but doesn't hurt to check */
|
||||
if (!stream->tx)
|
||||
return 0;
|
||||
|
||||
if (VIR_ALLOC_N(buffer, bufferLen) < 0)
|
||||
return -1;
|
||||
|
||||
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... */
|
||||
ret = 0;
|
||||
} else if (ret < 0) {
|
||||
remote_error rerr;
|
||||
memset(&rerr, 0, sizeof rerr);
|
||||
remoteDispatchConnError(&rerr, NULL);
|
||||
|
||||
ret = remoteSerializeStreamError(client, &rerr, stream->procedure, stream->serial);
|
||||
} else {
|
||||
stream->tx = 0;
|
||||
if (ret == 0)
|
||||
stream->recvEOF = 1;
|
||||
ret = remoteSendStreamData(client, stream, buffer, ret);
|
||||
}
|
||||
|
||||
VIR_FREE(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Invoked when an outgoing data packet message has been fully sent.
|
||||
* This simply re-enables TX of further data.
|
||||
*
|
||||
* The idea is to stop the daemon growing without bound due to
|
||||
* fast stream, but slow client
|
||||
*/
|
||||
void
|
||||
remoteStreamMessageFinished(struct qemud_client *client,
|
||||
struct qemud_client_message *msg)
|
||||
{
|
||||
struct qemud_client_stream *stream = client->streams;
|
||||
|
||||
while (stream) {
|
||||
if (msg->hdr.proc == stream->procedure &&
|
||||
msg->hdr.serial == stream->serial)
|
||||
break;
|
||||
stream = stream->next;
|
||||
}
|
||||
|
||||
DEBUG("Message client=%p stream=%p proc=%d serial=%d", client, stream, msg->hdr.proc, msg->hdr.serial);
|
||||
|
||||
if (stream) {
|
||||
stream->tx = 1;
|
||||
remoteStreamUpdateEvents(stream);
|
||||
}
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* stream.h: APIs for managing client streams
|
||||
*
|
||||
* Copyright (C) 2009 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __LIBVIRTD_STREAM_H__
|
||||
#define __LIBVIRTD_STREAM_H__
|
||||
|
||||
#include "libvirtd.h"
|
||||
|
||||
|
||||
|
||||
struct qemud_client_stream *
|
||||
remoteCreateClientStream(virConnectPtr conn,
|
||||
remote_message_header *hdr);
|
||||
|
||||
void remoteFreeClientStream(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream);
|
||||
|
||||
int remoteAddClientStream(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream,
|
||||
int transmit);
|
||||
|
||||
struct qemud_client_stream *
|
||||
remoteFindClientStream(struct qemud_client *client,
|
||||
virStreamPtr stream);
|
||||
|
||||
int
|
||||
remoteRemoveClientStream(struct qemud_client *client,
|
||||
struct qemud_client_stream *stream);
|
||||
|
||||
void
|
||||
remoteStreamMessageFinished(struct qemud_client *client,
|
||||
struct qemud_client_message *msg);
|
||||
|
||||
#endif /* __LIBVIRTD_STREAM_H__ */
|
@@ -1,545 +0,0 @@
|
||||
module Test_libvirtd =
|
||||
let conf = "# Master libvirt daemon configuration file
|
||||
#
|
||||
# For further information consult http://libvirt.org/format.html
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Network connectivity controls
|
||||
#
|
||||
|
||||
# Flag listening for secure TLS connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# It is necessary to setup a CA and issue server certificates before
|
||||
# using this capability.
|
||||
#
|
||||
# This is enabled by default, uncomment this to disable it
|
||||
listen_tls = 0
|
||||
|
||||
# Listen for unencrypted TCP connections on the public TCP/IP port.
|
||||
# NB, must pass the --listen flag to the libvirtd process for this to
|
||||
# have any effect.
|
||||
#
|
||||
# Using the TCP socket requires SASL authentication by default. Only
|
||||
# SASL mechanisms which support data encryption are allowed. This is
|
||||
# DIGEST_MD5 and GSSAPI (Kerberos5)
|
||||
#
|
||||
# This is disabled by default, uncomment this to enable it.
|
||||
listen_tcp = 1
|
||||
|
||||
|
||||
|
||||
# Override the port for accepting secure TLS connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
tls_port = \"16514\"
|
||||
|
||||
# Override the port for accepting insecure TCP connections
|
||||
# This can be a port number, or service name
|
||||
#
|
||||
tcp_port = \"16509\"
|
||||
|
||||
|
||||
# Override the default configuration which binds to all network
|
||||
# interfaces. This can be a numeric IPv4/6 address, or hostname
|
||||
#
|
||||
listen_addr = \"192.168.0.1\"
|
||||
|
||||
|
||||
# Flag toggling mDNS advertizement of the libvirt service.
|
||||
#
|
||||
# Alternatively can disable for all services on a host by
|
||||
# stopping the Avahi daemon
|
||||
#
|
||||
# This is enabled by default, uncomment this to disable it
|
||||
mdns_adv = 0
|
||||
|
||||
# Override the default mDNS advertizement name. This must be
|
||||
# unique on the immediate broadcast network.
|
||||
#
|
||||
# The default is \"Virtualization Host HOSTNAME\", where HOSTNAME
|
||||
# is subsituted for the short hostname of the machine (without domain)
|
||||
#
|
||||
mdns_name = \"Virtualization Host Joe Demo\"
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# UNIX socket access controls
|
||||
#
|
||||
|
||||
# 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.
|
||||
#
|
||||
# This is restricted to 'root' by default.
|
||||
unix_sock_group = \"libvirt\"
|
||||
|
||||
# Set the UNIX socket permissions for the R/O socket. This is used
|
||||
# for monitoring VM status only
|
||||
#
|
||||
# Default allows any user. If setting group ownership may want to
|
||||
# restrict this to:
|
||||
unix_sock_ro_perms = \"0777\"
|
||||
|
||||
# Set the UNIX socket permissions for the R/W socket. This is used
|
||||
# for full management of VMs
|
||||
#
|
||||
# Default allows only root. If PolicyKit is enabled on the socket,
|
||||
# the default will change to allow everyone (eg, 0777)
|
||||
#
|
||||
# If not using PolicyKit and setting group ownership for access
|
||||
# control then you may want to relax this to:
|
||||
unix_sock_rw_perms = \"0770\"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authentication.
|
||||
#
|
||||
# - none: do not perform auth checks. If you can connect to the
|
||||
# socket you are allowed. This is suitable if there are
|
||||
# restrictions on connecting to the socket (eg, UNIX
|
||||
# socket permissions), or if there is a lower layer in
|
||||
# the network providing auth (eg, TLS/x509 certificates)
|
||||
#
|
||||
# - sasl: use SASL infrastructure. The actual auth scheme is then
|
||||
# controlled from /etc/sasl2/libvirt.conf. For the TCP
|
||||
# socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
|
||||
# For non-TCP or TLS sockets, any scheme is allowed.
|
||||
#
|
||||
# - polkit: use PolicyKit to authenticate. This is only suitable
|
||||
# for use on the UNIX sockets. The default policy will
|
||||
# require a user to supply their own password to gain
|
||||
# full read/write access (aka sudo like), while anyone
|
||||
# is allowed read/only access.
|
||||
#
|
||||
# Set an authentication scheme for UNIX read-only sockets
|
||||
# By default socket permissions allow anyone to connect
|
||||
#
|
||||
# To restrict monitoring of domains you may wish to enable
|
||||
# an authentication mechanism here
|
||||
auth_unix_ro = \"none\"
|
||||
|
||||
# Set an authentication scheme for UNIX read-write sockets
|
||||
# By default socket permissions only allow root. If PolicyKit
|
||||
# support was compiled into libvirt, the default will be to
|
||||
# use 'polkit' auth.
|
||||
#
|
||||
# If the unix_sock_rw_perms are changed you may wish to enable
|
||||
# an authentication mechanism here
|
||||
auth_unix_rw = \"none\"
|
||||
|
||||
# Change the authentication scheme for TCP sockets.
|
||||
#
|
||||
# If you don't enable SASL, then all TCP traffic is cleartext.
|
||||
# Don't do this outside of a dev/test scenario. For real world
|
||||
# use, always enable SASL and use the GSSAPI or DIGEST-MD5
|
||||
# mechanism in /etc/sasl2/libvirt.conf
|
||||
auth_tcp = \"sasl\"
|
||||
|
||||
# Change the authentication scheme for TLS sockets.
|
||||
#
|
||||
# TLS sockets already have encryption provided by the TLS
|
||||
# layer, and limited authentication is done by certificates
|
||||
#
|
||||
# It is possible to make use of any SASL authentication
|
||||
# mechanism as well, by using 'sasl' for this option
|
||||
auth_tls = \"none\"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# TLS x509 certificate configuration
|
||||
#
|
||||
|
||||
|
||||
# Override the default server key file path
|
||||
#
|
||||
key_file = \"/etc/pki/libvirt/private/serverkey.pem\"
|
||||
|
||||
# Override the default server certificate file path
|
||||
#
|
||||
cert_file = \"/etc/pki/libvirt/servercert.pem\"
|
||||
|
||||
# Override the default CA certificate path
|
||||
#
|
||||
ca_file = \"/etc/pki/CA/cacert.pem\"
|
||||
|
||||
# Specify a certificate revocation list.
|
||||
#
|
||||
# Defaults to not using a CRL, uncomment to enable it
|
||||
crl_file = \"/etc/pki/CA/crl.pem\"
|
||||
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Authorization controls
|
||||
#
|
||||
|
||||
|
||||
# Flag to disable verification of client certificates
|
||||
#
|
||||
# Client certificate verification is the primary authentication mechanism.
|
||||
# Any client which does not present a certificate signed by the CA
|
||||
# will be rejected.
|
||||
#
|
||||
# Default is to always verify. Uncommenting this will disable
|
||||
# verification - make sure an IP whitelist is set
|
||||
tls_no_verify_certificate = 1
|
||||
|
||||
|
||||
# A whitelist of allowed x509 Distinguished Names
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# \"C=GB,ST=London,L=London,O=Red Hat,CN=*\"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no DN's are checked
|
||||
tls_allowed_dn_list = [\"DN1\", \"DN2\"]
|
||||
|
||||
|
||||
# A whitelist of allowed SASL usernames. The format for usernames
|
||||
# depends on the SASL authentication mechanism. Kerberos usernames
|
||||
# look like username@REALM
|
||||
#
|
||||
# This list may contain wildcards such as
|
||||
#
|
||||
# \"*@EXAMPLE.COM\"
|
||||
#
|
||||
# See the POSIX fnmatch function for the format of the wildcards.
|
||||
#
|
||||
# NB If this is an empty list, no client can connect, so comment out
|
||||
# entirely rather than using empty list to disable these checks
|
||||
#
|
||||
# By default, no Username's are checked
|
||||
sasl_allowed_username_list = [
|
||||
\"joe@EXAMPLE.COM\",
|
||||
\"fred@EXAMPLE.COM\"
|
||||
]
|
||||
|
||||
|
||||
#################################################################
|
||||
#
|
||||
# Processing controls
|
||||
#
|
||||
|
||||
# The maximum number of concurrent client connections to allow
|
||||
# over all sockets combined.
|
||||
max_clients = 20
|
||||
|
||||
|
||||
# The minimum limit sets the number of workers to start up
|
||||
# initially. If the number of active clients exceeds this,
|
||||
# then more threads are spawned, upto max_workers limit.
|
||||
# Typically you'd want max_workers to equal maximum number
|
||||
# of clients allowed
|
||||
min_workers = 5
|
||||
max_workers = 20
|
||||
|
||||
# Total global limit on concurrent RPC calls. Should be
|
||||
# at least as large as max_workers. Beyond this, RPC requests
|
||||
# will be read into memory and queued. This directly impact
|
||||
# memory usage, currently each request requires 256 KB of
|
||||
# memory. So by default upto 5 MB of memory is used
|
||||
max_requests = 20
|
||||
|
||||
# Limit on concurrent requests from a single client
|
||||
# connection. To avoid one client monopolizing the server
|
||||
# this should be a small fraction of the global max_requests
|
||||
# and max_workers parameter
|
||||
max_client_requests = 5
|
||||
|
||||
# Logging level:
|
||||
log_level = 4
|
||||
|
||||
# Logging outputs:
|
||||
log_outputs=\"4:stderr\"
|
||||
|
||||
# Logging filters:
|
||||
log_filters=\"a\"
|
||||
"
|
||||
|
||||
test Libvirtd.lns get conf =
|
||||
{ "#comment" = "Master libvirt daemon configuration file" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "For further information consult http://libvirt.org/format.html" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Network connectivity controls" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Flag listening for secure TLS connections on the public TCP/IP port." }
|
||||
{ "#comment" = "NB, must pass the --listen flag to the libvirtd process for this to" }
|
||||
{ "#comment" = "have any effect." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "It is necessary to setup a CA and issue server certificates before" }
|
||||
{ "#comment" = "using this capability." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is enabled by default, uncomment this to disable it" }
|
||||
{ "listen_tls" = "0" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Listen for unencrypted TCP connections on the public TCP/IP port." }
|
||||
{ "#comment" = "NB, must pass the --listen flag to the libvirtd process for this to" }
|
||||
{ "#comment" = "have any effect." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Using the TCP socket requires SASL authentication by default. Only" }
|
||||
{ "#comment" = "SASL mechanisms which support data encryption are allowed. This is" }
|
||||
{ "#comment" = "DIGEST_MD5 and GSSAPI (Kerberos5)" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is disabled by default, uncomment this to enable it." }
|
||||
{ "listen_tcp" = "1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the port for accepting secure TLS connections" }
|
||||
{ "#comment" = "This can be a port number, or service name" }
|
||||
{ "#comment" = "" }
|
||||
{ "tls_port" = "16514" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the port for accepting insecure TCP connections" }
|
||||
{ "#comment" = "This can be a port number, or service name" }
|
||||
{ "#comment" = "" }
|
||||
{ "tcp_port" = "16509" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default configuration which binds to all network" }
|
||||
{ "#comment" = "interfaces. This can be a numeric IPv4/6 address, or hostname" }
|
||||
{ "#comment" = "" }
|
||||
{ "listen_addr" = "192.168.0.1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Flag toggling mDNS advertizement of the libvirt service." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Alternatively can disable for all services on a host by" }
|
||||
{ "#comment" = "stopping the Avahi daemon" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is enabled by default, uncomment this to disable it" }
|
||||
{ "mdns_adv" = "0" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default mDNS advertizement name. This must be" }
|
||||
{ "#comment" = "unique on the immediate broadcast network." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "The default is \"Virtualization Host HOSTNAME\", where HOSTNAME" }
|
||||
{ "#comment" = "is subsituted for the short hostname of the machine (without domain)" }
|
||||
{ "#comment" = "" }
|
||||
{ "mdns_name" = "Virtualization Host Joe Demo" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "UNIX socket access controls" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set the UNIX domain socket group ownership. This can be used to" }
|
||||
{ "#comment" = "allow a 'trusted' set of users access to management capabilities" }
|
||||
{ "#comment" = "without becoming root." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This is restricted to 'root' by default." }
|
||||
{ "unix_sock_group" = "libvirt" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set the UNIX socket permissions for the R/O socket. This is used" }
|
||||
{ "#comment" = "for monitoring VM status only" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Default allows any user. If setting group ownership may want to" }
|
||||
{ "#comment" = "restrict this to:" }
|
||||
{ "unix_sock_ro_perms" = "0777" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set the UNIX socket permissions for the R/W socket. This is used" }
|
||||
{ "#comment" = "for full management of VMs" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Default allows only root. If PolicyKit is enabled on the socket," }
|
||||
{ "#comment" = "the default will change to allow everyone (eg, 0777)" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "If not using PolicyKit and setting group ownership for access" }
|
||||
{ "#comment" = "control then you may want to relax this to:" }
|
||||
{ "unix_sock_rw_perms" = "0770" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Authentication." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "- none: do not perform auth checks. If you can connect to the" }
|
||||
{ "#comment" = "socket you are allowed. This is suitable if there are" }
|
||||
{ "#comment" = "restrictions on connecting to the socket (eg, UNIX" }
|
||||
{ "#comment" = "socket permissions), or if there is a lower layer in" }
|
||||
{ "#comment" = "the network providing auth (eg, TLS/x509 certificates)" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "- sasl: use SASL infrastructure. The actual auth scheme is then" }
|
||||
{ "#comment" = "controlled from /etc/sasl2/libvirt.conf. For the TCP" }
|
||||
{ "#comment" = "socket only GSSAPI & DIGEST-MD5 mechanisms will be used." }
|
||||
{ "#comment" = "For non-TCP or TLS sockets, any scheme is allowed." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "- polkit: use PolicyKit to authenticate. This is only suitable" }
|
||||
{ "#comment" = "for use on the UNIX sockets. The default policy will" }
|
||||
{ "#comment" = "require a user to supply their own password to gain" }
|
||||
{ "#comment" = "full read/write access (aka sudo like), while anyone" }
|
||||
{ "#comment" = "is allowed read/only access." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Set an authentication scheme for UNIX read-only sockets" }
|
||||
{ "#comment" = "By default socket permissions allow anyone to connect" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "To restrict monitoring of domains you may wish to enable" }
|
||||
{ "#comment" = "an authentication mechanism here" }
|
||||
{ "auth_unix_ro" = "none" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Set an authentication scheme for UNIX read-write sockets" }
|
||||
{ "#comment" = "By default socket permissions only allow root. If PolicyKit" }
|
||||
{ "#comment" = "support was compiled into libvirt, the default will be to" }
|
||||
{ "#comment" = "use 'polkit' auth." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "If the unix_sock_rw_perms are changed you may wish to enable" }
|
||||
{ "#comment" = "an authentication mechanism here" }
|
||||
{ "auth_unix_rw" = "none" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Change the authentication scheme for TCP sockets." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "If you don't enable SASL, then all TCP traffic is cleartext." }
|
||||
{ "#comment" = "Don't do this outside of a dev/test scenario. For real world" }
|
||||
{ "#comment" = "use, always enable SASL and use the GSSAPI or DIGEST-MD5" }
|
||||
{ "#comment" = "mechanism in /etc/sasl2/libvirt.conf" }
|
||||
{ "auth_tcp" = "sasl" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Change the authentication scheme for TLS sockets." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "TLS sockets already have encryption provided by the TLS" }
|
||||
{ "#comment" = "layer, and limited authentication is done by certificates" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "It is possible to make use of any SASL authentication" }
|
||||
{ "#comment" = "mechanism as well, by using 'sasl' for this option" }
|
||||
{ "auth_tls" = "none" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "TLS x509 certificate configuration" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default server key file path" }
|
||||
{ "#comment" = "" }
|
||||
{ "key_file" = "/etc/pki/libvirt/private/serverkey.pem" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default server certificate file path" }
|
||||
{ "#comment" = "" }
|
||||
{ "cert_file" = "/etc/pki/libvirt/servercert.pem" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Override the default CA certificate path" }
|
||||
{ "#comment" = "" }
|
||||
{ "ca_file" = "/etc/pki/CA/cacert.pem" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Specify a certificate revocation list." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Defaults to not using a CRL, uncomment to enable it" }
|
||||
{ "crl_file" = "/etc/pki/CA/crl.pem" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Authorization controls" }
|
||||
{ "#comment" = "" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Flag to disable verification of client certificates" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Client certificate verification is the primary authentication mechanism." }
|
||||
{ "#comment" = "Any client which does not present a certificate signed by the CA" }
|
||||
{ "#comment" = "will be rejected." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "Default is to always verify. Uncommenting this will disable" }
|
||||
{ "#comment" = "verification - make sure an IP whitelist is set" }
|
||||
{ "tls_no_verify_certificate" = "1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "A whitelist of allowed x509 Distinguished Names" }
|
||||
{ "#comment" = "This list may contain wildcards such as" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "\"C=GB,ST=London,L=London,O=Red Hat,CN=*\"" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "See the POSIX fnmatch function for the format of the wildcards." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "NB If this is an empty list, no client can connect, so comment out" }
|
||||
{ "#comment" = "entirely rather than using empty list to disable these checks" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "By default, no DN's are checked" }
|
||||
{ "tls_allowed_dn_list"
|
||||
{ "1" = "DN1"}
|
||||
{ "2" = "DN2"}
|
||||
}
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "A whitelist of allowed SASL usernames. The format for usernames" }
|
||||
{ "#comment" = "depends on the SASL authentication mechanism. Kerberos usernames" }
|
||||
{ "#comment" = "look like username@REALM" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "This list may contain wildcards such as" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "\"*@EXAMPLE.COM\"" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "See the POSIX fnmatch function for the format of the wildcards." }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "NB If this is an empty list, no client can connect, so comment out" }
|
||||
{ "#comment" = "entirely rather than using empty list to disable these checks" }
|
||||
{ "#comment" = "" }
|
||||
{ "#comment" = "By default, no Username's are checked" }
|
||||
{ "sasl_allowed_username_list"
|
||||
{ "1" = "joe@EXAMPLE.COM" }
|
||||
{ "2" = "fred@EXAMPLE.COM" }
|
||||
}
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "################################################################"}
|
||||
{ "#comment" = ""}
|
||||
{ "#comment" = "Processing controls"}
|
||||
{ "#comment" = ""}
|
||||
{ "#empty" }
|
||||
{ "#comment" = "The maximum number of concurrent client connections to allow"}
|
||||
{ "#comment" = "over all sockets combined."}
|
||||
{ "max_clients" = "20" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "The minimum limit sets the number of workers to start up"}
|
||||
{ "#comment" = "initially. If the number of active clients exceeds this,"}
|
||||
{ "#comment" = "then more threads are spawned, upto max_workers limit."}
|
||||
{ "#comment" = "Typically you'd want max_workers to equal maximum number"}
|
||||
{ "#comment" = "of clients allowed"}
|
||||
{ "min_workers" = "5" }
|
||||
{ "max_workers" = "20" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Total global limit on concurrent RPC calls. Should be" }
|
||||
{ "#comment" = "at least as large as max_workers. Beyond this, RPC requests" }
|
||||
{ "#comment" = "will be read into memory and queued. This directly impact" }
|
||||
{ "#comment" = "memory usage, currently each request requires 256 KB of" }
|
||||
{ "#comment" = "memory. So by default upto 5 MB of memory is used" }
|
||||
{ "max_requests" = "20" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Limit on concurrent requests from a single client" }
|
||||
{ "#comment" = "connection. To avoid one client monopolizing the server" }
|
||||
{ "#comment" = "this should be a small fraction of the global max_requests" }
|
||||
{ "#comment" = "and max_workers parameter" }
|
||||
{ "max_client_requests" = "5" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Logging level:" }
|
||||
{ "log_level" = "4" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Logging outputs:" }
|
||||
{ "log_outputs" = "4:stderr" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "Logging filters:" }
|
||||
{ "log_filters" = "a" }
|
7
docs/.gitignore
vendored
7
docs/.gitignore
vendored
@@ -1,7 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.memdump
|
||||
apibuild.pyc
|
||||
*.html
|
||||
libvirt-api.xml
|
||||
libvirt-refs.xml
|
Binary file not shown.
Before Width: | Height: | Size: 783 B |
@@ -1,49 +0,0 @@
|
||||
#!/bin/awk -f
|
||||
function translate(str) {
|
||||
while (sub(/&/, "#amp;", str) == 1);
|
||||
while (sub(/#amp;/, "\\&", str) == 1); # fun isn't it ?
|
||||
while (sub(/</, "\\<", str) == 1);
|
||||
while (sub(/>/, "\\>", str) == 1);
|
||||
sub(/[0-9][0-9][0-9][0-9][0-9]+/, "<bug number='&'/>", str)
|
||||
return(str)
|
||||
}
|
||||
BEGIN {
|
||||
nb_entry = 0
|
||||
in_entry = 0
|
||||
in_item = 0
|
||||
print "<?xml version='1.0' encoding='ISO-8859-1'?>"
|
||||
print "<log>"
|
||||
}
|
||||
END {
|
||||
if (in_item == 1) printf("%s</item>\n", translate(item))
|
||||
if (in_entry == 1) print " </entry>"
|
||||
print "</log>"
|
||||
}
|
||||
/^[ \t]*$/ { next }
|
||||
/^[A-Za-z0-9]/ {
|
||||
match($0, "\(.*\) \([A-Z]+\) \([0-9][0-9][0-9][0-9]\) \(.*\) <\(.*\)>", loge)
|
||||
if (in_item == 1) printf("%s</item>\n", translate(item))
|
||||
if (in_entry == 1) print " </entry>"
|
||||
nb_entry = nb_entry + 1
|
||||
if (nb_entry > 50) {
|
||||
in_entry = 0
|
||||
in_item = 0
|
||||
exit
|
||||
}
|
||||
in_entry = 1
|
||||
in_item = 0
|
||||
printf(" <entry date='%s' timezone='%s' year='%s'\n who='%s' email='%s'>\n", loge[1], loge[2], loge[3], loge[4], loge[5])
|
||||
}
|
||||
/^[ \t]*\*/ {
|
||||
if (in_item == 1) printf("%s</item>\n", translate(item))
|
||||
in_item = 1
|
||||
printf(" <item>")
|
||||
match($0, "[ \t]*. *\(.*\)", loge)
|
||||
item = loge[1]
|
||||
}
|
||||
/^[ \t]*[a-zA-Z0-9\#]/ {
|
||||
if (in_item == 1) {
|
||||
match($0, "[ \t]*\(.*\)[ \t]*", loge)
|
||||
item = sprintf("%s %s", item, loge[1])
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- this stylesheet builds the ChangeLog.html -->
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<!-- Generate XHTML-1.0 transitional -->
|
||||
<xsl:output method="xml" encoding="UTF-8" indent="yes"
|
||||
doctype-public="-//W3C//DTD XHTML 1.0//EN"
|
||||
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
|
||||
|
||||
<xsl:template match="item">
|
||||
<li><xsl:apply-templates/></li>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="entry">
|
||||
<p>
|
||||
<span class="author"><xsl:value-of select="@who"/> </span>
|
||||
<span class="date"><xsl:value-of select="@date"/> </span>
|
||||
<span class="timezone"><xsl:value-of select="@timezone"/> </span>
|
||||
</p>
|
||||
<ul>
|
||||
<xsl:apply-templates select="item"/>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="log">
|
||||
<html>
|
||||
<body>
|
||||
<h1>Log of recent changes to libvirt</h1>
|
||||
<div id="changelog">
|
||||
<xsl:apply-templates select="entry"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
144
docs/FAQ.html.in
144
docs/FAQ.html.in
@@ -1,144 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1 >FAQ</h1>
|
||||
<p>Table of Contents:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="FAQ.html#License">License(s)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="FAQ.html#Installati">Installation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="FAQ.html#Compilatio">Compilation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="FAQ.html#Developer">Developer corner</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3><a name="License" id="License">License</a>(s)</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<em>Licensing Terms for libvirt</em>
|
||||
<p>libvirt is released under the <a href="http://www.opensource.org/licenses/lgpl-license.html">GNU Lesser
|
||||
General Public License</a>, see the file COPYING.LIB in the distribution
|
||||
for the precise wording. The only library that libvirt depends upon is
|
||||
the Xen store access library which is also licenced under the LGPL.</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>Can I embed libvirt in a proprietary application ?</em>
|
||||
<p>Yes. The LGPL allows you to embed libvirt into a proprietary
|
||||
application. It would be graceful to send-back bug fixes and improvements
|
||||
as patches for possible incorporation in the main development tree. It
|
||||
will decrease your maintenance costs anyway if you do so.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<h3>
|
||||
<a name="Installati" id="Installati">Installation</a>
|
||||
</h3>
|
||||
<ol>
|
||||
<li><em>Where can I get libvirt</em> ?
|
||||
<p>The original distribution comes from <a href="ftp://libvirt.org/libvirt/">ftp://libvirt.org/libvirt/</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>I can't install the libvirt/libvirt-devel RPM packages due to
|
||||
failed dependencies</em>
|
||||
<p>The most generic solution is to re-fetch the latest src.rpm , and
|
||||
rebuild it locally with</p>
|
||||
<p><code>rpm --rebuild libvirt-xxx.src.rpm</code>.</p>
|
||||
<p>If everything goes well it will generate two binary rpm packages (one
|
||||
providing the shared libs and virsh, and the other one, the -devel
|
||||
package, providing includes, static libraries and scripts needed to build
|
||||
applications with libvirt that you can install locally.</p>
|
||||
<p>One can also rebuild the RPMs from a tarball:</p>
|
||||
<p>
|
||||
<code>rpmbuild -ta libdir-xxx.tar.gz</code>
|
||||
</p>
|
||||
<p>Or from a configured tree with:</p>
|
||||
<p>
|
||||
<code>make rpm</code>
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>Failure to use the API for non-root users</em>
|
||||
<p>Large parts of the API may only be accessible with root privileges,
|
||||
however the read only access to the xenstore data doesnot have to be
|
||||
forbidden to user, at least for monitoring purposes. If "virsh dominfo"
|
||||
fails to run as an user, change the mode of the xenstore read-only socket
|
||||
with:</p>
|
||||
<p>
|
||||
<code>chmod 666 /var/run/xenstored/socket_ro</code>
|
||||
</p>
|
||||
<p>and also make sure that the Xen Daemon is running correctly with local
|
||||
HTTP server enabled, this is defined in
|
||||
<code>/etc/xen/xend-config.sxp</code> which need the following line to be
|
||||
enabled:</p>
|
||||
<p>
|
||||
<code>(xend-http-server yes)</code>
|
||||
</p>
|
||||
<p>If needed restart the xend daemon after making the change with the
|
||||
following command run as root:</p>
|
||||
<p>
|
||||
<code>service xend restart</code>
|
||||
</p>
|
||||
</li>
|
||||
</ol>
|
||||
<h3>
|
||||
<a name="Compilatio" id="Compilatio">Compilation</a>
|
||||
</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<em>What is the process to compile libvirt ?</em>
|
||||
<p>As most UNIX libraries libvirt follows the "standard":</p>
|
||||
<p>
|
||||
<code>gunzip -c libvirt-xxx.tar.gz | tar xvf -</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>cd libvirt-xxxx</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>./configure --help</code>
|
||||
</p>
|
||||
<p>to see the options, then the compilation/installation proper</p>
|
||||
<p>
|
||||
<code>./configure [possible options]</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>make</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>make install</code>
|
||||
</p>
|
||||
<p>At that point you may have to rerun ldconfig or a similar utility to
|
||||
update your list of installed shared libs.</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>What other libraries are needed to compile/install libvirt ?</em>
|
||||
<p>Libvirt requires libxenstore, which is usually provided by the xen
|
||||
packages as well as the public headers to compile against libxenstore.</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>I use the CVS version and there is no configure script</em>
|
||||
<p>The configure script (and other Makefiles) are generated. Use the
|
||||
autogen.sh script to regenerate the configure script and Makefiles,
|
||||
like:</p>
|
||||
<p>
|
||||
<code>./autogen.sh --prefix=/usr --disable-shared</code>
|
||||
</p>
|
||||
</li>
|
||||
</ol>
|
||||
<h3><a name="Developer" id="Developer">Developer</a> corner</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<em>Troubles compiling or linking programs using libvirt</em>
|
||||
<p>To simplify the process of reusing the library, libvirt comes with
|
||||
pkgconfig support, which can be used directly from autoconf support or
|
||||
via the pkg-config command line tool, like:</p>
|
||||
<p>
|
||||
<code>pkg-config libvirt --libs</code>
|
||||
</p>
|
||||
</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
162
docs/Makefile.am
162
docs/Makefile.am
@@ -1,162 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
SUBDIRS= schemas
|
||||
|
||||
# The directory containing the source code (if it contains documentation).
|
||||
DOC_SOURCE_DIR=../src
|
||||
|
||||
DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
|
||||
|
||||
apihtml = \
|
||||
html/index.html \
|
||||
html/libvirt-libvirt.html \
|
||||
html/libvirt-virterror.html
|
||||
|
||||
apipng = \
|
||||
html/left.png \
|
||||
html/up.png \
|
||||
html/home.png \
|
||||
html/right.png
|
||||
|
||||
devhelphtml = \
|
||||
devhelp/libvirt.devhelp \
|
||||
devhelp/index.html \
|
||||
devhelp/general.html \
|
||||
devhelp/libvirt-libvirt.html \
|
||||
devhelp/libvirt-virterror.html
|
||||
|
||||
devhelppng = \
|
||||
devhelp/home.png \
|
||||
devhelp/left.png \
|
||||
devhelp/right.png \
|
||||
devhelp/up.png
|
||||
|
||||
devhelpcss = devhelp/style.css
|
||||
|
||||
devhelpxsl = devhelp/devhelp.xsl devhelp/html.xsl
|
||||
|
||||
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
|
||||
|
||||
gif = \
|
||||
architecture.gif \
|
||||
node.gif
|
||||
|
||||
dot_html_in = $(wildcard *.html.in)
|
||||
dot_html = $(dot_html_in:%.html.in=%.html)
|
||||
|
||||
patches = $(wildcard api_extension/*.patch)
|
||||
|
||||
xml = \
|
||||
libvirt-api.xml \
|
||||
libvirt-refs.xml
|
||||
|
||||
fig = \
|
||||
libvirt-net-logical.fig \
|
||||
libvirt-net-physical.fig \
|
||||
libvirt-daemon-arch.fig \
|
||||
libvirt-driver-arch.fig \
|
||||
libvirt-object-model.fig
|
||||
|
||||
EXTRA_DIST= \
|
||||
libvirt-api.xml libvirt-refs.xml apibuild.py \
|
||||
site.xsl newapi.xsl news.xsl page.xsl ChangeLog.xsl \
|
||||
$(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
|
||||
$(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
|
||||
$(xml) $(fig) $(png) \
|
||||
$(patches) \
|
||||
ChangeLog.awk
|
||||
|
||||
CLEANFILES = $(dot_html) $(apihtml) $(devhelphtml)
|
||||
|
||||
all: web
|
||||
|
||||
api: libvirt-api.xml libvirt-refs.xml
|
||||
|
||||
web: $(dot_html) html/index.html devhelp/index.html
|
||||
|
||||
ChangeLog.xml: ../ChangeLog ChangeLog.awk
|
||||
awk -f ChangeLog.awk < $< > $@
|
||||
|
||||
ChangeLog.html.in: ChangeLog.xml ChangeLog.xsl
|
||||
@(if [ -x $(XSLTPROC) ] ; then \
|
||||
echo "Generating $@"; \
|
||||
name=`echo $@ | sed -e 's/.tmp//'`; \
|
||||
$(XSLTPROC) --nonet $(top_srcdir)/docs/ChangeLog.xsl $< > $@ || (rm $@ && exit 1) ; fi )
|
||||
|
||||
%.png: %.fig
|
||||
convert -rotate 90 $< $@
|
||||
|
||||
%.html.tmp: %.html.in site.xsl page.xsl sitemap.html.in
|
||||
@(if [ -x $(XSLTPROC) ] ; then \
|
||||
echo "Generating $@"; \
|
||||
name=`echo $@ | sed -e 's/.tmp//'`; \
|
||||
$(XSLTPROC) --stringparam pagename $$name --nonet --html $(top_srcdir)/docs/site.xsl $< > $@ || (rm $@ && exit 1) ; fi )
|
||||
|
||||
%.html: %.html.tmp
|
||||
@(if [ -x $(XMLLINT) -a -x $(XMLCATALOG) ] ; then \
|
||||
if $(XMLCATALOG) /etc/xml/catalog "-//W3C//DTD XHTML 1.0 Strict//EN" > /dev/null ; then \
|
||||
echo "Validating $@" ; \
|
||||
$(XMLLINT) --nonet --format --valid $< > $@ || : ; \
|
||||
else echo "missing XHTML1 DTD" ; fi ; fi );
|
||||
|
||||
|
||||
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
|
||||
-@(if [ -x $(XSLTPROC) ] ; then \
|
||||
echo "Rebuilding the HTML pages from the XML API" ; \
|
||||
$(XSLTPROC) --nonet $(srcdir)/newapi.xsl libvirt-api.xml ; fi )
|
||||
-@(if [ -x $(XMLLINT) -a -x $(XMLCATALOG) ] ; then \
|
||||
if $(XMLCATALOG) /etc/xml/catalog "-//W3C//DTD XHTML 1.0 Strict//EN" > /dev/null ; then \
|
||||
echo "Validating the resulting XHTML pages" ; \
|
||||
$(XMLLINT) --nonet --valid --noout html/*.html ; \
|
||||
else echo "missing XHTML1 DTD" ; fi ; fi );
|
||||
|
||||
devhelp/index.html devhelp/libvirt.devhelp: libvirt-api.xml $(devhelpxsl)
|
||||
-@(echo Rebuilding devhelp files)
|
||||
-@(if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet -o devhelp/libvirt.devhelp $(top_srcdir)/docs/devhelp/devhelp.xsl $(top_srcdir)/docs/libvirt-api.xml ; fi );
|
||||
|
||||
|
||||
libvirt-api.xml libvirt-refs.xml: apibuild.py \
|
||||
$(srcdir)/../include/libvirt/*.h \
|
||||
$(srcdir)/../src/libvirt.c $(srcdir)/../src/util/virterror.c
|
||||
-(./apibuild.py)
|
||||
|
||||
clean-local:
|
||||
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt
|
||||
|
||||
maintainer-clean-local: clean-local
|
||||
rm -rf libvirt-api.xml libvirt-refs.xml
|
||||
|
||||
rebuild: api all
|
||||
|
||||
install-data-local:
|
||||
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
|
||||
-@INSTALL@ -m 0644 $(srcdir)/FAQ.html \
|
||||
$(srcdir)/Libxml2-Logo-90x34.gif $(DESTDIR)$(HTML_DIR)
|
||||
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/html
|
||||
for h in $(apihtml); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$$h $(DESTDIR)$(HTML_DIR)/html; done
|
||||
for p in $(apipng); do \
|
||||
$(INSTALL) -m 0644 $(srcdir)/$$p $(DESTDIR)$(HTML_DIR)/html; done
|
||||
$(mkinstalldirs) $(DESTDIR)$(DEVHELP_DIR)
|
||||
for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
|
||||
@INSTALL@ -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
|
||||
done
|
||||
|
||||
uninstall-local:
|
||||
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 $(DESTDIR)$(DEVHELP_DIR)$$f ; done
|
4
docs/Plan
Normal file
4
docs/Plan
Normal file
@@ -0,0 +1,4 @@
|
||||
1/ go for a minimal library first, expand on use cases
|
||||
2/ reuse xenctrl.h / libxenctrl in a first implementation, but make
|
||||
sure to clearly isolate the bits calling them
|
||||
3/
|
33
docs/analysis
Normal file
33
docs/analysis
Normal file
@@ -0,0 +1,33 @@
|
||||
arch/xen/kernel/evtchn.c: Communication via Xen event channels
|
||||
->HYPERVISOR_xen_version call
|
||||
->HYPERVISOR_physdev_op call
|
||||
->HYPERVISOR_event_channel_op call
|
||||
-> global HYPERVISOR_shared_info
|
||||
|
||||
arch/xen/kernel/fixup.c: binary rewrinting for threads TLS
|
||||
-> message to suppress... + boot delay
|
||||
|
||||
arch/xen/kernel/gnttab.c: memory access and sharing
|
||||
inline assemby from privcmd.c using TRAP_INSTR macro to do an hypervisor
|
||||
call apparently.
|
||||
|
||||
arch/xen/kernel/reboot.c:
|
||||
-> HYPERVISOR_suspend call
|
||||
|
||||
include/asm-xen/asm-i386/hypercall.h:
|
||||
-> assembly macro for the hypervisor calls
|
||||
|
||||
tools/libxc/xc_*.c: library for xen control
|
||||
|
||||
tools/libxc/xc_private.h:
|
||||
-> Xen hypervisor call is an ioctl() with an privcmd_hypercall_t parameter
|
||||
xc_domain.c:
|
||||
-> API for all domain supervisor calls, create, memory, cpu weight, destroy
|
||||
|
||||
=> Fraser all over the place ...
|
||||
|
||||
/Xen/xen-unstable.hg/tools/libxc
|
||||
|
||||
|
||||
The hypervisor calls are defined as inlined functions in xc_private.h
|
||||
This is GPL and not installed.
|
136
docs/api.html.in
136
docs/api.html.in
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>The libvirt API concepts</h1>
|
||||
|
||||
<p> This page describes the main principles and architecture choices
|
||||
behind the definition of the libvirt API:
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#Objects">Objects exposed</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#Functions">Functions and naming conventions</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#Driver">The drivers</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#Remote">Daemon and remote access</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2><a name="Objects" id="Objects">Objects exposed</a></h2>
|
||||
<p> As defined in the <a href="goals.html">goals section</a>, libvirt
|
||||
API need to expose all the resources needed to manage the virtualization
|
||||
support of recent operating systems. The first object manipulated though
|
||||
the API is <code>virConnectPtr</code> which represent a connection to
|
||||
an hypervisor. Any application using libvirt is likely to start using the
|
||||
API by calling one of <a href="html/libvirt-libvirt.html#virConnectOpen"
|
||||
>the virConnectOpen functions</a>. You will note that those functions take
|
||||
a name argument which is actually an URI to select the right hypervisor to
|
||||
open, this is needed to allow remote connections and also select between
|
||||
different possible hypervisors (for example on a Linux system it may be
|
||||
possible to use both KVM and LinuxContainers on the same node). A NULL
|
||||
name will default to a preselected hypervisor but it's probably not a
|
||||
wise thing to do in most cases. See the <a href="uri.html">connection
|
||||
URI</a> page for a full descriptions of the values allowed.<p>
|
||||
<p> Once the application obtained a <code class='docref'>virConnectPtr</code>
|
||||
connection to the
|
||||
hypervisor it can then use it to manage domains and related resources
|
||||
available for virtualization like storage and networking. All those are
|
||||
exposed as first class objects, and connected to the hypervisor connection
|
||||
(and the node or cluster where it is available).</p>
|
||||
<p class="image">
|
||||
<img alt="first class objects exposed by the API"
|
||||
src="libvirt-object-model.png"/>
|
||||
</p>
|
||||
<p> The figure above shows the five main objects exported by the API:</p>
|
||||
<ul>
|
||||
<li>virConnectPtr: represent a connection to an hypervisor.</li>
|
||||
<li>virDomainPtr: represent one domain either active or defined (i.e.
|
||||
existing as permanent config file and storage but not currently running
|
||||
on that node). The function <code class='docref'>virConnectListDomains</code>
|
||||
allows to list all the IDs for the domains active on this hypervisor.</li>
|
||||
<li>virNetworkPtr: represent one network either active or defined (i.e.
|
||||
existing as permanent config file and storage but not currently activated.
|
||||
The function <code class='docref'>virConnectListNetworks</code>
|
||||
allows to list all the virtualization networks actived on this node.</li>
|
||||
<li>virStorageVolPtr: represent one storage volume, usually this is used
|
||||
as a block device available to one of the domains. The function
|
||||
<code class="docref">virStorageVolLookupByPath</code> allows to find
|
||||
the object based on its path on the node.</li>
|
||||
<li>virStoragePoolPtr: represent a storage pool, i.e. a logical area
|
||||
which can be used to allocate and store storage volumes. The function
|
||||
<code class="docref">virStoragePoolLookupByVolume</code> allows to find
|
||||
the storage pool containing a given storage volume.</li>
|
||||
</ul>
|
||||
<p> Most object manipulated by the library can also be represented using
|
||||
XML descriptions. This is used primarily to create those object, but is
|
||||
also helpful to modify or save their description back.</p>
|
||||
<p> Domains, network and storage pools can be either <code>active</code>
|
||||
i.e. either running or available for immediate use, or
|
||||
<code>defined</code> in which case they are inactive but there is
|
||||
a permanent definition available in the system for them. Based on this
|
||||
thay can be activated dynamically in order to be used.</p>
|
||||
<p> Most kind of object can also be named in various ways:<p>
|
||||
<ul>
|
||||
<li>by their <code>name</code>, an user friendly identifier but
|
||||
whose unicity cannot be garanteed between two nodes.</li>
|
||||
<li>by their <code>ID</code>, which is a runtime unique identifier
|
||||
provided by the hypervisor for one given activation of the object,
|
||||
but it becomes invalid once the resource is deactivated.</li >
|
||||
<li>by their <code>UUID</code>, a 16 bytes unique identifier
|
||||
as defined in <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>,
|
||||
which is garanteed to be unique for long term usage and across a
|
||||
set of nodes.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="Functions" id="Functions">Functions and naming
|
||||
conventions</a></h2>
|
||||
<p> The naming of the functions present in the library is usually
|
||||
made of a prefix describing the object associated to the function
|
||||
and a verb describing the action on that object.</p>
|
||||
<p> For each first class object you will find apis
|
||||
for the following actions:</p>
|
||||
<ul>
|
||||
<li><b>Lookup</b>:...LookupByName,
|
||||
<li><b>Enumeration</b>:virConnectList... and virConnectNumOf...:
|
||||
those are used to enumerate a set of object available to an given
|
||||
hypervisor connection like:
|
||||
<code class='docref'>virConnectListDomains</code>,
|
||||
<code class='docref'>virConnectNumOfDomains</code>,
|
||||
<code class='docref'>virConnectListNetworks</code>,
|
||||
<code class='docref'>virConnectListStoragePools</code>, etc.</li>
|
||||
<li><b>Description</b>: ...GetInfo: those are generic accessor providing
|
||||
a set of informations about an object, they are
|
||||
<code class='docref'>virNodeGetInfo</code>,
|
||||
<code class='docref'>virDomainGetInfo</code>,
|
||||
<code class='docref'>virStoragePoolGetInfo</code>,
|
||||
<code class='docref'>virStorageVolGetInfo</code>.</li>
|
||||
<li><b>Accessors</b>: ...Get... and ...Set...: those are more specific
|
||||
accessors to query or modify the given object, like
|
||||
<code class='docref'>virConnectGetType</code>,
|
||||
<code class='docref'>virDomainGetMaxMemory</code>,
|
||||
<code class='docref'>virDomainSetMemory</code>,
|
||||
<code class='docref'>virDomainGetVcpus</code>,
|
||||
<code class='docref'>virStoragePoolSetAutostart</code>,
|
||||
<code class='docref'>virNetworkGetBridgeName</code>, etc.</li>
|
||||
<li><b>Creation</b>: </li>
|
||||
<li><b>Destruction</b>: ... </li>
|
||||
</ul>
|
||||
<p> For more in-depth details of the storage related APIs see
|
||||
<a href="storage.html">the storage management page</a>,
|
||||
<h2><a name="Driver" id="Driver">The libvirt drivers</a></h2>
|
||||
<p></p>
|
||||
<p class="image">
|
||||
<img alt="The libvirt driver architecture"
|
||||
src="libvirt-driver-arch.png"/>
|
||||
</p>
|
||||
<h2><a name="Remote" id="Remote">Daemon and remote access</a></h2>
|
||||
<p></p>
|
||||
<p class="image">
|
||||
<img alt="The libvirt daemon and remote architecture"
|
||||
src="libvirt-daemon-arch.png"/>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@@ -1,302 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Implementing a new API in Libvirt</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Implementing a new API in Libvirt</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
This document walks you through the process of implementing a new
|
||||
API in libvirt. It uses as an example the addition of the node device
|
||||
create and destroy APIs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Before you begin coding, it is critical that you propose your
|
||||
changes on the libvirt mailing list and get feedback on your ideas to
|
||||
make sure what you're proposing fits with the general direction of the
|
||||
project. Even before doing a proof of concept implementation, send an
|
||||
email giving an overview of the functionality you think should be
|
||||
added to libvirt. Someone may already be working on the feature you
|
||||
want. Also, recognize that everything you write is likely to undergo
|
||||
significant rework as you discuss it with the other developers, so
|
||||
don't wait too long before getting feedback.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Adding a new API to libvirt is not difficult, but there are quite a
|
||||
few steps. This document assumes that you are familiar with C
|
||||
programming and have checked out the libvirt code from the source code
|
||||
repository and successfully built the existing tree. Instructions on
|
||||
how to check out and build the code can be found at:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="http://libvirt.org/downloads.html">http://libvirt.org/downloads.html</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once you have a working development environment, the steps to create a
|
||||
new API are:
|
||||
</p>
|
||||
<ol>
|
||||
<li>define the public API</li>
|
||||
<li>define the internal driver API</li>
|
||||
<li>implement the public API</li>
|
||||
<li>define the wire protocol format</li>
|
||||
<li>implement the RPC client</li>
|
||||
<li>implement the server side dispatcher</li>
|
||||
<li>implement the driver methods</li>
|
||||
<li>add virsh support</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
It is, of course, possible to implement the pieces in any order, but
|
||||
if the development tasks are completed in the order listed, the code
|
||||
will compile after each step. Given the number of changes required,
|
||||
verification after each step is highly recommended.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Submit new code in the form shown in the example code: one patch
|
||||
per step. That's not to say submit patches before you have working
|
||||
functionality--get the whole thing working and make sure you're happy
|
||||
with it. Then use git or some other version control system that lets
|
||||
you rewrite your commit history and break patches into pieces so you
|
||||
don't drop a big blob of code on the mailing list at one go. For
|
||||
example, I didn't follow my own advice when I originally submitted the
|
||||
example code to the libvirt list but rather submitted it in several
|
||||
large chunks. I've used git's ability to rewrite my commit history to
|
||||
break the code apart into the example patches shown.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Don't mix anything else into the patches you submit. The patches
|
||||
should be the minimal changes required to implement the functionality
|
||||
you're adding. If you notice a bug in unrelated code (i.e., code you
|
||||
don't have to touch to implement your API change) during development,
|
||||
create a patch that just addresses that bug and submit it
|
||||
separately.
|
||||
</p>
|
||||
|
||||
<p>With that said, let's begin.</p>
|
||||
|
||||
<h2><a name='publicapi'>Defining the public API</a></h2>
|
||||
|
||||
<p>The first task is to define the public API and add it to:</p>
|
||||
|
||||
<p><code>include/libvirt/libvirt.h.in</code></p>
|
||||
|
||||
<p>
|
||||
This task is in many ways the most important to get right, since once
|
||||
the API has been committed to the repository, it's libvirt's policy
|
||||
never to change it. Mistakes in the implementation are bugs that you
|
||||
can fix. Make a mistake in the API definition and you're stuck with
|
||||
it, so think carefully about the interface and don't be afraid to
|
||||
rework it as you go through the process of implementing it.
|
||||
</p>
|
||||
|
||||
<p>Once you have defined the API, you have to add the symbol names to:</p>
|
||||
|
||||
<p><code>src/libvirt_public.syms</code></p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0001-Step-1-of-8-Define-the-public-API.patch">0001-Step-1-of-8-Define-the-public-API.patch</a> for example code.</p>
|
||||
|
||||
|
||||
<h2><a name='internalapi'>Defining the internal API</a></h2>
|
||||
|
||||
<p>
|
||||
Each public API call is associated with a driver, such as a host
|
||||
virtualization driver, a network virtualization driver, a storage
|
||||
virtualization driver, a state driver, or a device monitor. Adding
|
||||
the internal API is ordinarily a matter of adding a new member to the
|
||||
struct representing one of these drivers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Of course, it's possible that the new API will involve the creation of
|
||||
an entire new driver type, in which case the changes will include the
|
||||
creation of a new struct type to represent the new driver type.
|
||||
</p>
|
||||
|
||||
<p>The driver structs are defined in:</p>
|
||||
|
||||
<p><code>src/driver.h</code></p>
|
||||
|
||||
<p>
|
||||
To define the internal API, first typedef the driver function
|
||||
prototype and then add a new field for it to the relevant driver
|
||||
struct.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0002-Step-2-of-8-Define-the-internal-driver-API.patch">0002-Step-2-of-8-Define-the-internal-driver-API.patch</a></p>
|
||||
|
||||
<h2><a name='implpublic'>Implementing the public API</a></h2>
|
||||
|
||||
<p>
|
||||
Implementing the public API is largely a formality in which we wire up
|
||||
public API to the internal driver API. The public API implementation
|
||||
takes care of some basic validity checks before passing control to the
|
||||
driver implementation. In RFC 2119 vocabulary, this function:
|
||||
</p>
|
||||
|
||||
<ol class="ordinarylist">
|
||||
<li>SHOULD log a message with VIR_DEBUG() indicating that it is
|
||||
being called and its parameters;</li>
|
||||
<li>MUST call virResetLastError();</li>
|
||||
<li>SHOULD confirm that the connection is valid with
|
||||
VIR_IS_CONNECT(conn);</li>
|
||||
<li><strong>SECURITY: If the API requires a connection with write
|
||||
privileges, MUST confirm that the connection flags do not
|
||||
indicate that the connection is read-only;</strong></li>
|
||||
<li>SHOULD do basic validation of the parameters that are being
|
||||
passed in;</li>
|
||||
<li>MUST confirm that the driver for this connection exists and that
|
||||
it implements this function;</li>
|
||||
<li>MUST call the internal API;</li>
|
||||
<li>SHOULD log a message with VIR_DEBUG() indicating that it is
|
||||
returning, its return value, and status.</li>
|
||||
<li>MUST return status to the caller.</li>
|
||||
</ol>
|
||||
|
||||
<p>The public API calls are implemented in:</p>
|
||||
|
||||
<p><code>src/libvirt.c</code></p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0003-Step-3-of-8-Implement-the-public-API.patch">0003-Step-3-of-8-Implement-the-public-API.patch</a></p>
|
||||
|
||||
|
||||
<h2><a name='wireproto'>Defining the wire protocol format</a></h2>
|
||||
|
||||
<p>
|
||||
Defining the wire protocol is essentially a straightforward exercise
|
||||
which is probably most easily understood by referring to the existing
|
||||
remote protocol wire format definitions and the example patch. It
|
||||
involves making two additions to:
|
||||
</p>
|
||||
|
||||
<p><code>qemud/remote_protocol.x</code></p>
|
||||
|
||||
<p>
|
||||
First, create two new structs for each new function that you're adding
|
||||
to the API. One struct describes the parameters to be passed to the
|
||||
remote function, and a second struct describes the value returned by
|
||||
the remote function. The one exception to this rule is that functions
|
||||
that return only integer status do not require a struct for returned
|
||||
data.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Second, add values to the remote_procedure enum for each new function
|
||||
added to the API.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0004-Step-4-of-8-Define-the-wire-protocol-format.patch">0004-Step-4-of-8-Define-the-wire-protocol-format.patch</a></p>
|
||||
|
||||
<p>
|
||||
Once these changes are in place, it's necessary to run 'make rpcgen'
|
||||
in the qemud directory to create the .c and .h files required by the
|
||||
remote protocol code. This must be done on a Linux host using the
|
||||
GLibC rpcgen program. Other rpcgen versions may generate code which
|
||||
results in bogus compile time warnings
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name='rpcclient'>Implement the RPC client</a></h2>
|
||||
|
||||
<p>
|
||||
Implementing the RPC client is also relatively mechanical, so refer to
|
||||
the exising code and example patch for guidance. The RPC client uses
|
||||
the rpcgen generated .h files. The remote method calls go in:
|
||||
</p>
|
||||
|
||||
<p><code>src/remote_internal.c</code></p>
|
||||
|
||||
<p>Each remote method invocation does the following:</p>
|
||||
|
||||
<ol class="ordinarylist">
|
||||
<li>locks the remote driver;</li>
|
||||
<li>sets up the method arguments;</li>
|
||||
<li>invokes the remote function;</li>
|
||||
<li>checks the return value, if necessary;</li>
|
||||
<li>extracts any returned data;</li>
|
||||
<li>frees any returned data;</li>
|
||||
<li>unlocks the remote driver.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Once you have created the remote method calls, you have to add fields
|
||||
for them to the driver structs for the appropriate remote driver.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0005-Step-5-of-8-Implement-the-RPC-client.patch">0005-Step-5-of-8-Implement-the-RPC-client.patch</a></p>
|
||||
|
||||
<h2><a name="serverdispatch">Implement the server side dispatcher</a></h2>
|
||||
|
||||
<p>
|
||||
Implementing the server side of the remote function calls is simply a
|
||||
matter of deserializing the parameters passed in from the remote
|
||||
caller and passing them to the corresponding internal API function.
|
||||
The server side dispatchers are implemented in:
|
||||
</p>
|
||||
|
||||
<p><code>qemud/remote.c</code></p>
|
||||
|
||||
<p>Again, this step uses the .h files generated by make rpcgen.</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0006-Step-6-of-8-Implement-the-server-side-dispatcher.patch">0006-Step-6-of-8-Implement-the-server-side-dispatcher.patch</a></p>
|
||||
|
||||
|
||||
<h2><a name="driverimpl">Implement the driver methods</a></h2>
|
||||
|
||||
<p>
|
||||
So, after all that, we get to the fun part. All functionality in
|
||||
libvirt is implemented inside a driver. Thus, here is where you
|
||||
implement whatever functionality you're adding to libvirt. You'll
|
||||
either need to add additional files to the src directory or extend
|
||||
files that are already there, depending on what functionality you're
|
||||
adding.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the example code, the extension is only an additional two function
|
||||
calls in the node device API, so most of the new code is additions to
|
||||
existing files. The only new files are there for multi-platform
|
||||
implementation convenience, as some of the new code is Linux specific.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The example code is probably uninteresting unless you're concerned
|
||||
with libvirt storage, but I've included it here to show how new files
|
||||
are added to the build environment.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0007-Step-7-of-8-Implement-the-driver-methods.patch">0007-Step-7-of-8-Implement-the-driver-methods.patch</a></p>
|
||||
|
||||
<h2><a name="virsh">Implement virsh commands</a></h2>
|
||||
|
||||
<p>
|
||||
Once you have the new functionality in place, the easiest way to test
|
||||
it and also to provide it to end users is to implement support for it
|
||||
in virsh.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A virsh command is composed of a few pieces of code. You need to
|
||||
define an array of vshCmdInfo structs for each new command that
|
||||
contain the help text and the command description text. You also need
|
||||
an array of vshCmdOptDef structs to describe the command options.
|
||||
Once you have those pieces of data in place you can write the function
|
||||
implementing the virsh command. Finally, you need to add the new
|
||||
command to the commands[] array.
|
||||
</p>
|
||||
|
||||
<p class="example">See <a href="api_extension/0008-Step-8-of-8-Add-virsh-support.patch">0008-Step-8-of-8-Add-virsh-support.patch</a></p>
|
||||
|
||||
<p>Once you have working functionality, run make check and make
|
||||
syntax-check before generating patches.</p>
|
||||
</body>
|
||||
</html>
|
@@ -1,44 +0,0 @@
|
||||
From 2ae8fd62a1e5e085b7902da9bc207b806d84fd91 Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Tue, 19 May 2009 16:16:11 -0400
|
||||
Subject: [PATCH] Step 1 of 8 Define the public API
|
||||
|
||||
---
|
||||
include/libvirt/libvirt.h.in | 6 ++++++
|
||||
src/libvirt_public.syms | 6 ++++++
|
||||
2 files changed, 12 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
|
||||
index a028b21..2f7076f 100644
|
||||
--- a/include/libvirt/libvirt.h.in
|
||||
+++ b/include/libvirt/libvirt.h.in
|
||||
@@ -1124,6 +1124,12 @@ int virNodeDeviceDettach (virNodeDevicePtr dev);
|
||||
int virNodeDeviceReAttach (virNodeDevicePtr dev);
|
||||
int virNodeDeviceReset (virNodeDevicePtr dev);
|
||||
|
||||
+virNodeDevicePtr virNodeDeviceCreateXML (virConnectPtr conn,
|
||||
+ const char *xmlDesc,
|
||||
+ unsigned int flags);
|
||||
+
|
||||
+int virNodeDeviceDestroy (virNodeDevicePtr dev);
|
||||
+
|
||||
/*
|
||||
* Domain Event Notification
|
||||
*/
|
||||
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
|
||||
index f7ebbc3..b8f9128 100644
|
||||
--- a/src/libvirt_public.syms
|
||||
+++ b/src/libvirt_public.syms
|
||||
@@ -258,4 +258,10 @@ LIBVIRT_0.6.1 {
|
||||
virNodeGetSecurityModel;
|
||||
} LIBVIRT_0.6.0;
|
||||
|
||||
+LIBVIRT_0.6.3 {
|
||||
+ global:
|
||||
+ virNodeDeviceCreateXML;
|
||||
+ virNodeDeviceDestroy;
|
||||
+} LIBVIRT_0.6.1;
|
||||
+
|
||||
# .... define new API here using predicted next version number ....
|
||||
--
|
||||
1.6.0.6
|
@@ -1,36 +0,0 @@
|
||||
From b26d7fc2d64e7e6e4d3ea2b43361015d3620d7a6 Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Tue, 19 May 2009 16:19:14 -0400
|
||||
Subject: [PATCH] Step 2 of 8 Define the internal driver API
|
||||
|
||||
---
|
||||
src/driver.h | 7 +++++++
|
||||
1 files changed, 7 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/driver.h b/src/driver.h
|
||||
index 39dc413..c357b76 100644
|
||||
--- a/src/driver.h
|
||||
+++ b/src/driver.h
|
||||
@@ -684,6 +684,11 @@ typedef int (*virDevMonDeviceListCaps)(virNodeDevicePtr dev,
|
||||
char **const names,
|
||||
int maxnames);
|
||||
|
||||
+typedef virNodeDevicePtr (*virDrvNodeDeviceCreateXML)(virConnectPtr conn,
|
||||
+ const char *xmlDesc,
|
||||
+ unsigned int flags);
|
||||
+typedef int (*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev);
|
||||
+
|
||||
/**
|
||||
* _virDeviceMonitor:
|
||||
*
|
||||
@@ -702,6 +707,8 @@ struct _virDeviceMonitor {
|
||||
virDevMonDeviceGetParent deviceGetParent;
|
||||
virDevMonDeviceNumOfCaps deviceNumOfCaps;
|
||||
virDevMonDeviceListCaps deviceListCaps;
|
||||
+ virDrvNodeDeviceCreateXML deviceCreateXML;
|
||||
+ virDrvNodeDeviceDestroy deviceDestroy;
|
||||
};
|
||||
|
||||
/*
|
||||
--
|
||||
1.6.0.6
|
@@ -1,119 +0,0 @@
|
||||
From fc585594a207dfb9149e7d3d01c9eb1c79b6d52d Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Tue, 19 May 2009 16:22:23 -0400
|
||||
Subject: [PATCH] Step 3 of 8 Implement the public API
|
||||
|
||||
---
|
||||
src/libvirt.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 97 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/libvirt.c b/src/libvirt.c
|
||||
index f3d4484..ded18a7 100644
|
||||
--- a/src/libvirt.c
|
||||
+++ b/src/libvirt.c
|
||||
@@ -7509,6 +7509,103 @@ error:
|
||||
}
|
||||
|
||||
|
||||
+/**
|
||||
+ * virNodeDeviceCreateXML:
|
||||
+ * @conn: pointer to the hypervisor connection
|
||||
+ * @xmlDesc: string containing an XML description of the device to be created
|
||||
+ * @flags: callers should always pass 0
|
||||
+ *
|
||||
+ * Create a new device on the VM host machine, for example, virtual
|
||||
+ * HBAs created using vport_create.
|
||||
+ *
|
||||
+ * Returns a node device object if successful, NULL in case of failure
|
||||
+ */
|
||||
+virNodeDevicePtr
|
||||
+virNodeDeviceCreateXML(virConnectPtr conn,
|
||||
+ const char *xmlDesc,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%d", conn, xmlDesc, flags);
|
||||
+
|
||||
+ virResetLastError();
|
||||
+
|
||||
+ if (!VIR_IS_CONNECT(conn)) {
|
||||
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (conn->flags & VIR_CONNECT_RO) {
|
||||
+ virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (xmlDesc == NULL) {
|
||||
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (conn->deviceMonitor &&
|
||||
+ conn->deviceMonitor->deviceCreateXML) {
|
||||
+ virNodeDevicePtr dev = conn->deviceMonitor->deviceCreateXML(conn, xmlDesc, flags);
|
||||
+ if (dev == NULL)
|
||||
+ goto error;
|
||||
+ return dev;
|
||||
+ }
|
||||
+
|
||||
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
+
|
||||
+error:
|
||||
+ /* Copy to connection error object for back compatability */
|
||||
+ virSetConnError(conn);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * virNodeDeviceDestroy:
|
||||
+ * @dev: a device object
|
||||
+ *
|
||||
+ * Destroy the device object. The virtual device is removed from the host operating system.
|
||||
+ * This function may require privileged access
|
||||
+ *
|
||||
+ * Returns 0 in case of success and -1 in case of failure.
|
||||
+ */
|
||||
+int
|
||||
+virNodeDeviceDestroy(virNodeDevicePtr dev)
|
||||
+{
|
||||
+ DEBUG("dev=%p", dev);
|
||||
+
|
||||
+ virResetLastError();
|
||||
+
|
||||
+ if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
|
||||
+ virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ if (dev->conn->flags & VIR_CONNECT_RO) {
|
||||
+ virLibConnError(dev->conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (dev->conn->deviceMonitor &&
|
||||
+ dev->conn->deviceMonitor->deviceDestroy) {
|
||||
+ int retval = dev->conn->deviceMonitor->deviceDestroy(dev);
|
||||
+ if (retval < 0) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
+
|
||||
+error:
|
||||
+ /* Copy to connection error object for back compatability */
|
||||
+ virSetConnError(dev->conn);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Domain Event Notification
|
||||
*/
|
||||
--
|
||||
1.6.0.6
|
@@ -1,47 +0,0 @@
|
||||
From bce8f1243b0454c0d70e3db832a039d22faab09a Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Wed, 20 May 2009 13:58:58 -0400
|
||||
Subject: [PATCH] Step 4 of 8 Define the wire protocol format
|
||||
|
||||
---
|
||||
qemud/remote_protocol.x | 18 +++++++++++++++++-
|
||||
1 files changed, 17 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x
|
||||
index 2d8e6a2..2c79949 100644
|
||||
--- a/qemud/remote_protocol.x
|
||||
+++ b/qemud/remote_protocol.x
|
||||
@@ -1109,6 +1109,19 @@ struct remote_node_device_reset_args {
|
||||
remote_nonnull_string name;
|
||||
};
|
||||
|
||||
+struct remote_node_device_create_xml_args {
|
||||
+ remote_nonnull_string xml_desc;
|
||||
+ int flags;
|
||||
+};
|
||||
+
|
||||
+struct remote_node_device_create_xml_ret {
|
||||
+ remote_nonnull_node_device dev;
|
||||
+};
|
||||
+
|
||||
+struct remote_node_device_destroy_args {
|
||||
+ remote_nonnull_string name;
|
||||
+};
|
||||
+
|
||||
|
||||
/**
|
||||
* Events Register/Deregister:
|
||||
@@ -1270,7 +1283,10 @@ enum remote_procedure {
|
||||
REMOTE_PROC_NODE_DEVICE_RESET = 120,
|
||||
|
||||
REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 121,
|
||||
- REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122
|
||||
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 122,
|
||||
+
|
||||
+ REMOTE_PROC_NODE_DEVICE_CREATE_XML = 123,
|
||||
+ REMOTE_PROC_NODE_DEVICE_DESTROY = 124
|
||||
};
|
||||
|
||||
/* Custom RPC structure. */
|
||||
--
|
||||
1.6.0.6
|
@@ -1,84 +0,0 @@
|
||||
From ff272552c297966ace3492aefe91fc830152251a Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Tue, 19 May 2009 16:26:12 -0400
|
||||
Subject: [PATCH] Step 5 of 8 Implement the RPC client
|
||||
|
||||
---
|
||||
src/remote_internal.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 55 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/remote_internal.c b/src/remote_internal.c
|
||||
index 4b3afb0..e665ef8 100644
|
||||
--- a/src/remote_internal.c
|
||||
+++ b/src/remote_internal.c
|
||||
@@ -4978,6 +4978,59 @@ done:
|
||||
}
|
||||
|
||||
|
||||
+static virNodeDevicePtr
|
||||
+remoteNodeDeviceCreateXML(virConnectPtr conn,
|
||||
+ const char *xmlDesc,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ remote_node_device_create_xml_args args;
|
||||
+ remote_node_device_create_xml_ret ret;
|
||||
+ virNodeDevicePtr dev = NULL;
|
||||
+ struct private_data *priv = conn->privateData;
|
||||
+
|
||||
+ remoteDriverLock(priv);
|
||||
+
|
||||
+ memset(&ret, 0, sizeof ret);
|
||||
+ args.xml_desc = (char *)xmlDesc;
|
||||
+ args.flags = flags;
|
||||
+
|
||||
+ if (call(conn, priv, 0, REMOTE_PROC_NODE_DEVICE_CREATE_XML,
|
||||
+ (xdrproc_t) xdr_remote_node_device_create_xml_args, (char *) &args,
|
||||
+ (xdrproc_t) xdr_remote_node_device_create_xml_ret, (char *) &ret) == -1)
|
||||
+ goto done;
|
||||
+
|
||||
+ dev = get_nonnull_node_device(conn, ret.dev);
|
||||
+ xdr_free ((xdrproc_t) xdr_remote_node_device_create_xml_ret, (char *) &ret);
|
||||
+
|
||||
+done:
|
||||
+ remoteDriverUnlock(priv);
|
||||
+ return dev;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+remoteNodeDeviceDestroy(virNodeDevicePtr dev)
|
||||
+{
|
||||
+ int rv = -1;
|
||||
+ remote_node_device_destroy_args args;
|
||||
+ struct private_data *priv = dev->conn->privateData;
|
||||
+
|
||||
+ remoteDriverLock(priv);
|
||||
+
|
||||
+ args.name = dev->name;
|
||||
+
|
||||
+ if (call(dev->conn, priv, 0, REMOTE_PROC_NODE_DEVICE_DESTROY,
|
||||
+ (xdrproc_t) xdr_remote_node_device_destroy_args, (char *) &args,
|
||||
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
|
||||
+ goto done;
|
||||
+
|
||||
+ rv = 0;
|
||||
+
|
||||
+done:
|
||||
+ remoteDriverUnlock(priv);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
@@ -6982,6 +7035,8 @@ static virDeviceMonitor dev_monitor = {
|
||||
.deviceGetParent = remoteNodeDeviceGetParent,
|
||||
.deviceNumOfCaps = remoteNodeDeviceNumOfCaps,
|
||||
.deviceListCaps = remoteNodeDeviceListCaps,
|
||||
+ .deviceCreateXML = remoteNodeDeviceCreateXML,
|
||||
+ .deviceDestroy = remoteNodeDeviceDestroy
|
||||
};
|
||||
|
||||
|
||||
--
|
||||
1.6.0.6
|
@@ -1,70 +0,0 @@
|
||||
From 4c5166df583459574526841234d61d6ae5be19a0 Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Tue, 19 May 2009 16:26:55 -0400
|
||||
Subject: [PATCH] Step 6 of 8 Implement the server side dispatcher
|
||||
|
||||
---
|
||||
qemud/remote.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 48 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/qemud/remote.c b/qemud/remote.c
|
||||
index e27820f..8d24a3a 100644
|
||||
--- a/qemud/remote.c
|
||||
+++ b/qemud/remote.c
|
||||
@@ -4323,6 +4323,54 @@ remoteDispatchNodeDeviceReset (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+remoteDispatchNodeDeviceCreateXml(struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
+ struct qemud_client *client ATTRIBUTE_UNUSED,
|
||||
+ virConnectPtr conn,
|
||||
+ remote_error *rerr,
|
||||
+ remote_node_device_create_xml_args *args,
|
||||
+ remote_node_device_create_xml_ret *ret)
|
||||
+{
|
||||
+ virNodeDevicePtr dev;
|
||||
+
|
||||
+ dev = virNodeDeviceCreateXML (conn, args->xml_desc, args->flags);
|
||||
+ if (dev == NULL) {
|
||||
+ remoteDispatchConnError(rerr, conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ make_nonnull_node_device (&ret->dev, dev);
|
||||
+ virNodeDeviceFree(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+remoteDispatchNodeDeviceDestroy(struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
+ struct qemud_client *client ATTRIBUTE_UNUSED,
|
||||
+ virConnectPtr conn,
|
||||
+ remote_error *rerr,
|
||||
+ remote_node_device_destroy_args *args,
|
||||
+ void *ret ATTRIBUTE_UNUSED)
|
||||
+{
|
||||
+ virNodeDevicePtr dev;
|
||||
+
|
||||
+ dev = virNodeDeviceLookupByName(conn, args->name);
|
||||
+ if (dev == NULL) {
|
||||
+ remoteDispatchFormatError(rerr, "%s", _("node_device not found"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (virNodeDeviceDestroy(dev) == -1) {
|
||||
+ remoteDispatchConnError(rerr, conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**************************
|
||||
* Async Events
|
||||
**************************/
|
||||
--
|
||||
1.6.0.6
|
File diff suppressed because it is too large
Load Diff
@@ -1,132 +0,0 @@
|
||||
From 193cc4abbb6c2fc5557d3699f86ff0103d5a21ef Mon Sep 17 00:00:00 2001
|
||||
From: David Allan <dallan@redhat.com>
|
||||
Date: Tue, 19 May 2009 16:47:31 -0400
|
||||
Subject: [PATCH 8/8] Step 8 of 8 Add virsh support
|
||||
|
||||
---
|
||||
src/virsh.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 103 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/virsh.c b/src/virsh.c
|
||||
index cb32ede..ab2a2b7 100644
|
||||
--- a/src/virsh.c
|
||||
+++ b/src/virsh.c
|
||||
@@ -2962,6 +2962,107 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd)
|
||||
|
||||
|
||||
/*
|
||||
+ * "nodedev-create" command
|
||||
+ */
|
||||
+static const vshCmdInfo info_node_device_create[] = {
|
||||
+ {"help", gettext_noop("create a device defined "
|
||||
+ "by an XML file on the node")},
|
||||
+ {"desc", gettext_noop("Create a device on the node. Note that this "
|
||||
+ "command creates devices on the physical host "
|
||||
+ "that can then be assigned to a virtual machine.")},
|
||||
+ {NULL, NULL}
|
||||
+};
|
||||
+
|
||||
+static const vshCmdOptDef opts_node_device_create[] = {
|
||||
+ {"file", VSH_OT_DATA, VSH_OFLAG_REQ,
|
||||
+ gettext_noop("file containing an XML description of the device")},
|
||||
+ {NULL, 0, 0, NULL}
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd)
|
||||
+{
|
||||
+ virNodeDevicePtr dev = NULL;
|
||||
+ char *from;
|
||||
+ int found = 0;
|
||||
+ int ret = TRUE;
|
||||
+ char *buffer;
|
||||
+
|
||||
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ from = vshCommandOptString(cmd, "file", &found);
|
||||
+ if (!found) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ dev = virNodeDeviceCreateXML(ctl->conn, buffer, 0);
|
||||
+ free (buffer);
|
||||
+
|
||||
+ if (dev != NULL) {
|
||||
+ vshPrint(ctl, _("Node device %s created from %s\n"),
|
||||
+ virNodeDeviceGetName(dev), from);
|
||||
+ } else {
|
||||
+ vshError(ctl, FALSE, _("Failed to create node device from %s"), from);
|
||||
+ ret = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * "nodedev-destroy" command
|
||||
+ */
|
||||
+static const vshCmdInfo info_node_device_destroy[] = {
|
||||
+ {"help", gettext_noop("destroy a device on the node")},
|
||||
+ {"desc", gettext_noop("Destroy a device on the node. Note that this "
|
||||
+ "command destroys devices on the physical host ")},
|
||||
+ {NULL, NULL}
|
||||
+};
|
||||
+
|
||||
+static const vshCmdOptDef opts_node_device_destroy[] = {
|
||||
+ {"name", VSH_OT_DATA, VSH_OFLAG_REQ,
|
||||
+ gettext_noop("name of the device to be destroyed")},
|
||||
+ {NULL, 0, 0, NULL}
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+cmdNodeDeviceDestroy(vshControl *ctl, const vshCmd *cmd)
|
||||
+{
|
||||
+ virNodeDevicePtr dev = NULL;
|
||||
+ int ret = TRUE;
|
||||
+ int found = 0;
|
||||
+ char *name;
|
||||
+
|
||||
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ name = vshCommandOptString(cmd, "name", &found);
|
||||
+ if (!found) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ dev = virNodeDeviceLookupByName(ctl->conn, name);
|
||||
+
|
||||
+ if (virNodeDeviceDestroy(dev) == 0) {
|
||||
+ vshPrint(ctl, _("Destroyed node device '%s'\n"), name);
|
||||
+ } else {
|
||||
+ vshError(ctl, FALSE, _("Failed to destroy node device '%s'"), name);
|
||||
+ ret = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ virNodeDeviceFree(dev);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
* XML Building helper for pool-define-as and pool-create-as
|
||||
*/
|
||||
static const vshCmdOptDef opts_pool_X_as[] = {
|
||||
@@ -5895,6 +5996,8 @@ static const vshCmdDef commands[] = {
|
||||
{"nodedev-dettach", cmdNodeDeviceDettach, opts_node_device_dettach, info_node_device_dettach},
|
||||
{"nodedev-reattach", cmdNodeDeviceReAttach, opts_node_device_reattach, info_node_device_reattach},
|
||||
{"nodedev-reset", cmdNodeDeviceReset, opts_node_device_reset, info_node_device_reset},
|
||||
+ {"nodedev-create", cmdNodeDeviceCreate, opts_node_device_create, info_node_device_create},
|
||||
+ {"nodedev-destroy", cmdNodeDeviceDestroy, opts_node_device_destroy, info_node_device_destroy},
|
||||
|
||||
{"pool-autostart", cmdPoolAutostart, opts_pool_autostart, info_pool_autostart},
|
||||
{"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build},
|
||||
--
|
||||
1.6.0.6
|
2134
docs/apibuild.py
2134
docs/apibuild.py
File diff suppressed because it is too large
Load Diff
@@ -1,142 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Applications using <strong>libvirt</strong></h1>
|
||||
|
||||
<p>
|
||||
This page provides an illustration of the wide variety of
|
||||
applications using the libvirt management API. If you know
|
||||
of interesting applications not listed on this page, send
|
||||
a message to the <a href="contact.html">mailing list</a>
|
||||
to request that it be added here. If your application uses
|
||||
libvirt as its API, the following graphic is available for
|
||||
your website to advertise support for libvirt:
|
||||
</p>
|
||||
|
||||
<p class="image">
|
||||
<img src="madeWith.png" alt="Made with libvirt"/>
|
||||
</p>
|
||||
|
||||
<h2>Command line tools</h2>
|
||||
|
||||
<dl>
|
||||
<dt>virsh</dt>
|
||||
<dd>
|
||||
An interactive shell, and batch scriptable tool for performing
|
||||
management tasks on all libvirt managed domains, networks and
|
||||
storage. This is part of the libvirt core distribution.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-install</a></dt>
|
||||
<dd>
|
||||
Provides a way to provision new virtual machines from a
|
||||
OS distribution install tree. It supports provisioning from
|
||||
local CD images, and the network over NFS, HTTP and FTP.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-clone</a></dt>
|
||||
<dd>
|
||||
Allows the disk image(s) and configuration for an existing
|
||||
virtual machine to be cloned to form a new virtual machine.
|
||||
It automates copying of data across to new disk images, and
|
||||
updates the UUID, Mac address and name in the configuration
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-image</a></dt>
|
||||
<dd>
|
||||
Provides a way to deploy virtual appliances. It defines a
|
||||
simplified portable XML format describing the pre-requisites
|
||||
of a virtual machine. At time of deployment this is translated
|
||||
into the domain XML format for execution under any libvirt
|
||||
hypervisor meeting the pre-requisites.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-df/">virt-df</a></dt>
|
||||
<dd>
|
||||
Examine the utilization of each filesystem in a virtual machine
|
||||
from the comfort of the host machine. This tool peeks into the
|
||||
guest disks and determines how much space is used. It can cope
|
||||
with common Linux filesystems and LVM volumes.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-top/">virt-top</a></dt>
|
||||
<dd>
|
||||
Watch the CPU, memory, network and disk utilization of all
|
||||
virtual machines running on a host.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>Desktop applications</h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://virt-manager.org/">virt-manager</a></dt>
|
||||
<dd>
|
||||
A general purpose desktop management tool, able to manage
|
||||
virtual machines across both local and remotely accessed
|
||||
hypervisors. It is targeted at home and small office usage
|
||||
upto managing 10-20 hosts and their VMs.
|
||||
</dd>
|
||||
<dt><a href="http://virt-manager.org/">virt-viewer</a></dt>
|
||||
<dd>
|
||||
A lightweight tool for accessing the graphical console
|
||||
associated with a virtual machine. It can securely connect
|
||||
to remote consoles supporting the VNC protocol. Also provides
|
||||
an optional mozilla browser plugin.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>Web applications</h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://ovirt.org/">oVirt</a></dt>
|
||||
<dd>
|
||||
oVirt provides the ability to manage large numbers of virtual
|
||||
machines across an entire data center of hosts. It integrates
|
||||
with FreeIPA for Kerberos authentication, and in the future,
|
||||
certificate management.
|
||||
</dd>
|
||||
<dt><a href="http://community.abiquo.com/display/AbiCloud">AbiCloud</a></dt>
|
||||
<dd>
|
||||
AbiCloud is an open source cloud platform manager which allows to
|
||||
easily deploy a private cloud in your datacenter. One of the key
|
||||
differences of AbiCloud is the web rich interface for managing the
|
||||
infrastructure. You can deploy a new service just dragging and
|
||||
dropping a VM.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>LiveCD / Appliances</h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://et.redhat.com/~rjones/virt-p2v/">virt-p2v</a></dt>
|
||||
<dd>
|
||||
A tool for converting a physical machine into a virtual machine. It
|
||||
is a LiveCD which is booted on the machine to be converted. It collects
|
||||
a little information from the user and then copies the disks over to
|
||||
a remote machine and defines the XML for a domain to run the guest.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>Monitoring plugins</h2>
|
||||
<dl>
|
||||
<dt><a href="http://honk.sigxcpu.org/projects/libvirt/#munin">for munin</a></dt>
|
||||
<dd>
|
||||
The plugins provided by Guido Günther allow to monitor various things
|
||||
like network and block I/O with
|
||||
<a href="http://munin.projects.linpro.no/">Munin</a>.
|
||||
</dd>
|
||||
<dt><a href="http://collectd.org/plugins/libvirt.shtml">for collectd</a></dt>
|
||||
<dd>
|
||||
The libvirt-plugin is part of <a href="http://collectd.org/">collectd</a>
|
||||
and gather statistics about virtualized guests on a system. This
|
||||
way, you can collect CPU, network interface and block device usage
|
||||
for each guest without installing collectd on the guest systems.
|
||||
or a full description of available please refer to the libvirt section
|
||||
in the collectd.conf(5) manual page.
|
||||
</dd>
|
||||
<dt><a href="http://et.redhat.com/~rjones/nagios-virt/">nagios-virt</a></dt>
|
||||
<dd>
|
||||
Nagios-virt is a configuration tool for adding monitoring of your
|
||||
virtualised domains to <a href="http://www.nagios.org/">Nagios</a>.
|
||||
You can use this tool to either set up a new Nagios installation for
|
||||
your Xen or QEMU/KVM guests, or to integrate with your existing Nagios
|
||||
installation.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Domain management architecture</h1>
|
||||
</body>
|
||||
</html>
|
@@ -1,87 +0,0 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1050 7500 9375 7500 9375 8700 1050 8700 1050 7500
|
||||
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
3525 7275 3525 4125 1050 4125 1050 7275 3525 7275
|
||||
2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2
|
||||
1050 6540 3540 6525
|
||||
2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5
|
||||
1590 6900 1590 6645 1140 6645 1140 6900 1590 6900
|
||||
2 4 0 1 0 7 50 -1 -1 4.000 0 0 7 0 0 5
|
||||
1590 7185 1590 6930 1140 6930 1140 7185 1590 7185
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1 1 2.00 120.00 240.00
|
||||
1875 7725 8625 7725
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1650 5625 3000 5625 3000 6375 1650 6375 1650 5625
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
2850 7725 2850 6375
|
||||
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
6450 7275 6450 4125 3975 4125 3975 7275 6450 7275
|
||||
2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
9300 7275 9300 4125 6825 4125 6825 7275 9300 7275
|
||||
2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2
|
||||
3975 6540 6465 6525
|
||||
2 1 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2
|
||||
6825 6540 9315 6525
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
5400 7725 5400 7050
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
8025 7725 8025 7050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1050 8925 9375 8925 9375 9900 1050 9900 1050 8925
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2100 4575 3450 4575 3450 5325 2100 5325 2100 4575
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
3225 5325 3225 8325
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
6225 6900 6225 8250
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
8925 6900 8925 8250
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1725 7125 1725 8325
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1 1 2.00 120.00 240.00
|
||||
2850 5850 2850 5025
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
5175 8475 5175 9375
|
||||
2 1 1 3 0 7 50 -1 -1 2.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
1350 7125 1350 9450
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
2325 7725 2325 7200
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1
|
||||
900 3975
|
||||
2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 1
|
||||
9525 9975
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 870 4350 7980 XenBus\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 780 1680 6870 drivers\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 1050 1800 6075 XenStore\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 900 1875 7125 Kernel0\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 960 4875 6975 KernelU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 960 7650 6975 KernelU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 255 1740 4050 8400 Xen Hypervisor\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 585 2325 4950 Xend\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 690 1200 4725 Dom0\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 750 4875 5325 DomU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 750 7650 5325 DomU\001
|
||||
4 0 0 50 -1 0 18 0.0000 4 195 1080 3750 9450 Hardware\001
|
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
@@ -1,101 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1 >libvirt architecture</h1>
|
||||
<p>Currently libvirt supports 2 kind of virtualization, and its
|
||||
internal structure is based on a driver model which simplifies adding new
|
||||
engines:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#Xen">Xen hypervisor</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#QEmu">QEmu and KVM based virtualization</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#drivers">the driver architecture</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a name="Xen" id="Xen">Libvirt Xen support</a>
|
||||
</h3>
|
||||
<p>When running in a Xen environment, programs using libvirt have to execute
|
||||
in "Domain 0", which is the primary Linux OS loaded on the machine. That OS
|
||||
kernel provides most if not all of the actual drivers used by the set of
|
||||
domains. It also runs the Xen Store, a database of information shared by the
|
||||
hypervisor, the kernels, the drivers and the xen daemon. Xend. The xen daemon
|
||||
supervise the control and execution of the sets of domains. The hypervisor,
|
||||
drivers, kernels and daemons communicate though a shared system bus
|
||||
implemented in the hypervisor. The figure below tries to provide a view of
|
||||
this environment:</p>
|
||||
<img src="architecture.gif" alt="The Xen architecture" />
|
||||
<p>The library can be initialized in 2 ways depending on the level of
|
||||
privilege of the embedding program. If it runs with root access,
|
||||
virConnectOpen() can be used, it will use three different ways to connect to
|
||||
the Xen infrastructure:</p>
|
||||
<ul>
|
||||
<li>a connection to the Xen Daemon though an HTTP RPC layer</li>
|
||||
<li>a read/write connection to the Xen Store</li>
|
||||
<li>use Xen Hypervisor calls</li>
|
||||
<li>when used as non-root libvirt connect to a proxy daemon running
|
||||
as root and providing read-only support</li>
|
||||
</ul>
|
||||
<p>The library will usually interact with the Xen daemon for any operation
|
||||
changing the state of the system, but for performance and accuracy reasons
|
||||
may talk directly to the hypervisor when gathering state information at
|
||||
least when possible (i.e. when the running program using libvirt has root
|
||||
privilege access).</p>
|
||||
<p>If it runs without root access virConnectOpenReadOnly() should be used to
|
||||
connect to initialize the library. It will then fork a libvirt_proxy
|
||||
program running as root and providing read_only access to the API, this is
|
||||
then only useful for reporting and monitoring.</p>
|
||||
<h3>
|
||||
<a name="QEmu" id="QEmu">Libvirt QEmu and KVM support</a>
|
||||
</h3>
|
||||
<p>The model for QEmu and KVM is completely similar, basically KVM is based
|
||||
on QEmu for the process controlling a new domain, only small details differs
|
||||
between the two. In both case the libvirt API is provided by a controlling
|
||||
process forked by libvirt in the background and which launch and control the
|
||||
QEmu or KVM process. That program called libvirt_qemud talks though a specific
|
||||
protocol to the library, and connects to the console of the QEmu process in
|
||||
order to control and report on its status. Libvirt tries to expose all the
|
||||
emulations models of QEmu, the selection is done when creating the new
|
||||
domain, by specifying the architecture and machine type targeted.</p>
|
||||
<p>The code controlling the QEmu process is available in the
|
||||
<code>qemud/</code> directory.</p>
|
||||
<h3>
|
||||
<a name="drivers" id="drivers">the driver based architecture</a>
|
||||
</h3>
|
||||
<p>As the previous section explains, libvirt can communicate using different
|
||||
channels with the current hypervisor, and should also be able to use
|
||||
different kind of hypervisor. To simplify the internal design, code, ease
|
||||
maintenance and simplify the support of other virtualization engine the
|
||||
internals have been structured as one core component, the libvirt.c module
|
||||
acting as a front-end for the library API and a set of hypervisor drivers
|
||||
defining a common set of routines. That way the Xen Daemon access, the Xen
|
||||
Store one, the Hypervisor hypercall are all isolated in separate C modules
|
||||
implementing at least a subset of the common operations defined by the
|
||||
drivers present in driver.h:</p>
|
||||
<ul>
|
||||
<li>xend_internal: implements the driver functions though the Xen
|
||||
Daemon</li>
|
||||
<li>xs_internal: implements the subset of the driver available though the
|
||||
Xen Store</li>
|
||||
<li>xen_internal: provide the implementation of the functions possible via
|
||||
direct hypervisor access</li>
|
||||
<li>proxy_internal: provide read-only Xen access via a proxy, the proxy code
|
||||
is in the <code>proxy/</code>directory.</li>
|
||||
<li>xm_internal: provide support for Xen defined but not running
|
||||
domains.</li>
|
||||
<li>qemu_internal: implement the driver functions for QEmu and
|
||||
KVM virtualization engines. It also uses a qemud/ specific daemon
|
||||
which interacts with the QEmu process to implement libvirt API.</li>
|
||||
<li>test: this is a test driver useful for regression tests of the
|
||||
front-end part of libvirt.</li>
|
||||
</ul>
|
||||
<p>Note that a given driver may only implement a subset of those functions,
|
||||
(for example saving a Xen domain state to disk and restoring it is only
|
||||
possible though the Xen Daemon), in that case the driver entry points for
|
||||
unsupported functions are initialized to NULL.</p>
|
||||
<p></p>
|
||||
</body>
|
||||
</html>
|
@@ -1,50 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Network management architecture</h1>
|
||||
|
||||
<h2>Architecture illustration</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>Logical diagram</h3>
|
||||
|
||||
<p class="image">
|
||||
<img src="libvirt-net-logical.png" alt="Logical network architecture"/>
|
||||
</p>
|
||||
|
||||
<h3>Physical diagram</h3>
|
||||
|
||||
<p class="image">
|
||||
<img src="libvirt-net-physical.png" alt="Physical network architecture"/>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Node device management architecture</h1>
|
||||
</body>
|
||||
</html>
|
@@ -1,30 +0,0 @@
|
||||
<html>
|
||||
<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>
|
@@ -1,187 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1 >Access control</h1>
|
||||
<p>
|
||||
When connecting to libvirt, some connections may require client
|
||||
authentication before allowing use of the APIs. The set of possible
|
||||
authentication mechanisms is administrator controlled, independent
|
||||
of applications using libvirt.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#ACL_server_config">Server configuration</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ACL_server_unix_perms">UNIX socket permissions/group</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ACL_server_polkit">UNIX socket PolicyKit auth</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ACL_server_username">Username/password auth</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ACL_server_kerberos">Kerberos auth</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3><a name="ACL_server_config">Server configuration</a></h3>
|
||||
<p>
|
||||
The libvirt daemon allows the administrator to choose the authentication
|
||||
mechanisms used for client connections on each network socket independently.
|
||||
This is primarily controlled via the libvirt daemon master config file in
|
||||
<code>/etc/libvirt/libvirtd.conf</code>. Each of the libvirt sockets can
|
||||
have its authentication mechanism configured independently. There is
|
||||
currently a choice of <code>none</code>, <code>polkit</code>, and <code>sasl</code>.
|
||||
The SASL scheme can be further configured to choose between a large
|
||||
number of different mechanisms.
|
||||
</p>
|
||||
<h3><a name="ACL_server_unix_perms">UNIX socket permissions/group</a></h3>
|
||||
<p>
|
||||
If libvirt does not contain support for PolicyKit, then access control for
|
||||
the UNIX domain socket is done using traditional file user/group ownership
|
||||
and permissions. There are 2 sockets, one for full read-write access, the
|
||||
other for read-only access. The RW socket will be restricted (mode 0700) to
|
||||
only allow the <code>root</code> user to connect. The read-only socket will
|
||||
be open access (mode 0777) to allow any user to connect.
|
||||
</p>
|
||||
<p>
|
||||
To allow non-root users greater access, the <code>libvirtd.conf</code> file
|
||||
can be edited to change the permissions via the <code>unix_sock_rw_perms</code>,
|
||||
config parameter and to set a user group via the <code>unix_sock_group</code>
|
||||
parameter. For example, setting the former to mode <code>0770</code> and the
|
||||
latter <code>wheel</code> would let any user in the wheel group connect to
|
||||
the libvirt daemon.
|
||||
</p>
|
||||
<h3><a name="ACL_server_polkit">UNIX socket PolicyKit auth</a></h3>
|
||||
<p>
|
||||
If libvirt contains support for PolicyKit, then access control options are
|
||||
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
|
||||
RW daemon socket will require any application running in the current desktop
|
||||
session to authenticate using the user's password. This is akin to <code>sudo</code>
|
||||
auth, but does not require that the client application ultimately run as root.
|
||||
Default policy will still allow any application to connect to the RO socket.
|
||||
</p>
|
||||
<p>
|
||||
The default policy can be overridden by the administrator using the PolicyKit
|
||||
master configuration file in <code>/etc/PolicyKit/PolicyKit.conf</code>. The
|
||||
<code>PolicyKit.conf(5)</code> manual page provides details on the syntax
|
||||
available. The two libvirt daemon actions available are named <code>org.libvirt.unix.monitor</code>
|
||||
for the RO socket, and <code>org.libvirt.unix.manage</code> for the RW socket.
|
||||
</p>
|
||||
<p>
|
||||
As an example, to allow a user <code>fred</code>full access to the RW socket,
|
||||
while requiring <code>joe</code> to authenticate with the admin password,
|
||||
would require adding the following snippet to <code>PolicyKit.conf</code>.
|
||||
</p>
|
||||
<pre>
|
||||
<match action="org.libvirt.unix.manage">
|
||||
<match user="fred">
|
||||
<return result="yes"/>
|
||||
</match>
|
||||
</match>
|
||||
<match action="org.libvirt.unix.manage">
|
||||
<match user="joe">
|
||||
<return result="auth_admin"/>
|
||||
</match>
|
||||
</match>
|
||||
</pre>
|
||||
<h3><a name="ACL_server_username">Username/password auth</a></h3>
|
||||
<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>
|
||||
command. When running this command it is important to tell it that the appname is <code>libvirt</code>.
|
||||
As an example, to add a user <code>fred</code>, run
|
||||
</p>
|
||||
<pre>
|
||||
# saslpasswd2 -a libvirt fred
|
||||
Password: xxxxxx
|
||||
Again (for verification): xxxxxx
|
||||
</pre>
|
||||
<p>
|
||||
To see a list of all accounts the <code>sasldblistusers2</code> command can be used.
|
||||
This command expects to be given the path to the libvirt user database, which is kept
|
||||
in <code>/etc/libvirt/passwd.db</code>
|
||||
</p>
|
||||
<pre>
|
||||
# sasldblistusers2 -f /etc/libvirt/passwd.db
|
||||
fred@t60wlan.home.berrange.com: userPassword
|
||||
</pre>
|
||||
<p>
|
||||
Finally, to disable a user's access, the <code>saslpasswd2</code> command can be used
|
||||
again:
|
||||
</p>
|
||||
<pre>
|
||||
# saslpasswd2 -a libvirt -d fred
|
||||
</pre>
|
||||
<h3><a name="ACL_server_kerberos">Kerberos auth</a></h3>
|
||||
<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. 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>. 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
|
||||
may be necessary to install a sub-package such as <code>cyrus-sasl-gssapi</code>.
|
||||
To check whether the Kerberos plugin is installed run the <code>pluginviewer</code>
|
||||
program and verify that <code>gssapi</code> is listed,eg:
|
||||
</p>
|
||||
<pre>
|
||||
# pluginviewer
|
||||
...snip...
|
||||
Plugin "gssapiv2" [loaded], API version: 4
|
||||
SASL mechanism: GSSAPI, best SSF: 56
|
||||
security flags: NO_ANONYMOUS|NO_PLAINTEXT|NO_ACTIVE|PASS_CREDENTIALS|MUTUAL_AUTH
|
||||
features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN
|
||||
</pre>
|
||||
<p>
|
||||
Next it is necessary for the administrator of the Kerberos realm to issue a principle
|
||||
for the libvirt server. There needs to be one principle per host running the libvirt
|
||||
daemon. The principle should be named <code>libvirt/full.hostname@KERBEROS.REALM</code>.
|
||||
This is typically done by running the <code>kadmin.local</code> command on the Kerberos
|
||||
server, though some Kerberos servers have alternate ways of setting up service principles.
|
||||
Once created, the principle should be exported to a keytab, copied to the host running
|
||||
the libvirt daemon and placed in <code>/etc/libvirt/krb5.tab</code>
|
||||
</p>
|
||||
<pre>
|
||||
# kadmin.local
|
||||
kadmin.local: add_principal libvirt/foo.example.com
|
||||
Enter password for principal "libvirt/foo.example.com@EXAMPLE.COM":
|
||||
Re-enter password for principal "libvirt/foo.example.com@EXAMPLE.COM":
|
||||
Principal "libvirt/foo.example.com@EXAMPLE.COM" created.
|
||||
|
||||
kadmin.local: ktadd -k /root/libvirt-foo-example.tab libvirt/foo.example.com@EXAMPLE.COM
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type ArcFour with HMAC/md5 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type DES with HMAC/sha1 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
Entry for principal libvirt/foo.example.com@EXAMPLE.COM with kvno 4, encryption type DES cbc mode with RSA-MD5 added to keytab WRFILE:/root/libvirt-foo-example.tab.
|
||||
|
||||
kadmin.local: quit
|
||||
|
||||
# scp /root/libvirt-foo-example.tab root@foo.example.com:/etc/libvirt/krb5.tab
|
||||
# rm /root/libvirt-foo-example.tab
|
||||
</pre>
|
||||
<p>
|
||||
Any client application wishing to connect to a Kerberos enabled libvirt server
|
||||
merely needs to run <code>kinit</code> to gain a user principle. This may well
|
||||
be done automatically when a user logs into a desktop session, if PAM is setup
|
||||
to authenticate against Kerberos.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@@ -1,30 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1 >Bindings for other languages</h1>
|
||||
<p>Libvirt comes with bindings to support other languages than
|
||||
pure <strong>C</strong>. First the headers embeds the necessary declarations to
|
||||
allow direct access from <strong>C++</strong> code, but also we have bindings for
|
||||
higher level kind of languages:</p>
|
||||
<ul>
|
||||
<li><strong>Python</strong>: Libvirt comes with direct support for the Python language
|
||||
(just make sure you installed the libvirt-python package if not
|
||||
compiling from sources). See below for more information about
|
||||
using libvirt with python</li>
|
||||
<li><strong>Perl</strong>: Daniel Berrange provides <a href="http://search.cpan.org/dist/Sys-Virt/">bindings for
|
||||
Perl</a>.</li>
|
||||
<li><strong>OCaml</strong>: Richard Jones supplies <a href="http://libvirt.org/ocaml/">bindings for OCaml</a>.</li>
|
||||
<li><strong>Ruby</strong>: David Lutterkort provides <a href="http://libvirt.org/ruby/">bindings for Ruby</a>.</li>
|
||||
<li><strong>Java</strong>: Daniel Veillard maintains <a href="java.html">Java bindings</a>.</li>
|
||||
<li><strong>C#</strong>: Jaromír Červenka maintains <a href="http://svn.i-tux.cz/listing.php?repname=SharpLibVirt">C# bindings here</a>.</li>
|
||||
</ul>
|
||||
<p>For information on using libvirt on <strong>Windows</strong>
|
||||
<a href="windows.html">please see the Windows
|
||||
support page</a>.
|
||||
</p>
|
||||
<p>Support, requests or help for libvirt bindings are welcome on
|
||||
the <a href="https://www.redhat.com/mailman/listinfo/libvir-list/">mailing
|
||||
list</a>, as usual try to provide enough background information
|
||||
and make sure you use recent version, see the <a href="bugs.html">help
|
||||
page</a>.</p>
|
||||
</body>
|
||||
</html>
|
@@ -1,82 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h1>Bug reporting</h1>
|
||||
|
||||
<p>
|
||||
The <a href="http://bugzilla.redhat.com">Red Hat Bugzilla Server</a>
|
||||
should be used to report bugs and request features against libvirt.
|
||||
Before submitting a ticket, check the existing tickets to see if
|
||||
the bug/feature is already tracked.
|
||||
</p>
|
||||
|
||||
<h2>General libvirt bug reports</h2>
|
||||
|
||||
<p>
|
||||
If you are using official libvirt binaries from a Linux distribution
|
||||
check below for distribution specific bug reporting policies first.
|
||||
For general libvirt bug reports, from self-built releases, CVS snapshots
|
||||
and any other non-distribution supported builds, enter tickets under
|
||||
the <code>Virtualization Tools</code> product and the <code>libvirt</code>
|
||||
component.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://bugzilla.redhat.com/buglist.cgi?component=libvirt&product=Virtualization%20Tools">View libvirt tickets</a></li>
|
||||
<li><a href="http://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Virtualization%20Tools&component=libvirt">New libvirt ticket</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Linux Distribution specific bug reports</h2>
|
||||
<ul>
|
||||
<li>
|
||||
If you are using official binaries from a <strong>Fedora distribution</strong>, enter
|
||||
tickets against the <code>Fedora</code> product and the <code>libvirt</code>
|
||||
component.
|
||||
<ul>
|
||||
<li><a href="http://bugzilla.redhat.com/buglist.cgi?component=libvirt&product=Fedora">View Fedora libvirt tickets</a></li>
|
||||
<li><a href="http://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Fedora&component=libvirt">New Fedora libvirt ticket</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
If you are using official binaries from <strong>Red Hat Enterprise Linux distribution</strong>,
|
||||
tickets against the <code>Red Hat Enterprise Linux 5</code> product and
|
||||
the <code>libvirt</code> component.
|
||||
<ul>
|
||||
<li><a href="http://bugzilla.redhat.com/buglist.cgi?component=libvirt&product=Red%20Hat%20Enterprise%20Linux%205">View Red Hat Enterprise Linux libvirt tickets</a></li>
|
||||
<li><a href="http://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Red%20Hat%20Enterprise%20Linux%205&component=libvirt">New Red Hat Enterprise Linux libvirt ticket</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
If you are using official binaries from another Linux distribution first
|
||||
follow their own bug reporting guidelines.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>How to file high quality bug reports</h2>
|
||||
|
||||
<p>
|
||||
To increase the likelihood of your bug report being addressed it is
|
||||
important to provide as much information as possible. When filing
|
||||
libvirt bugs use this checklist to see if you are providing enough
|
||||
information:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>The version number of the libvirt build, or date of the CVS
|
||||
checkout</li>
|
||||
<li>The hardware architecture being used</li>
|
||||
<li>The name of the hypervisor (Xen, QEMU, KVM)</li>
|
||||
<li>The XML config of the guest domain if relevant</li>
|
||||
<li>For Xen hypervisor, the XenD logfile from /var/log/xen</li>
|
||||
<li>For QEMU/KVM, the domain logfile from /var/log/libvirt/qemu</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
If requesting a new feature attach any available patch to the ticket
|
||||
and also email the patch to the libvirt mailing list for discussion
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Contacting the development team</h1>
|
||||
|
||||
<h2>Mailing list</h2>
|
||||
|
||||
<p>
|
||||
There is a mailing-list <a href="mailto:libvir-list@redhat.com">libvir-list@redhat.com</a> for libvirt,
|
||||
with an <a href="https://www.redhat.com/archives/libvir-list/">on-line archive</a>.
|
||||
Please subscribe to this list before posting by visiting the
|
||||
<a href="https://www.redhat.com/mailman/listinfo/libvir-list">associated Web</a>
|
||||
page and follow the instructions. Patches with explanations and provided as
|
||||
attachments are really appreciated and will be discussed on the mailing list.
|
||||
If possible generate the patches by using <code>cvs diff -up</code> in a CVS
|
||||
checkout.
|
||||
</p>
|
||||
|
||||
<h2>IRC discussion</h2>
|
||||
|
||||
<p>
|
||||
Some of the libvirt developers may be found on IRC on the <a href="http://oftc.net">OFTC IRC</a>
|
||||
network. Use the settings:
|
||||
</p>
|
||||
<ul>
|
||||
<li>server: irc.oftc.net</li>
|
||||
<li>port: 6667 (the usual IRC port)</li>
|
||||
<li>channel: #virt</li>
|
||||
</ul>
|
||||
<p>
|
||||
NB There is no guarantee that someone will be watching or able to reply
|
||||
promptly, so use the mailing-list if you don't get an answer on the IRC
|
||||
channel.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,46 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Deployment</h1>
|
||||
|
||||
<h2>Pre-packaged releases</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>Self-built releases</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>Built from CVS / GIT</h2>
|
||||
|
||||
<p>
|
||||
When building from CVS 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>
|
4
docs/devhelp/.gitignore
vendored
4
docs/devhelp/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
libvirt.devhelp
|
||||
*.html
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user