mirror of
				https://gitlab.com/libvirt/libvirt.git
				synced 2025-11-04 12:24:23 +03:00 
			
		
		
		
	Compare commits
	
		
			10 Commits
		
	
	
		
			v6.1.0-rc2
			...
			v1.2.17-ma
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					49fa383bb0 | ||
| 
						 | 
					08acad56ce | ||
| 
						 | 
					4268b1f102 | ||
| 
						 | 
					d055989083 | ||
| 
						 | 
					98242f94cd | ||
| 
						 | 
					a3ee6885d9 | ||
| 
						 | 
					a0080cbc17 | ||
| 
						 | 
					45e32f2ea5 | ||
| 
						 | 
					02b9226ee3 | ||
| 
						 | 
					ea16e3ef07 | 
@@ -1,38 +0,0 @@
 | 
			
		||||
-I@abs_top_builddir@
 | 
			
		||||
-I@abs_top_srcdir@
 | 
			
		||||
-I@abs_top_builddir@/include
 | 
			
		||||
-I@abs_top_srcdir@/include
 | 
			
		||||
-I@abs_top_builddir@/src
 | 
			
		||||
-I@abs_top_srcdir@/src
 | 
			
		||||
-I@abs_top_builddir@/src/access
 | 
			
		||||
-I@abs_top_srcdir@/src/access
 | 
			
		||||
-I@abs_top_builddir@/src/admin
 | 
			
		||||
-I@abs_top_srcdir@/src/admin
 | 
			
		||||
-I@abs_top_builddir@/src/bhyve
 | 
			
		||||
-I@abs_top_srcdir@/src/bhyve
 | 
			
		||||
-I@abs_top_builddir@/src/conf
 | 
			
		||||
-I@abs_top_srcdir@/src/conf
 | 
			
		||||
-I@abs_top_builddir@/src/libxl
 | 
			
		||||
-I@abs_top_srcdir@/src/libxl
 | 
			
		||||
-I@abs_top_builddir@/src/locking
 | 
			
		||||
-I@abs_top_srcdir@/src/locking
 | 
			
		||||
-I@abs_top_builddir@/src/logging
 | 
			
		||||
-I@abs_top_srcdir@/src/logging
 | 
			
		||||
-I@abs_top_builddir@/src/lxc
 | 
			
		||||
-I@abs_top_srcdir@/src/lxc
 | 
			
		||||
-I@abs_top_builddir@/src/qemu
 | 
			
		||||
-I@abs_top_srcdir@/src/qemu
 | 
			
		||||
-I@abs_top_builddir@/src/remote
 | 
			
		||||
-I@abs_top_srcdir@/src/remote
 | 
			
		||||
-I@abs_top_builddir@/src/rpc
 | 
			
		||||
-I@abs_top_srcdir@/src/rpc
 | 
			
		||||
-I@abs_top_builddir@/src/secret
 | 
			
		||||
-I@abs_top_srcdir@/src/secret
 | 
			
		||||
-I@abs_top_builddir@/src/security
 | 
			
		||||
-I@abs_top_srcdir@/src/security
 | 
			
		||||
-I@abs_top_builddir@/src/util
 | 
			
		||||
-I@abs_top_srcdir@/src/util
 | 
			
		||||
-I@abs_top_builddir@/src/vmx
 | 
			
		||||
-I@abs_top_srcdir@/src/vmx
 | 
			
		||||
-I@abs_top_builddir@/src/xenconfig
 | 
			
		||||
-I@abs_top_srcdir@/src/xenconfig
 | 
			
		||||
							
								
								
									
										1
									
								
								.ctags
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								.ctags
									
									
									
									
									
								
							@@ -3,4 +3,3 @@
 | 
			
		||||
--exclude=*.html
 | 
			
		||||
--exclude=*.html.in
 | 
			
		||||
--langmap=c:+.h.in
 | 
			
		||||
--c-kinds=+p
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
../.ctags
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
# EditorConfig is a file format and collection of text editor plugins
 | 
			
		||||
# for maintaining consistent coding styles between different editors
 | 
			
		||||
# and IDEs. Most popular editors support this either natively or via
 | 
			
		||||
# plugin.
 | 
			
		||||
#
 | 
			
		||||
# Check https://editorconfig.org for details.
 | 
			
		||||
 | 
			
		||||
root = true
 | 
			
		||||
 | 
			
		||||
[*]
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
charset = utf-8
 | 
			
		||||
 | 
			
		||||
[*.c]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[*.{rng,xml}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
							
								
								
									
										217
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										217
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,40 +1,203 @@
 | 
			
		||||
# vim related ignores
 | 
			
		||||
*.swp
 | 
			
		||||
.lvimrc
 | 
			
		||||
 | 
			
		||||
# emacs related ignores
 | 
			
		||||
*#*#
 | 
			
		||||
*.#*#
 | 
			
		||||
.#*
 | 
			
		||||
*~
 | 
			
		||||
 | 
			
		||||
# autotools related ignores
 | 
			
		||||
!/m4/virt-*.m4
 | 
			
		||||
*.a
 | 
			
		||||
*.cov
 | 
			
		||||
*.exe
 | 
			
		||||
*.exe.manifest
 | 
			
		||||
*.gcda
 | 
			
		||||
*.gcno
 | 
			
		||||
*.gcov
 | 
			
		||||
*.html
 | 
			
		||||
*.i
 | 
			
		||||
*.la
 | 
			
		||||
*.lo
 | 
			
		||||
*.loT
 | 
			
		||||
*.o
 | 
			
		||||
*.orig
 | 
			
		||||
*.pem
 | 
			
		||||
*.pyc
 | 
			
		||||
*.rej
 | 
			
		||||
*.s
 | 
			
		||||
*.swp
 | 
			
		||||
*~
 | 
			
		||||
.#*
 | 
			
		||||
.deps
 | 
			
		||||
.dirstamp
 | 
			
		||||
.gdb_history
 | 
			
		||||
.git
 | 
			
		||||
.git-module-status
 | 
			
		||||
.libs
 | 
			
		||||
.lvimrc
 | 
			
		||||
.memdump
 | 
			
		||||
.sc-start-sc_*
 | 
			
		||||
/ABOUT-NLS
 | 
			
		||||
/AUTHORS
 | 
			
		||||
/ChangeLog
 | 
			
		||||
/GNUmakefile
 | 
			
		||||
/INSTALL
 | 
			
		||||
/NEWS
 | 
			
		||||
/aclocal.m4
 | 
			
		||||
/autom4te.cache
 | 
			
		||||
/build-aux/compile
 | 
			
		||||
/build-aux/config.guess
 | 
			
		||||
/build-aux/config.sub
 | 
			
		||||
/build-aux/depcomp
 | 
			
		||||
/build-aux/install-sh
 | 
			
		||||
/build-aux/ltmain.sh
 | 
			
		||||
/build-aux/missing
 | 
			
		||||
/build-aux/test-driver
 | 
			
		||||
/build-aux
 | 
			
		||||
/build-aux/
 | 
			
		||||
/build/
 | 
			
		||||
/confdefs.h
 | 
			
		||||
/config.cache
 | 
			
		||||
/config.guess
 | 
			
		||||
/config.h
 | 
			
		||||
/config.h.in
 | 
			
		||||
/config.log
 | 
			
		||||
/config.rpath
 | 
			
		||||
/config.status
 | 
			
		||||
/config.sub
 | 
			
		||||
/configure
 | 
			
		||||
/configure.lineno
 | 
			
		||||
/conftest.*
 | 
			
		||||
/daemon/*_dispatch.h
 | 
			
		||||
/daemon/libvirt_qemud
 | 
			
		||||
/daemon/libvirtd
 | 
			
		||||
/daemon/libvirtd*.logrotate
 | 
			
		||||
/daemon/libvirtd.8
 | 
			
		||||
/daemon/libvirtd.8.in
 | 
			
		||||
/daemon/libvirtd.init
 | 
			
		||||
/daemon/libvirtd.pod
 | 
			
		||||
/daemon/libvirtd.policy
 | 
			
		||||
/daemon/libvirtd.service
 | 
			
		||||
/daemon/libvirtd.socket
 | 
			
		||||
/daemon/test_libvirtd.aug
 | 
			
		||||
/docs/aclperms.htmlinc
 | 
			
		||||
/docs/apibuild.py.stamp
 | 
			
		||||
/docs/devhelp/libvirt.devhelp
 | 
			
		||||
/docs/hvsupport.html.in
 | 
			
		||||
/docs/libvirt-admin-*.xml
 | 
			
		||||
/docs/libvirt-api.xml
 | 
			
		||||
/docs/libvirt-lxc-*.xml
 | 
			
		||||
/docs/libvirt-qemu-*.xml
 | 
			
		||||
/docs/libvirt-refs.xml
 | 
			
		||||
/docs/search.php
 | 
			
		||||
/docs/todo.html.in
 | 
			
		||||
/examples/object-events/event-test
 | 
			
		||||
/examples/dominfo/info1
 | 
			
		||||
/examples/domsuspend/suspend
 | 
			
		||||
/examples/dommigrate/dommigrate
 | 
			
		||||
/examples/domtop/domtop
 | 
			
		||||
/examples/hellolibvirt/hellolibvirt
 | 
			
		||||
/examples/openauth/openauth
 | 
			
		||||
/gnulib/lib/*
 | 
			
		||||
/gnulib/m4/*
 | 
			
		||||
/gnulib/tests/*
 | 
			
		||||
/include/libvirt/libvirt.h
 | 
			
		||||
/libtool
 | 
			
		||||
/libvirt-*.tar.gz
 | 
			
		||||
/libvirt-[0-9]*
 | 
			
		||||
/libvirt*.pc
 | 
			
		||||
/libvirt.spec
 | 
			
		||||
/ltconfig
 | 
			
		||||
/ltmain.sh
 | 
			
		||||
/m4/*
 | 
			
		||||
/maint.mk
 | 
			
		||||
/mingw-libvirt.spec
 | 
			
		||||
/mkinstalldirs
 | 
			
		||||
/po/*
 | 
			
		||||
/proxy/
 | 
			
		||||
/python/
 | 
			
		||||
/run
 | 
			
		||||
/sc_*
 | 
			
		||||
/src/.*.stamp
 | 
			
		||||
/src/*.pc
 | 
			
		||||
/src/access/org.libvirt.api.policy
 | 
			
		||||
/src/access/viraccessapicheck.c
 | 
			
		||||
/src/access/viraccessapicheck.h
 | 
			
		||||
/src/access/viraccessapichecklxc.c
 | 
			
		||||
/src/access/viraccessapichecklxc.h
 | 
			
		||||
/src/access/viraccessapicheckqemu.c
 | 
			
		||||
/src/access/viraccessapicheckqemu.h
 | 
			
		||||
/src/admin/admin_client.h
 | 
			
		||||
/src/admin/admin_protocol.[ch]
 | 
			
		||||
/src/esx/*.generated.*
 | 
			
		||||
/src/hyperv/*.generated.*
 | 
			
		||||
/src/libvirt*.def
 | 
			
		||||
/src/libvirt.syms
 | 
			
		||||
/src/libvirt_access.syms
 | 
			
		||||
/src/libvirt_access.xml
 | 
			
		||||
/src/libvirt_access_lxc.syms
 | 
			
		||||
/src/libvirt_access_lxc.xml
 | 
			
		||||
/src/libvirt_access_qemu.syms
 | 
			
		||||
/src/libvirt_access_qemu.xml
 | 
			
		||||
/src/libvirt_*.stp
 | 
			
		||||
/src/libvirt_*helper
 | 
			
		||||
/src/libvirt_*probes.h
 | 
			
		||||
/src/libvirt_lxc
 | 
			
		||||
/src/locking/libxl-lockd.conf
 | 
			
		||||
/src/locking/libxl-sanlock.conf
 | 
			
		||||
/src/locking/lock_daemon_dispatch_stubs.h
 | 
			
		||||
/src/locking/lock_protocol.[ch]
 | 
			
		||||
/src/locking/qemu-lockd.conf
 | 
			
		||||
/src/locking/qemu-sanlock.conf
 | 
			
		||||
/src/locking/test_libvirt_sanlock.aug
 | 
			
		||||
/src/lxc/lxc_controller_dispatch.h
 | 
			
		||||
/src/lxc/lxc_monitor_dispatch.h
 | 
			
		||||
/src/lxc/lxc_monitor_protocol.c
 | 
			
		||||
/src/lxc/lxc_monitor_protocol.h
 | 
			
		||||
/src/lxc/lxc_protocol.[ch]
 | 
			
		||||
/src/lxc/test_libvirtd_lxc.aug
 | 
			
		||||
/src/qemu/test_libvirtd_qemu.aug
 | 
			
		||||
/src/remote/*_client_bodies.h
 | 
			
		||||
/src/remote/*_protocol.[ch]
 | 
			
		||||
/src/rpc/virkeepaliveprotocol.[ch]
 | 
			
		||||
/src/rpc/virnetprotocol.[ch]
 | 
			
		||||
/src/test_libvirt*.aug
 | 
			
		||||
/src/test_virtlockd.aug
 | 
			
		||||
/src/util/virkeymaps.h
 | 
			
		||||
/src/virt-aa-helper
 | 
			
		||||
/src/virtlockd
 | 
			
		||||
/src/virtlockd.8
 | 
			
		||||
/src/virtlockd.8.in
 | 
			
		||||
/src/virtlockd.init
 | 
			
		||||
/tests/*.log
 | 
			
		||||
/tests/*.pid
 | 
			
		||||
/tests/*.trs
 | 
			
		||||
/tests/commandhelper
 | 
			
		||||
/tests/*test
 | 
			
		||||
!/tests/*schematest
 | 
			
		||||
!/tests/virt-aa-helper-test
 | 
			
		||||
/tests/objectlocking
 | 
			
		||||
/tests/objectlocking-files.txt
 | 
			
		||||
/tests/objectlocking.cm[ix]
 | 
			
		||||
/tests/reconnect
 | 
			
		||||
/tests/ssh
 | 
			
		||||
/tests/test_conf
 | 
			
		||||
/tools/*.[18]
 | 
			
		||||
/tools/libvirt-guests.init
 | 
			
		||||
/tools/libvirt-guests.service
 | 
			
		||||
/tools/libvirt-guests.sh
 | 
			
		||||
/tools/virt-login-shell
 | 
			
		||||
/tools/virsh
 | 
			
		||||
/tools/virsh-*-edit.c
 | 
			
		||||
/tools/virt-*-validate
 | 
			
		||||
/tools/virt-sanlock-cleanup
 | 
			
		||||
/tools/wireshark/src/plugin.c
 | 
			
		||||
/tools/wireshark/src/libvirt
 | 
			
		||||
/update.log
 | 
			
		||||
GPATH
 | 
			
		||||
GRTAGS
 | 
			
		||||
GTAGS
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
 | 
			
		||||
# git related ignores
 | 
			
		||||
*.rej
 | 
			
		||||
*.orig
 | 
			
		||||
.git-module-status
 | 
			
		||||
 | 
			
		||||
# libvirt related ignores
 | 
			
		||||
/build/
 | 
			
		||||
/ci/scratch/
 | 
			
		||||
TAGS
 | 
			
		||||
coverage
 | 
			
		||||
cscope.files
 | 
			
		||||
cscope.in.out
 | 
			
		||||
cscope.out
 | 
			
		||||
cscope.po.out
 | 
			
		||||
results.log
 | 
			
		||||
stamp-h
 | 
			
		||||
stamp-h.in
 | 
			
		||||
stamp-h1
 | 
			
		||||
tags
 | 
			
		||||
!/gnulib/lib/Makefile.am
 | 
			
		||||
!/gnulib/tests/Makefile.am
 | 
			
		||||
!/m4/virt-*.m4
 | 
			
		||||
!/po/*.po
 | 
			
		||||
!/po/POTFILES.in
 | 
			
		||||
!/po/libvirt.pot
 | 
			
		||||
 
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
.job_template: &job_definition
 | 
			
		||||
  script:
 | 
			
		||||
    - mkdir build
 | 
			
		||||
    - cd build
 | 
			
		||||
    - ../autogen.sh $CONFIGURE_OPTS || (cat config.log && exit 1)
 | 
			
		||||
    - make -j $(getconf _NPROCESSORS_ONLN)
 | 
			
		||||
 | 
			
		||||
# We could run every arch on every versions, but it is a little
 | 
			
		||||
# overkill. Instead we split jobs evenly across 9, 10 and sid
 | 
			
		||||
# to achieve reasonable cross-coverage.
 | 
			
		||||
 | 
			
		||||
debian-9-cross-armv6l:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-9-cross-armv6l:latest
 | 
			
		||||
 | 
			
		||||
debian-9-cross-mips64el:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-9-cross-mips64el:latest
 | 
			
		||||
 | 
			
		||||
debian-9-cross-mips:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-9-cross-mips:latest
 | 
			
		||||
 | 
			
		||||
debian-10-cross-aarch64:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-10-cross-aarch64:latest
 | 
			
		||||
 | 
			
		||||
debian-10-cross-ppc64le:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-10-cross-ppc64le:latest
 | 
			
		||||
 | 
			
		||||
debian-10-cross-s390x:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-10-cross-s390x:latest
 | 
			
		||||
 | 
			
		||||
debian-sid-cross-armv7l:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-sid-cross-armv7l:latest
 | 
			
		||||
 | 
			
		||||
debian-sid-cross-i686:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-sid-cross-i686:latest
 | 
			
		||||
 | 
			
		||||
debian-sid-cross-mipsel:
 | 
			
		||||
  <<: *job_definition
 | 
			
		||||
  image: quay.io/libvirt/buildenv-libvirt-debian-sid-cross-mipsel:latest
 | 
			
		||||
							
								
								
									
										6
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,3 @@
 | 
			
		||||
[submodule "keycodemapdb"]
 | 
			
		||||
	path = src/keycodemapdb
 | 
			
		||||
	url = https://gitlab.com/keycodemap/keycodemapdb.git
 | 
			
		||||
[submodule "gnulib"]
 | 
			
		||||
	path = .gnulib
 | 
			
		||||
	url = git://git.sv.gnu.org/gnulib.git
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
[gitpublishprofile "default"]
 | 
			
		||||
base = master
 | 
			
		||||
to = libvir-list@redhat.com
 | 
			
		||||
prefix = libvirt PATCH
 | 
			
		||||
							
								
								
									
										1
									
								
								.gnulib
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								.gnulib
									
									
									
									
									
										Submodule
									
								
							 Submodule .gnulib added at f39477dba7
									
								
							
							
								
								
									
										22
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								.mailmap
									
									
									
									
									
								
							@@ -20,6 +20,7 @@
 | 
			
		||||
<jfehlig@suse.com> <jfehlig@novell.com>
 | 
			
		||||
<jfehlig@suse.com> <jfehlig@linux-ypgk.site>
 | 
			
		||||
<jclift@redhat.com> <justin@salasaga.org>
 | 
			
		||||
<berrange@redhat.com> <dan@berrange.com>
 | 
			
		||||
<soren@linux2go.dk> <soren@canonical.com>
 | 
			
		||||
<cfergeau@redhat.com> <teuf@gnome.org>
 | 
			
		||||
<wency@cn.fujitsu.com> <wency cn fujitsu com>
 | 
			
		||||
@@ -38,15 +39,6 @@
 | 
			
		||||
<zhlcindy@linux.vnet.ibm.com> <zhlcindy@gmail.com>
 | 
			
		||||
<serge.hallyn@canonical.com> <serue@us.ibm.com>
 | 
			
		||||
<pritesh.kothari@sun.com> <Pritesh.Kothari@Sun.COM>
 | 
			
		||||
<cbosdonnat@suse.com> <cedric.bosdonnat@free.fr>
 | 
			
		||||
<mnestratov@virtuozzo.com> <mnestratov@parallels.com>
 | 
			
		||||
<nshirokovskiy@virtuozzo.com> <nshirokovskiy@parallels.com>
 | 
			
		||||
<jyang@redhat.com> <osier@yunify.com>
 | 
			
		||||
<kkoukiou@redhat.com> <k.koukiou@googlemail.com>
 | 
			
		||||
<intrigeri@boum.org> <intrigeri+libvirt@boum.org>
 | 
			
		||||
<fidencio@redhat.com> <fabiano@fidencio.org>
 | 
			
		||||
<shi_lei@massclouds.com> <shilei.massclouds@gmx.com>
 | 
			
		||||
<adrian.brzezinski@eo.pl> <redhat@adrb.pl>
 | 
			
		||||
 | 
			
		||||
# Name consolidation:
 | 
			
		||||
# Preferred author spelling <preferred email>
 | 
			
		||||
@@ -64,16 +56,8 @@ Aurelien Rougemont <beorn@binaries.fr>
 | 
			
		||||
Serge E. Hallyn <serge.hallyn@canonical.com>
 | 
			
		||||
Henrik Persson E <henrik.e.persson@ericsson.com>
 | 
			
		||||
Philipp Hahn <hahn@univention.de>
 | 
			
		||||
Marco Bozzolan <bozzolan@gmail.com>
 | 
			
		||||
Marco Bozzolan <redshift@gmx.com>
 | 
			
		||||
Pritesh Kothari <pritesh.kothari@sun.com>
 | 
			
		||||
Wang Yufei (James) <james.wangyufei@huawei.com>
 | 
			
		||||
Deepak C Shetty <dpkshetty@gmail.com>
 | 
			
		||||
Dave Allan <dallan@redhat.com>
 | 
			
		||||
Richard W.M. Jones <rjones@redhat.com>
 | 
			
		||||
 | 
			
		||||
# Non-trivial consolidation:
 | 
			
		||||
# see git documentation for information about the format
 | 
			
		||||
Daniel P. Berrangé <berrange@redhat.com>
 | 
			
		||||
Daniel P. Berrangé <berrange@redhat.com> <dan@berrange.com>
 | 
			
		||||
Michal Prívozník <mprivozn@redhat.com>
 | 
			
		||||
Michal Prívozník <mprivozn@redhat.com> <miso.privoznik@gmail.com>
 | 
			
		||||
Marco Bozzolan <bozzolan@gmail.com> <redshift@gmx.com>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										116
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,116 +0,0 @@
 | 
			
		||||
sudo: required
 | 
			
		||||
language: generic
 | 
			
		||||
 | 
			
		||||
branches:
 | 
			
		||||
  except:
 | 
			
		||||
    - /^.*-maint$/
 | 
			
		||||
 | 
			
		||||
addons:
 | 
			
		||||
  homebrew:
 | 
			
		||||
    update: true
 | 
			
		||||
    packages:
 | 
			
		||||
      - ccache
 | 
			
		||||
      - rpcgen
 | 
			
		||||
      - xz
 | 
			
		||||
      - yajl
 | 
			
		||||
      - glib
 | 
			
		||||
      - docutils
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
  include:
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="ubuntu-1804"
 | 
			
		||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="centos-7"
 | 
			
		||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="debian-9"
 | 
			
		||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="fedora-31"
 | 
			
		||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="fedora-rawhide"
 | 
			
		||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="fedora-30-cross-mingw32"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE
 | 
			
		||||
    - services:
 | 
			
		||||
        - docker
 | 
			
		||||
      env:
 | 
			
		||||
        - IMAGE="fedora-30-cross-mingw64"
 | 
			
		||||
      script:
 | 
			
		||||
        - make -C ci/ ci-build@$IMAGE
 | 
			
		||||
    - compiler: clang
 | 
			
		||||
      language: c
 | 
			
		||||
      os: osx
 | 
			
		||||
      osx_image: xcode10.3
 | 
			
		||||
      env:
 | 
			
		||||
        - PATH="/usr/local/opt/gettext/bin:/usr/local/opt/ccache/libexec:/usr/local/opt/rpcgen/bin:$PATH"
 | 
			
		||||
        - PKG_CONFIG_PATH="/usr/local/opt/libxml2/lib/pkgconfig"
 | 
			
		||||
      before_script:
 | 
			
		||||
        # Hack to blow away py2
 | 
			
		||||
        - brew link --overwrite python
 | 
			
		||||
      script:
 | 
			
		||||
        # We can't run 'distcheck' or 'syntax-check' because they fail on
 | 
			
		||||
        # macOS, but doing 'install' and 'dist' gives us some useful coverage
 | 
			
		||||
        - mkdir build && cd build
 | 
			
		||||
        - ../autogen.sh --prefix=$(pwd)/install-root && make -j3 && make -j3 install && make -j3 dist
 | 
			
		||||
    - compiler: clang
 | 
			
		||||
      language: c
 | 
			
		||||
      os: osx
 | 
			
		||||
      osx_image: xcode11.3
 | 
			
		||||
      env:
 | 
			
		||||
        - PATH="/usr/local/opt/gettext/bin:/usr/local/opt/ccache/libexec:/usr/local/opt/rpcgen/bin:$PATH"
 | 
			
		||||
        - PKG_CONFIG_PATH="/usr/local/opt/libxml2/lib/pkgconfig"
 | 
			
		||||
      before_script:
 | 
			
		||||
        # Hack to blow away py2
 | 
			
		||||
        - brew link --overwrite python
 | 
			
		||||
      script:
 | 
			
		||||
        # We can't run 'distcheck' or 'syntax-check' because they fail on
 | 
			
		||||
        # macOS, but doing 'install' and 'dist' gives us some useful coverage
 | 
			
		||||
        - mkdir build && cd build
 | 
			
		||||
        - ../autogen.sh --prefix=$(pwd)/install-root && make -j3 && make -j3 install && make -j3 dist
 | 
			
		||||
 | 
			
		||||
git:
 | 
			
		||||
  submodules: true
 | 
			
		||||
 | 
			
		||||
notifications:
 | 
			
		||||
  irc:
 | 
			
		||||
    # The channel name "irc.oftc.net#virt" is encrypted against libvirt/libvirt
 | 
			
		||||
    # to prevent IRC notifications from github forks. This was created using:
 | 
			
		||||
    # $ travis encrypt -r "libvirt/libvirt" "irc.oftc.net#virt"
 | 
			
		||||
    channels:
 | 
			
		||||
      - secure: "hUPdkLxX7nh75+clpnk4U0XLExLfV9DFKSvQSAUtf5JtDNMslj7AeOCf2wcbkNsEhkiF557odTAnov1s5m1w/yaa56zbjFAh5agzqRKya3QjqsrvlBKw/WuN+l82iMNLLeebTgCPAXrbAbGWH8YmYssp/7+eMsnKaVh84EQQNbMCHlLg6ovE26Fs18mZ6J5RC3OPa1vbv+xkdCHvGg/Oyp4K8bpU7RYyimA56jdxI/OfdTH9HxntHYSzykR7hDbyzZhdIlAUyRKReQVjcV5+R8fdDL/1imyGA/88KTztMeKXpZ5Rf+Ss3vYLZb6qsLLegCZ4AU/q0vvbWxjpZGJZoeyrVpfBTZdYGIzmLTMl9GYXXa/gDwFlbvRDiPDG4TIy6GlMUROinj7KRKEHu1fWRYu012ife5OjidxcwrTnz21vYaCv3AKWPpMPxwIzQPkY1hex9uLLX6z+TrAxxDLF+7UzRT9w2RLFBkLYlj2aDVrLAVb/ynRsxDz5CGzC61FSQVft2e308SkGjdn8YxvguCuXv+N70Fu1cvFyh5XYeHb4fbBRo0Ctzaec78leHlQvRGWKJxXDXRkE2lvvBc7YbBNSAYh7Fs8Y+zY7l7rMxvXdrt3nuaNQhe74V3yhxPDAld66qmAn9TYMmaZW2f5/KKKILLbCa0t2MxiAc6L2OI8="
 | 
			
		||||
    on_success: change
 | 
			
		||||
    on_failure: always
 | 
			
		||||
  email:
 | 
			
		||||
    # The list name 'libvirt-ci@redhat.com" is encrypted against libvirt/libvirt
 | 
			
		||||
    # to prevent IRC notifications from github forks. This was created using:
 | 
			
		||||
    # $ travis encrypt -r "libvirt/libvirt" "libvirt-ci@redhat.com"
 | 
			
		||||
    recipients:
 | 
			
		||||
      - secure: "QcU9eP96P0RlDNzVRZl/4sxyydPStGzECrpgJhr2IPB/7pHk23yaBrmUsq9S830tB+jwLGma1IscNB8uf7Sf7WY+cYIpfR8v030OffWnaipo/Gcs0dpnlfURWHjOFQI3RJzGEihsqvbwUFOwsM+3IDyO3qdWaiT6cN2Tj9ROlwYCySSX5YWzLyX7arBZ4lp8ESs7ohQaEwp2cegnMP2oGPJJe4SebvlCDjHZbjkU5aEradwUWnRQDJZWTKknpNLArVFxN2/ixp6f/MGY4DmkHoDweio6mHIPN5zTs5Jt32aiX6wDBa+bBa4v8TCRqzhYkQ63ZZhNV8bY5Uf9ufTdyvt96yIANyakd85b1QpMdAX76IyJi1l0/Uub6DTQZAcq3vK7iPjGeTVSpyoXrqTfGy4JxMjqDoocpWvv8ALX1wrYI/HfN2R2Aepw9jModTimOsebYhJ1yMhSt8qnh5AQNftGKL2JBKoA1LWdU2YJ5fO1bGjKNiVEkGFQTPYFWrYCUY5JcT+s5WCzNeMNm8s9na8liYhGl3WtS3rPr5M8bof+BMsBhG2hQ0loduc94x2GkvyhQZUgRbqrwNR+y4hn+rWFC3hBzzyiAULs43vY/PJ+eBdKEf3VAc0MkhQ8GgXGSA61fR6aXYonroI/WnBVItwDmUnnMfSziZXxk09GLl4="
 | 
			
		||||
@@ -1,43 +0,0 @@
 | 
			
		||||
flags = [
 | 
			
		||||
  '-I@abs_top_builddir@',
 | 
			
		||||
  '-I@abs_top_srcdir@',
 | 
			
		||||
  '-I@abs_top_builddir@/include',
 | 
			
		||||
  '-I@abs_top_srcdir@/include',
 | 
			
		||||
  '-I@abs_top_builddir@/src',
 | 
			
		||||
  '-I@abs_top_srcdir@/src',
 | 
			
		||||
  '-I@abs_top_builddir@/src/access',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/access',
 | 
			
		||||
  '-I@abs_top_builddir@/src/admin',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/admin',
 | 
			
		||||
  '-I@abs_top_builddir@/src/bhyve',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/bhyve',
 | 
			
		||||
  '-I@abs_top_builddir@/src/conf',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/conf',
 | 
			
		||||
  '-I@abs_top_builddir@/src/libxl',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/libxl',
 | 
			
		||||
  '-I@abs_top_builddir@/src/locking',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/locking',
 | 
			
		||||
  '-I@abs_top_builddir@/src/logging',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/logging',
 | 
			
		||||
  '-I@abs_top_builddir@/src/lxc',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/lxc',
 | 
			
		||||
  '-I@abs_top_builddir@/src/qemu',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/qemu',
 | 
			
		||||
  '-I@abs_top_builddir@/src/remote',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/remote',
 | 
			
		||||
  '-I@abs_top_builddir@/src/rpc',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/rpc',
 | 
			
		||||
  '-I@abs_top_builddir@/src/secret',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/secret',
 | 
			
		||||
  '-I@abs_top_builddir@/src/security',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/security',
 | 
			
		||||
  '-I@abs_top_builddir@/src/util',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/util',
 | 
			
		||||
  '-I@abs_top_builddir@/src/vmx',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/vmx',
 | 
			
		||||
  '-I@abs_top_builddir@/src/xenconfig',
 | 
			
		||||
  '-I@abs_top_srcdir@/src/xenconfig',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
def FlagsForFile(filename, **kwargs):
 | 
			
		||||
  return { 'flags': flags, 'do_cache': True }
 | 
			
		||||
							
								
								
									
										15
									
								
								AUTHORS.in
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								AUTHORS.in
									
									
									
									
									
								
							@@ -8,32 +8,27 @@ Daniel Veillard <veillard@redhat.com> or <daniel@veillard.com>
 | 
			
		||||
The primary maintainers and people with commit access rights:
 | 
			
		||||
 | 
			
		||||
Alex Jia <ajia@redhat.com>
 | 
			
		||||
Andrea Bolognani <abologna@redhat.com>
 | 
			
		||||
Cédric Bosdonnat <cbosdonnat@suse.com>
 | 
			
		||||
Christian Ehrhardt <christian.ehrhardt@canonical.com>
 | 
			
		||||
Christophe Fergeau <cfergeau@redhat.com>
 | 
			
		||||
Claudio Bley <claudio.bley@gmail.com>
 | 
			
		||||
Cole Robinson <crobinso@redhat.com>
 | 
			
		||||
Daniel P. Berrangé <berrange@redhat.com>
 | 
			
		||||
Daniel Berrange <berrange@redhat.com>
 | 
			
		||||
Daniel Veillard <veillard@redhat.com>
 | 
			
		||||
Dmitry Guryanov <dguryanov@parallels.com>
 | 
			
		||||
Doug Goldstein <cardoe@gentoo.org>
 | 
			
		||||
Eric Blake <eblake@redhat.com>
 | 
			
		||||
Erik Skultety <eskultet@redhat.com>
 | 
			
		||||
Fabiano Fidêncio <fidencio@redhat.com>
 | 
			
		||||
Gao Feng <gaofeng@cn.fujitsu.com>
 | 
			
		||||
Guido Günther <agx@sigxcpu.org>
 | 
			
		||||
Ján Tomko <jtomko@redhat.com>
 | 
			
		||||
Jim Fehlig <jfehlig@suse.com>
 | 
			
		||||
Jiří Denemark <jdenemar@redhat.com>
 | 
			
		||||
John Ferlan <jferlan@redhat.com>
 | 
			
		||||
Katerina Koukiou <kkoukiou@redhat.com>
 | 
			
		||||
Laine Stump <laine@redhat.com>
 | 
			
		||||
Mark McLoughlin <markmc@redhat.com>
 | 
			
		||||
Martin Kletzander <mkletzan@redhat.com>
 | 
			
		||||
Matthias Bolte <matthias.bolte@googlemail.com>
 | 
			
		||||
Maxim Nestratov <mnestratov@virtuozzo.com>
 | 
			
		||||
Michal Prívozník <mprivozn@redhat.com>
 | 
			
		||||
Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
 | 
			
		||||
Pavel Hrdina <phrdina@redhat.com>
 | 
			
		||||
Peter Krempa <pkrempa@redhat.com>
 | 
			
		||||
Richard W.M. Jones <rjones@redhat.com>
 | 
			
		||||
@@ -49,7 +44,6 @@ Chris Lalancette <clalance@redhat.com>
 | 
			
		||||
Dan Smith <danms@us.ibm.com>
 | 
			
		||||
Dave Allan <dallan@redhat.com>
 | 
			
		||||
Dave Leskovec <dlesko@linux.vnet.ibm.com>
 | 
			
		||||
Dmitry Guryanov <dguryanov@parallels.com>
 | 
			
		||||
Guannan Ren <gren@redhat.com>
 | 
			
		||||
Jim Meyering <meyering@redhat.com>
 | 
			
		||||
John Levon <john.levon@sun.com>
 | 
			
		||||
@@ -64,6 +58,7 @@ Amit Shah <amit.shah@redhat.com>
 | 
			
		||||
Andrew Puch <apuch@redhat.com>
 | 
			
		||||
Anton Protopopov <aspsk2@gmail.com>
 | 
			
		||||
Ben Guthro <ben.guthro@gmail.com>
 | 
			
		||||
Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
 | 
			
		||||
Daniel Hokka Zakrisson <daniel@hozac.com>
 | 
			
		||||
Dan Wendlandt <dan@nicira.com>
 | 
			
		||||
David Lively <dlively@virtualiron.com>
 | 
			
		||||
@@ -92,7 +87,9 @@ Stefan de Konink <dekonink@kinkrsoftware.nl>
 | 
			
		||||
Takahashi Tomohiro <takatom@jp.fujitsu.com>
 | 
			
		||||
Tatsuro Enokura <fj7716hz@aa.jp.fujitsu.com>
 | 
			
		||||
 | 
			
		||||
#contributorslist#
 | 
			
		||||
#authorslist#
 | 
			
		||||
 | 
			
		||||
[....send patches to get your name here....]
 | 
			
		||||
 | 
			
		||||
The libvirt logo was designed by Diana Fong
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
 | 
			
		||||
that what they have is not the original version, so that the original
 | 
			
		||||
author's reputation will not be affected by problems that might be
 | 
			
		||||
introduced by others.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Finally, software patents pose a constant threat to the existence of
 | 
			
		||||
any free program.  We wish to make sure that a company cannot
 | 
			
		||||
effectively restrict the users of a free program by obtaining a
 | 
			
		||||
@@ -111,7 +111,7 @@ modification follow.  Pay close attention to the difference between a
 | 
			
		||||
"work based on the library" and a "work that uses the library".  The
 | 
			
		||||
former contains code derived from the library, whereas the latter must
 | 
			
		||||
be combined with the library in order to run.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                  GNU LESSER GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
@@ -158,7 +158,7 @@ Library.
 | 
			
		||||
  You may charge a fee for the physical act of transferring a copy,
 | 
			
		||||
and you may at your option offer warranty protection in exchange for a
 | 
			
		||||
fee.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Library or any portion
 | 
			
		||||
of it, thus forming a work based on the Library, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
@@ -216,7 +216,7 @@ instead of to this License.  (If a newer version than version 2 of the
 | 
			
		||||
ordinary GNU General Public License has appeared, then you can specify
 | 
			
		||||
that version instead if you wish.)  Do not make any other change in
 | 
			
		||||
these notices.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Once this change is made in a given copy, it is irreversible for
 | 
			
		||||
that copy, so the ordinary GNU General Public License applies to all
 | 
			
		||||
subsequent copies and derivative works made from that copy.
 | 
			
		||||
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
 | 
			
		||||
distribute the object code for the work under the terms of Section 6.
 | 
			
		||||
Any executables containing that work also fall under Section 6,
 | 
			
		||||
whether or not they are linked directly with the Library itself.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  6. As an exception to the Sections above, you may also combine or
 | 
			
		||||
link a "work that uses the Library" with the Library to produce a
 | 
			
		||||
work containing portions of the Library, and distribute that work
 | 
			
		||||
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
 | 
			
		||||
accompany the operating system.  Such a contradiction means you cannot
 | 
			
		||||
use both them and the Library together in an executable that you
 | 
			
		||||
distribute.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  7. You may place library facilities that are a work based on the
 | 
			
		||||
Library side-by-side in a single library together with other library
 | 
			
		||||
facilities not covered by this License, and distribute such a combined
 | 
			
		||||
@@ -370,7 +370,7 @@ subject to these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties with
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  11. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
 | 
			
		||||
the Free Software Foundation.  If the Library does not specify a
 | 
			
		||||
license version number, you may choose any version ever published by
 | 
			
		||||
the Free Software Foundation.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  14. If you wish to incorporate parts of the Library into other free
 | 
			
		||||
programs whose distribution conditions are incompatible with these,
 | 
			
		||||
write to the author to ask for permission.  For software which is
 | 
			
		||||
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 | 
			
		||||
DAMAGES.
 | 
			
		||||
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           How to Apply These Terms to Your New Libraries
 | 
			
		||||
 | 
			
		||||
  If you develop a new library, and you want it to be of the greatest
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,15 +0,0 @@
 | 
			
		||||
libvirt ChangeLog
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
The libvirt project doesn't include a detailed ChangeLog in its release
 | 
			
		||||
archives.
 | 
			
		||||
 | 
			
		||||
If you're interested in the full list of changes made to libvirt since
 | 
			
		||||
the project was started, you can clone the git repository from
 | 
			
		||||
 | 
			
		||||
  https://libvirt.org/git/libvirt.git
 | 
			
		||||
 | 
			
		||||
and browse them locally using your favorite git history viewer or,
 | 
			
		||||
alternatively, browse them online at
 | 
			
		||||
 | 
			
		||||
  https://libvirt.org/git/?p=libvirt.git;a=log
 | 
			
		||||
							
								
								
									
										16699
									
								
								ChangeLog-old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16699
									
								
								ChangeLog-old
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										74
									
								
								GNUmakefile
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								GNUmakefile
									
									
									
									
									
								
							@@ -1,74 +0,0 @@
 | 
			
		||||
# Having a separate GNUmakefile lets me 'include' the dynamically
 | 
			
		||||
# generated rules created via cfg.mk (package-local configuration)
 | 
			
		||||
# as well as maint.mk (generic maintainer rules).
 | 
			
		||||
# This makefile is used only if you run GNU Make.
 | 
			
		||||
# It is necessary if you want to build targets usually of interest
 | 
			
		||||
# only to the maintainer.
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2001, 2003, 2006-2019 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 <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
_build-aux ?= build-aux
 | 
			
		||||
_autoreconf ?= autoreconf -v
 | 
			
		||||
 | 
			
		||||
# If the user runs GNU make but has not yet run ./configure,
 | 
			
		||||
# give them a diagnostic.
 | 
			
		||||
_gl-Makefile := $(wildcard [M]akefile)
 | 
			
		||||
ifneq ($(_gl-Makefile),)
 | 
			
		||||
 | 
			
		||||
# Make tar archive easier to reproduce.
 | 
			
		||||
export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner
 | 
			
		||||
 | 
			
		||||
# Allow the user to add to this in the Makefile.
 | 
			
		||||
ALL_RECURSIVE_TARGETS =
 | 
			
		||||
 | 
			
		||||
include Makefile
 | 
			
		||||
include $(srcdir)/$(_build-aux)/syntax-check.mk
 | 
			
		||||
 | 
			
		||||
else
 | 
			
		||||
 | 
			
		||||
.DEFAULT_GOAL := abort-due-to-no-makefile
 | 
			
		||||
srcdir = .
 | 
			
		||||
 | 
			
		||||
# The package can override .DEFAULT_GOAL to run actions like autoreconf.
 | 
			
		||||
include $(srcdir)/$(_build-aux)/syntax-check.mk
 | 
			
		||||
 | 
			
		||||
ifeq ($(.DEFAULT_GOAL),abort-due-to-no-makefile)
 | 
			
		||||
$(MAKECMDGOALS): abort-due-to-no-makefile
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
abort-due-to-no-makefile:
 | 
			
		||||
	@echo There seems to be no Makefile in this directory.   1>&2
 | 
			
		||||
	@echo "You must run ./configure before running 'make'." 1>&2
 | 
			
		||||
	@exit 1
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Tell version 3.79 and up of GNU make to not build goals in this
 | 
			
		||||
# directory in parallel, in case someone tries to build multiple
 | 
			
		||||
# targets, and one of them can cause a recursive target to be invoked.
 | 
			
		||||
 | 
			
		||||
# Only set this if Automake doesn't provide it.
 | 
			
		||||
AM_RECURSIVE_TARGETS ?= $(RECURSIVE_TARGETS:-recursive=) \
 | 
			
		||||
  $(RECURSIVE_CLEAN_TARGETS:-recursive=) \
 | 
			
		||||
  dist distcheck tags ctags
 | 
			
		||||
 | 
			
		||||
ALL_RECURSIVE_TARGETS += $(AM_RECURSIVE_TARGETS)
 | 
			
		||||
 | 
			
		||||
ifneq ($(word 2, $(MAKECMDGOALS)), )
 | 
			
		||||
ifneq ($(filter $(ALL_RECURSIVE_TARGETS), $(MAKECMDGOALS)), )
 | 
			
		||||
.NOTPARALLEL:
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
							
								
								
									
										191
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										191
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -19,104 +19,67 @@
 | 
			
		||||
LCOV = lcov
 | 
			
		||||
GENHTML = genhtml
 | 
			
		||||
 | 
			
		||||
# when building from tarball -Werror isn't auto enabled
 | 
			
		||||
# so force it explicitly
 | 
			
		||||
DISTCHECK_CONFIGURE_FLAGS = --enable-werror
 | 
			
		||||
 | 
			
		||||
SUBDIRS = . include/libvirt src tools docs \
 | 
			
		||||
  tests po examples
 | 
			
		||||
 | 
			
		||||
XZ_OPT ?= -v -T0
 | 
			
		||||
export XZ_OPT
 | 
			
		||||
SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
 | 
			
		||||
  tests po examples/object-events examples/hellolibvirt \
 | 
			
		||||
  examples/dominfo examples/domsuspend examples/apparmor \
 | 
			
		||||
  examples/xml/nwfilter examples/openauth examples/systemtap \
 | 
			
		||||
  tools/wireshark examples/dommigrate \
 | 
			
		||||
  examples/lxcconvert examples/domtop
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
 | 
			
		||||
XML_EXAMPLES = \
 | 
			
		||||
  $(patsubst $(srcdir)/%,%,$(wildcard $(addprefix $(srcdir)/examples/xml/, \
 | 
			
		||||
					test/*.xml storage/*.xml)))
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
  config-post.h \
 | 
			
		||||
  ChangeLog-old \
 | 
			
		||||
  libvirt.spec libvirt.spec.in \
 | 
			
		||||
  mingw-libvirt.spec.in \
 | 
			
		||||
  libvirt.pc.in \
 | 
			
		||||
  libvirt-qemu.pc.in \
 | 
			
		||||
  libvirt-lxc.pc.in \
 | 
			
		||||
  libvirt-admin.pc.in \
 | 
			
		||||
  autobuild.sh \
 | 
			
		||||
  Makefile.nonreentrant \
 | 
			
		||||
  autogen.sh \
 | 
			
		||||
  GNUmakefile \
 | 
			
		||||
  cfg.mk \
 | 
			
		||||
  run.in \
 | 
			
		||||
  README.md \
 | 
			
		||||
  AUTHORS.in \
 | 
			
		||||
  scripts/apibuild.py \
 | 
			
		||||
  scripts/augeas-gentest.py \
 | 
			
		||||
  build-aux/check-spacing.pl \
 | 
			
		||||
  scripts/check-aclperms.py \
 | 
			
		||||
  scripts/check-aclrules.py \
 | 
			
		||||
  scripts/check-drivername.py \
 | 
			
		||||
  scripts/check-driverimpls.py \
 | 
			
		||||
  scripts/check-file-access.py \
 | 
			
		||||
  scripts/check-remote-protocol.py \
 | 
			
		||||
  scripts/check-symfile.py \
 | 
			
		||||
  scripts/check-symsorting.py \
 | 
			
		||||
  scripts/dtrace2systemtap.py \
 | 
			
		||||
  scripts/esx_vi_generator.py \
 | 
			
		||||
  scripts/genaclperms.py \
 | 
			
		||||
  scripts/genpolkit.py \
 | 
			
		||||
  scripts/gensystemtap.py \
 | 
			
		||||
  scripts/group-qemu-caps.py \
 | 
			
		||||
  scripts/header-ifdef.py \
 | 
			
		||||
  scripts/hvsupport.py \
 | 
			
		||||
  scripts/hyperv_wmi_generator.py \
 | 
			
		||||
  scripts/minimize-po.py \
 | 
			
		||||
  scripts/mock-noinline.py \
 | 
			
		||||
  scripts/prohibit-duplicate-header.py \
 | 
			
		||||
  scripts/reformat-news.py \
 | 
			
		||||
  scripts/test-wrap-argv.py \
 | 
			
		||||
  build-aux/syntax-check.mk \
 | 
			
		||||
  build-aux/useless-if-before-free \
 | 
			
		||||
  build-aux/vc-list-files \
 | 
			
		||||
  ci/Makefile \
 | 
			
		||||
  ci/build.sh \
 | 
			
		||||
  ci/list-images.sh \
 | 
			
		||||
  ci/prepare.sh \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
  $(XML_EXAMPLES)
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc libvirt-admin.pc
 | 
			
		||||
pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc
 | 
			
		||||
 | 
			
		||||
NEWS: \
 | 
			
		||||
	  $(srcdir)/docs/news.xml \
 | 
			
		||||
	  $(srcdir)/docs/news-ascii.xsl \
 | 
			
		||||
	  $(top_srcdir)/scripts/reformat-news.py
 | 
			
		||||
	$(AM_V_GEN) \
 | 
			
		||||
	if [ -x $(XSLTPROC) ]; then \
 | 
			
		||||
	  $(XSLTPROC) --nonet \
 | 
			
		||||
	    $(srcdir)/docs/news-ascii.xsl \
 | 
			
		||||
	    $(srcdir)/docs/news.xml \
 | 
			
		||||
	  >$@-tmp \
 | 
			
		||||
	    || { rm -f $@-tmp; exit 1; }; \
 | 
			
		||||
	  $(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/reformat-news.py $@-tmp >$@ \
 | 
			
		||||
	    || { rm -f $@-tmp; exit 1; }; \
 | 
			
		||||
	  rm -f $@-tmp; \
 | 
			
		||||
	fi
 | 
			
		||||
EXTRA_DIST += \
 | 
			
		||||
	$(srcdir)/docs/news.xml \
 | 
			
		||||
	$(srcdir)/docs/news-ascii.xsl \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
NEWS: $(top_srcdir)/docs/news.xsl $(top_srcdir)/docs/news.html.in
 | 
			
		||||
	$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then			\
 | 
			
		||||
	  $(XSLTPROC) --nonet $(top_srcdir)/docs/news.xsl	\
 | 
			
		||||
	     $(top_srcdir)/docs/news.html.in			\
 | 
			
		||||
	   | perl -0777 -pe 's/\n\n+$$/\n/'			\
 | 
			
		||||
	   | perl -pe 's/[ \t]+$$//'				\
 | 
			
		||||
	   > $@-t && mv $@-t $@ ; fi
 | 
			
		||||
 | 
			
		||||
$(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl \
 | 
			
		||||
			$(top_srcdir)/docs/hacking2.xsl \
 | 
			
		||||
			$(top_srcdir)/docs/wrapstring.xsl \
 | 
			
		||||
			$(top_srcdir)/docs/hacking.html.in
 | 
			
		||||
	$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	   $(XSLTPROC) --nonet $(top_srcdir)/docs/hacking1.xsl \
 | 
			
		||||
		$(top_srcdir)/docs/hacking.html.in | \
 | 
			
		||||
	   $(XSLTPROC) --nonet $(top_srcdir)/docs/hacking2.xsl - \
 | 
			
		||||
	   | perl -0777 -pe 's/\n\n+$$/\n/' \
 | 
			
		||||
	   > $@-t && mv $@-t $@ ; fi;
 | 
			
		||||
 | 
			
		||||
rpm: clean
 | 
			
		||||
	@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.xz)
 | 
			
		||||
 | 
			
		||||
srpm: clean
 | 
			
		||||
	@(unset CDPATH ; $(MAKE) dist && rpmbuild -ts $(distdir).tar.xz)
 | 
			
		||||
	@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz)
 | 
			
		||||
 | 
			
		||||
check-local: all tests
 | 
			
		||||
 | 
			
		||||
check-access: all
 | 
			
		||||
	@($(MAKE) $(AM_MAKEFLAGS) -C tests check-access)
 | 
			
		||||
 | 
			
		||||
cov: clean-cov
 | 
			
		||||
	$(MKDIR_P) $(top_builddir)/coverage
 | 
			
		||||
	mkdir $(top_builddir)/coverage
 | 
			
		||||
	$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp \
 | 
			
		||||
	  -d $(top_builddir)/src \
 | 
			
		||||
	  -d $(top_builddir)/src  -d $(top_builddir)/daemon \
 | 
			
		||||
	  -d $(top_builddir)/tests
 | 
			
		||||
	$(LCOV) -r $(top_builddir)/coverage/libvirt.info.tmp \
 | 
			
		||||
	  -o $(top_builddir)/coverage/libvirt.info
 | 
			
		||||
@@ -129,72 +92,28 @@ clean-cov:
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = .git-module-status
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = configmake.h
 | 
			
		||||
CLEANFILES = configmake.h
 | 
			
		||||
# disable this check
 | 
			
		||||
distuninstallcheck:
 | 
			
		||||
 | 
			
		||||
distclean-local: clean-GNUmakefile
 | 
			
		||||
clean-GNUmakefile:
 | 
			
		||||
	test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile
 | 
			
		||||
dist-hook: gen-ChangeLog gen-AUTHORS
 | 
			
		||||
 | 
			
		||||
dist-hook: gen-AUTHORS
 | 
			
		||||
# 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:
 | 
			
		||||
	$(AM_V_GEN)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
 | 
			
		||||
 | 
			
		||||
.PHONY: gen-AUTHORS
 | 
			
		||||
gen-AUTHORS:
 | 
			
		||||
	$(AM_V_GEN)\
 | 
			
		||||
	if test -d $(srcdir)/.git; then \
 | 
			
		||||
	  ( \
 | 
			
		||||
	    cd $(srcdir) && \
 | 
			
		||||
	    git log --pretty=format:'%aN <%aE>' | sort -u \
 | 
			
		||||
	  ) > all.list && \
 | 
			
		||||
	  sort -u $(srcdir)/AUTHORS.in > maint.list && \
 | 
			
		||||
	  comm -23 all.list maint.list > contrib.list && \
 | 
			
		||||
	  contrib="`cat contrib.list`" && \
 | 
			
		||||
	  perl -p -e "s/#contributorslist#// and print '$$contrib'" \
 | 
			
		||||
	    < $(srcdir)/AUTHORS.in > $(distdir)/AUTHORS-tmp && \
 | 
			
		||||
	  mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS && \
 | 
			
		||||
	  rm -f all.list maint.list contrib.list; \
 | 
			
		||||
	$(AM_V_GEN)if test -d $(srcdir)/.git; then \
 | 
			
		||||
	    out="`cd $(srcdir) && git log --pretty=format:'%aN <%aE>' | sort -u`" && \
 | 
			
		||||
	    perl -p -e "s/#authorslist#// and print '$$out'" \
 | 
			
		||||
	      < $(srcdir)/AUTHORS.in > $(distdir)/AUTHORS-tmp && \
 | 
			
		||||
	    mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS ; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
ci-%:
 | 
			
		||||
	$(MAKE) -C $(srcdir)/ci/ $@
 | 
			
		||||
 | 
			
		||||
# Listed in the same order as the GNU makefile conventions, and
 | 
			
		||||
# provided by autoconf 2.59c+ or 2.70.
 | 
			
		||||
# The Automake-defined pkg* macros are appended, in the order
 | 
			
		||||
# listed in the Automake 1.10a+ documentation.
 | 
			
		||||
configmake.h: Makefile
 | 
			
		||||
	$(AM_V_GEN)rm -f $@-t && \
 | 
			
		||||
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
 | 
			
		||||
	  echo '#if WIN32'; \
 | 
			
		||||
	  echo '# include <winsock2.h> /* avoid mingw pollution on DATADIR */'; \
 | 
			
		||||
	  echo '#endif'; \
 | 
			
		||||
	  echo '#define PREFIX "$(prefix)"'; \
 | 
			
		||||
	  echo '#define EXEC_PREFIX "$(exec_prefix)"'; \
 | 
			
		||||
	  echo '#define BINDIR "$(bindir)"'; \
 | 
			
		||||
	  echo '#define SBINDIR "$(sbindir)"'; \
 | 
			
		||||
	  echo '#define LIBEXECDIR "$(libexecdir)"'; \
 | 
			
		||||
	  echo '#define DATAROOTDIR "$(datarootdir)"'; \
 | 
			
		||||
	  echo '#define DATADIR "$(datadir)"'; \
 | 
			
		||||
	  echo '#define SYSCONFDIR "$(sysconfdir)"'; \
 | 
			
		||||
	  echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \
 | 
			
		||||
	  echo '#define LOCALSTATEDIR "$(localstatedir)"'; \
 | 
			
		||||
	  echo '#define RUNSTATEDIR "$(runstatedir)"'; \
 | 
			
		||||
	  echo '#define INCLUDEDIR "$(includedir)"'; \
 | 
			
		||||
	  echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \
 | 
			
		||||
	  echo '#define DOCDIR "$(docdir)"'; \
 | 
			
		||||
	  echo '#define INFODIR "$(infodir)"'; \
 | 
			
		||||
	  echo '#define HTMLDIR "$(htmldir)"'; \
 | 
			
		||||
	  echo '#define DVIDIR "$(dvidir)"'; \
 | 
			
		||||
	  echo '#define PDFDIR "$(pdfdir)"'; \
 | 
			
		||||
	  echo '#define PSDIR "$(psdir)"'; \
 | 
			
		||||
	  echo '#define LIBDIR "$(libdir)"'; \
 | 
			
		||||
	  echo '#define LISPDIR "$(lispdir)"'; \
 | 
			
		||||
	  echo '#define LOCALEDIR "$(localedir)"'; \
 | 
			
		||||
	  echo '#define MANDIR "$(mandir)"'; \
 | 
			
		||||
	  echo '#define MANEXT "$(manext)"'; \
 | 
			
		||||
	  echo '#define PKGDATADIR "$(pkgdatadir)"'; \
 | 
			
		||||
	  echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \
 | 
			
		||||
	  echo '#define PKGLIBDIR "$(pkglibdir)"'; \
 | 
			
		||||
	  echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \
 | 
			
		||||
	} | sed '/""/d' > $@-t && \
 | 
			
		||||
	mv -f $@-t $@
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,9 @@
 | 
			
		||||
## <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Generated by running the following on Fedora 26:
 | 
			
		||||
# Generated by running the following on Fedora 9:
 | 
			
		||||
#
 | 
			
		||||
#  nm -D --defined-only /lib64/libc.so.6 \
 | 
			
		||||
#  nm -D --defined-only /lib/libc.so.6  \
 | 
			
		||||
#      | grep '_r$' \
 | 
			
		||||
#      | awk '{print $3}' \
 | 
			
		||||
#      | grep -v __ \
 | 
			
		||||
@@ -43,7 +43,6 @@ NON_REENTRANT += ether_ntoa
 | 
			
		||||
NON_REENTRANT += fcvt
 | 
			
		||||
NON_REENTRANT += fgetgrent
 | 
			
		||||
NON_REENTRANT += fgetpwent
 | 
			
		||||
NON_REENTRANT += fgetsgent
 | 
			
		||||
NON_REENTRANT += fgetspent
 | 
			
		||||
NON_REENTRANT += getaliasbyname
 | 
			
		||||
NON_REENTRANT += getaliasent
 | 
			
		||||
@@ -73,8 +72,6 @@ NON_REENTRANT += getrpcent
 | 
			
		||||
NON_REENTRANT += getservbyname
 | 
			
		||||
NON_REENTRANT += getservbyport
 | 
			
		||||
NON_REENTRANT += getservent
 | 
			
		||||
NON_REENTRANT += getsgent
 | 
			
		||||
NON_REENTRANT += getsgnam
 | 
			
		||||
NON_REENTRANT += getspent
 | 
			
		||||
NON_REENTRANT += getspnam
 | 
			
		||||
NON_REENTRANT += getutent
 | 
			
		||||
@@ -98,7 +95,6 @@ NON_REENTRANT += random
 | 
			
		||||
NON_REENTRANT += rand
 | 
			
		||||
NON_REENTRANT += seed48
 | 
			
		||||
NON_REENTRANT += setstate
 | 
			
		||||
NON_REENTRANT += sgetsgent
 | 
			
		||||
NON_REENTRANT += sgetspent
 | 
			
		||||
NON_REENTRANT += srand48
 | 
			
		||||
NON_REENTRANT += srandom
 | 
			
		||||
@@ -117,11 +113,3 @@ NON_REENTRANT += inet_nsap_ntoa
 | 
			
		||||
NON_REENTRANT += inet_ntoa
 | 
			
		||||
NON_REENTRANT += inet_ntop
 | 
			
		||||
NON_REENTRANT += inet_pton
 | 
			
		||||
 | 
			
		||||
# Separate two nothings by space to get one space in a variable
 | 
			
		||||
space =
 | 
			
		||||
space +=
 | 
			
		||||
# The space needs to be in a variable otherwise it would be ignored.
 | 
			
		||||
# And there must be no spaces around the commas because they would
 | 
			
		||||
# not be ignored, logically.
 | 
			
		||||
NON_REENTRANT_RE=$(subst $(space),|,$(NON_REENTRANT))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								README
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
 | 
			
		||||
         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>
 | 
			
		||||
@@ -2,8 +2,7 @@
 | 
			
		||||
 | 
			
		||||
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 docs/hacking.html (after building libvirt using the information
 | 
			
		||||
included in this file) for more detailed contribution guidelines.
 | 
			
		||||
See also HACKING for more detailed libvirt contribution guidelines.
 | 
			
		||||
 | 
			
		||||
* Requirements
 | 
			
		||||
 | 
			
		||||
@@ -11,7 +10,7 @@ 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.
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
@@ -25,16 +24,19 @@ few prerequisites, later, a plain `git pull && make' should be sufficient.
 | 
			
		||||
 | 
			
		||||
You can get a copy of the source repository like this:
 | 
			
		||||
 | 
			
		||||
        $ git clone https://libvirt.org/git/libvirt.git
 | 
			
		||||
        $ git clone git://libvirt.org/libvirt
 | 
			
		||||
        $ cd libvirt
 | 
			
		||||
 | 
			
		||||
We require to have the build directory different than the source directory:
 | 
			
		||||
As an optional step, if you already have a copy of the gnulib git
 | 
			
		||||
repository on your hard drive, then you can use it as a reference to
 | 
			
		||||
reduce download time and disk space requirements:
 | 
			
		||||
 | 
			
		||||
        $ mkdir build && cd build
 | 
			
		||||
        $ export GNULIB_SRCDIR=/path/to/gnulib
 | 
			
		||||
 | 
			
		||||
The next step is to invoke ../autogen.sh:
 | 
			
		||||
The next step is to get all required pieces from gnulib,
 | 
			
		||||
to run autoreconf, and to invoke ./configure:
 | 
			
		||||
 | 
			
		||||
        $ ../autogen.sh
 | 
			
		||||
        $ ./autogen.sh
 | 
			
		||||
 | 
			
		||||
And there you are!  Just
 | 
			
		||||
 | 
			
		||||
@@ -44,7 +46,6 @@ And there you are!  Just
 | 
			
		||||
At this point, there should be no difference between your local copy,
 | 
			
		||||
and the GIT master copy:
 | 
			
		||||
 | 
			
		||||
        $ cd ..
 | 
			
		||||
        $ git diff
 | 
			
		||||
 | 
			
		||||
should output no difference.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										86
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								README.md
									
									
									
									
									
								
							@@ -1,86 +0,0 @@
 | 
			
		||||
[](https://travis-ci.org/libvirt/libvirt)
 | 
			
		||||
 [](https://bestpractices.coreinfrastructure.org/projects/355)
 | 
			
		||||
 | 
			
		||||
Libvirt API for virtualization
 | 
			
		||||
==============================
 | 
			
		||||
 | 
			
		||||
Libvirt provides a portable, long term stable C API for managing the
 | 
			
		||||
virtualization technologies provided by many operating systems. It
 | 
			
		||||
includes support for QEMU, KVM, Xen, LXC, bhyve, Virtuozzo, VMware
 | 
			
		||||
vCenter and ESX, VMware Desktop, Hyper-V, VirtualBox and the POWER
 | 
			
		||||
Hypervisor.
 | 
			
		||||
 | 
			
		||||
For some of these hypervisors, it provides a stateful management
 | 
			
		||||
daemon which runs on the virtualization host allowing access to the
 | 
			
		||||
API both by non-privileged local users and remote users.
 | 
			
		||||
 | 
			
		||||
Layered packages provide bindings of the libvirt C API into other
 | 
			
		||||
languages including Python, Perl, PHP, Go, Java, OCaml, as well as
 | 
			
		||||
mappings into object systems such as GObject, CIM and SNMP.
 | 
			
		||||
 | 
			
		||||
Further information about the libvirt project can be found on the
 | 
			
		||||
website:
 | 
			
		||||
 | 
			
		||||
[https://libvirt.org](https://libvirt.org)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
The libvirt C API is distributed under the terms of GNU Lesser General
 | 
			
		||||
Public License, version 2.1 (or later). Some parts of the code that are
 | 
			
		||||
not part of the C library may have the more restrictive GNU General
 | 
			
		||||
Public License, version 2.0 (or later). See the files `COPYING.LESSER`
 | 
			
		||||
and `COPYING` for full license terms & conditions.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
Libvirt uses the GNU Autotools build system, so in general can be built
 | 
			
		||||
and installed with the usual commands, however, we mandate to have the
 | 
			
		||||
build directory different than the source directory. For example, to build
 | 
			
		||||
in a manner that is suitable for installing as root, use:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ mkdir build && cd build
 | 
			
		||||
$ ../configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
 | 
			
		||||
$ make
 | 
			
		||||
$ sudo make install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
While to build & install as an unprivileged user
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ mkdir build && cd build
 | 
			
		||||
$ ../configure --prefix=$HOME/usr
 | 
			
		||||
$ make
 | 
			
		||||
$ make install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The libvirt code relies on a large number of 3rd party libraries. These will
 | 
			
		||||
be detected during execution of the `configure` script and a summary printed
 | 
			
		||||
which lists any missing (optional) dependencies.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contributing
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
The libvirt project welcomes contributions in many ways. For most components
 | 
			
		||||
the best way to contribute is to send patches to the primary development
 | 
			
		||||
mailing list. Further guidance on this can be found on the website:
 | 
			
		||||
 | 
			
		||||
[https://libvirt.org/contribute.html](https://libvirt.org/contribute.html)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contact
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
The libvirt project has two primary mailing lists:
 | 
			
		||||
 | 
			
		||||
  * libvirt-users@redhat.com (**for user discussions**)
 | 
			
		||||
  * libvir-list@redhat.com (**for development only**)
 | 
			
		||||
 | 
			
		||||
Further details on contacting the project are available on the website:
 | 
			
		||||
 | 
			
		||||
[https://libvirt.org/contact.html](https://libvirt.org/contact.html)
 | 
			
		||||
							
								
								
									
										22
									
								
								TODO
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								TODO
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
         libvirt TODO list
 | 
			
		||||
         =================
 | 
			
		||||
 | 
			
		||||
The TODO list changes frequently, so is maintained online
 | 
			
		||||
in the libvirt bugzilla
 | 
			
		||||
 | 
			
		||||
  http://bugzilla.redhat.com/
 | 
			
		||||
 | 
			
		||||
Search against
 | 
			
		||||
 | 
			
		||||
    Product: Virtualization Tools
 | 
			
		||||
  Component: libvirt
 | 
			
		||||
    Subject: RFE
 | 
			
		||||
 | 
			
		||||
Or browse dependent bugs under
 | 
			
		||||
 | 
			
		||||
  https://bugzilla.redhat.com/show_bug.cgi?id=libvirtTodo
 | 
			
		||||
 | 
			
		||||
Summarized reports automatically generated from bugzilla
 | 
			
		||||
and provided online at
 | 
			
		||||
 | 
			
		||||
  http://libvirt.org/todo.html
 | 
			
		||||
							
								
								
									
										122
									
								
								autobuild.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										122
									
								
								autobuild.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
set -v
 | 
			
		||||
 | 
			
		||||
# Make things clean.
 | 
			
		||||
 | 
			
		||||
test -n "$1" && RESULTS=$1 || RESULTS=results.log
 | 
			
		||||
: ${AUTOBUILD_INSTALL_ROOT=$HOME/builder}
 | 
			
		||||
 | 
			
		||||
# If run under the autobuilder, we must use --nodeps with rpmbuild;
 | 
			
		||||
# but this can lead to odd error diagnosis for normal development.
 | 
			
		||||
nodeps=
 | 
			
		||||
if test "${AUTOBUILD_COUNTER+set}"; then
 | 
			
		||||
  nodeps=--nodeps
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
test -f Makefile && make -k distclean || :
 | 
			
		||||
rm -rf coverage
 | 
			
		||||
 | 
			
		||||
rm -rf build
 | 
			
		||||
mkdir build
 | 
			
		||||
cd build
 | 
			
		||||
 | 
			
		||||
# Run with options not normally exercised by the rpm build, for
 | 
			
		||||
# more complete code coverage.
 | 
			
		||||
../autogen.sh --prefix="$AUTOBUILD_INSTALL_ROOT" \
 | 
			
		||||
  --enable-expensive-tests \
 | 
			
		||||
  --enable-test-coverage \
 | 
			
		||||
  --disable-nls \
 | 
			
		||||
  --enable-werror \
 | 
			
		||||
  --enable-static
 | 
			
		||||
 | 
			
		||||
# If the MAKEFLAGS envvar does not yet include a -j option,
 | 
			
		||||
# add -jN where N depends on the number of processors.
 | 
			
		||||
case $MAKEFLAGS in
 | 
			
		||||
  *-j*) ;;
 | 
			
		||||
  *) n=$(getconf _NPROCESSORS_ONLN 2> /dev/null)
 | 
			
		||||
    test "$n" -gt 0 || n=1
 | 
			
		||||
    n=$(expr $n + 1)
 | 
			
		||||
    MAKEFLAGS="$MAKEFLAGS -j$n"
 | 
			
		||||
    export MAKEFLAGS
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
make
 | 
			
		||||
make install
 | 
			
		||||
 | 
			
		||||
# set -o pipefail is a bashism; this use of exec is the POSIX alternative
 | 
			
		||||
exec 3>&1
 | 
			
		||||
st=$(
 | 
			
		||||
  exec 4>&1 >&3
 | 
			
		||||
  { make check syntax-check 2>&1 3>&- 4>&-; echo $? >&4; } | tee "$RESULTS"
 | 
			
		||||
)
 | 
			
		||||
exec 3>&-
 | 
			
		||||
test "$st" = 0
 | 
			
		||||
test -x /usr/bin/lcov && make cov
 | 
			
		||||
 | 
			
		||||
rm -f *.tar.gz
 | 
			
		||||
make dist
 | 
			
		||||
 | 
			
		||||
if test -n "$AUTOBUILD_COUNTER" ; then
 | 
			
		||||
  EXTRA_RELEASE=".auto$AUTOBUILD_COUNTER"
 | 
			
		||||
else
 | 
			
		||||
  NOW=`date +"%s"`
 | 
			
		||||
  EXTRA_RELEASE=".$USER$NOW"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -f /usr/bin/rpmbuild ; then
 | 
			
		||||
  rpmbuild $nodeps \
 | 
			
		||||
     --define "extra_release $EXTRA_RELEASE" \
 | 
			
		||||
     --define "_sourcedir `pwd`" \
 | 
			
		||||
     -ba --clean libvirt.spec
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Test mingw32 cross-compile
 | 
			
		||||
if test -x /usr/bin/i686-w64-mingw32-gcc ; then
 | 
			
		||||
  make distclean
 | 
			
		||||
 | 
			
		||||
  PKG_CONFIG_LIBDIR="/usr/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig:/usr/i686-w64-mingw32/sys-root/mingw/share/pkgconfig" \
 | 
			
		||||
  PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig" \
 | 
			
		||||
  CC="i686-w64-mingw32-gcc" \
 | 
			
		||||
  ../configure \
 | 
			
		||||
    --build=$(uname -m)-w64-linux \
 | 
			
		||||
    --host=i686-w64-mingw32 \
 | 
			
		||||
    --prefix="$AUTOBUILD_INSTALL_ROOT/i686-w64-mingw32/sys-root/mingw" \
 | 
			
		||||
    --enable-expensive-tests \
 | 
			
		||||
    --enable-werror
 | 
			
		||||
 | 
			
		||||
  make
 | 
			
		||||
  make install
 | 
			
		||||
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Test mingw64 cross-compile
 | 
			
		||||
if test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
 | 
			
		||||
  make distclean
 | 
			
		||||
 | 
			
		||||
  PKG_CONFIG_LIBDIR="/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig:/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig" \
 | 
			
		||||
  PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig" \
 | 
			
		||||
  CC="x86_64-w64-mingw32-gcc" \
 | 
			
		||||
  ../configure \
 | 
			
		||||
    --build=$(uname -m)-w64-linux \
 | 
			
		||||
    --host=x86_64-w64-mingw32 \
 | 
			
		||||
    --prefix="$AUTOBUILD_INSTALL_ROOT/x86_64-w64-mingw32/sys-root/mingw" \
 | 
			
		||||
    --enable-expensive-tests \
 | 
			
		||||
    --enable-werror
 | 
			
		||||
 | 
			
		||||
  make
 | 
			
		||||
  make install
 | 
			
		||||
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if test -x /usr/bin/i686-w64-mingw32-gcc && test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
 | 
			
		||||
  if test -f /usr/bin/rpmbuild ; then
 | 
			
		||||
    rpmbuild $nodeps \
 | 
			
		||||
       --define "extra_release $EXTRA_RELEASE" \
 | 
			
		||||
       --define "_sourcedir `pwd`" \
 | 
			
		||||
       -ba --clean mingw-libvirt.spec
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
							
								
								
									
										113
									
								
								autogen.sh
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								autogen.sh
									
									
									
									
									
								
							@@ -1,23 +1,32 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Run this to generate all the initial makefiles, etc.
 | 
			
		||||
test -n "$srcdir" || srcdir=$(dirname "$0")
 | 
			
		||||
test -n "$srcdir" || srcdir=.
 | 
			
		||||
 | 
			
		||||
olddir=$(pwd)
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
srcdir=`dirname "$0"`
 | 
			
		||||
test -z "$srcdir" && srcdir=.
 | 
			
		||||
 | 
			
		||||
THEDIR=`pwd`
 | 
			
		||||
cd "$srcdir"
 | 
			
		||||
 | 
			
		||||
(test -f src/libvirt.c) || {
 | 
			
		||||
    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
 | 
			
		||||
    echo " top-level libvirt directory"
 | 
			
		||||
test -f src/libvirt.c || {
 | 
			
		||||
    echo "You must run this script in the top-level libvirt directory"
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
git submodule update --init || exit 1
 | 
			
		||||
 | 
			
		||||
autoreconf --verbose --force --install || exit 1
 | 
			
		||||
 | 
			
		||||
if test "x$1" = "x--system"; then
 | 
			
		||||
EXTRA_ARGS=
 | 
			
		||||
no_git=
 | 
			
		||||
if test "x$1" = "x--no-git"; then
 | 
			
		||||
  no_git=" $1"
 | 
			
		||||
  shift
 | 
			
		||||
  case "$1 $2" in
 | 
			
		||||
    --gnulib-srcdir=*) no_git="$no_git $1"; shift ;;
 | 
			
		||||
    --gnulib-srcdir\ *) no_git="$no_git $1=$2"; shift; shift;;
 | 
			
		||||
  esac
 | 
			
		||||
fi
 | 
			
		||||
if test -z "$NOCONFIGURE" ; then
 | 
			
		||||
  if test "x$1" = "x--system"; then
 | 
			
		||||
    shift
 | 
			
		||||
    prefix=/usr
 | 
			
		||||
    libdir=$prefix/lib
 | 
			
		||||
@@ -27,18 +36,82 @@ if test "x$1" = "x--system"; then
 | 
			
		||||
      libdir=$prefix/lib64
 | 
			
		||||
    fi
 | 
			
		||||
    EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir"
 | 
			
		||||
    echo "Running ./configure with $EXTRA_ARGS $@"
 | 
			
		||||
  else
 | 
			
		||||
    if test -z "$*" && test ! -f "$THEDIR/config.status"; then
 | 
			
		||||
        echo "I am going to run ./configure with no arguments - if you wish"
 | 
			
		||||
        echo "to pass any to it, please specify them on the $0 command line."
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
cd "$olddir"
 | 
			
		||||
# Compute the hash we'll use to determine whether rerunning bootstrap
 | 
			
		||||
# is required.  The first is just the SHA1 that selects a gnulib snapshot.
 | 
			
		||||
# The second ensures that whenever we change the set of gnulib modules used
 | 
			
		||||
# by this package, we rerun bootstrap to pull in the matching set of files.
 | 
			
		||||
# The third ensures that whenever we change the set of local gnulib diffs,
 | 
			
		||||
# we rerun bootstrap to pull in those diffs.
 | 
			
		||||
bootstrap_hash()
 | 
			
		||||
{
 | 
			
		||||
    if test "$no_git"; then
 | 
			
		||||
        echo no-git
 | 
			
		||||
        return
 | 
			
		||||
    fi
 | 
			
		||||
    git submodule status | sed 's/^[ +-]//;s/ .*//'
 | 
			
		||||
    git hash-object bootstrap.conf
 | 
			
		||||
    git ls-tree -d HEAD gnulib/local | awk '{print $3}'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if [ "$NOCONFIGURE" = "" ]; then
 | 
			
		||||
        $srcdir/configure $EXTRA_ARGS "$@" || exit 1
 | 
			
		||||
 | 
			
		||||
        if [ "$1" = "--help" ]; then
 | 
			
		||||
                exit 0
 | 
			
		||||
        else
 | 
			
		||||
                echo "Now type 'make' to compile libvirt" || exit 1
 | 
			
		||||
# Ensure that whenever we pull in a gnulib update or otherwise change to a
 | 
			
		||||
# different version (i.e., when switching branches), we also rerun ./bootstrap.
 | 
			
		||||
# Also, running 'make rpm' tends to litter the po/ directory, and some people
 | 
			
		||||
# like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates
 | 
			
		||||
# the required file po/Makevars.
 | 
			
		||||
# Only run bootstrap from a git checkout, never from a tarball.
 | 
			
		||||
if test -d .git || test -f .git; then
 | 
			
		||||
    curr_status=.git-module-status t=
 | 
			
		||||
    if test "$no_git"; then
 | 
			
		||||
        t=no-git
 | 
			
		||||
    elif test -d .gnulib; then
 | 
			
		||||
        t=$(bootstrap_hash; git diff .gnulib)
 | 
			
		||||
    fi
 | 
			
		||||
    case $t:${CLEAN_SUBMODULE+set} in
 | 
			
		||||
        *:set) ;;
 | 
			
		||||
        *-dirty*)
 | 
			
		||||
            echo "error: gnulib submodule is dirty, please investigate" 2>&1
 | 
			
		||||
            echo "set env-var CLEAN_SUBMODULE to discard gnulib changes" 2>&1
 | 
			
		||||
            exit 1 ;;
 | 
			
		||||
    esac
 | 
			
		||||
    # Keep this test in sync with cfg.mk:_update_required
 | 
			
		||||
    if test "$t" = "$(cat $curr_status 2>/dev/null)" \
 | 
			
		||||
        && test -f "po/Makevars" && test -f AUTHORS; then
 | 
			
		||||
        # good, it's up to date, all we need is autoreconf
 | 
			
		||||
        autoreconf -if
 | 
			
		||||
    else
 | 
			
		||||
        if test -z "$no_git" && test ${CLEAN_SUBMODULE+set}; then
 | 
			
		||||
            echo cleaning up submodules...
 | 
			
		||||
            git submodule foreach 'git clean -dfqx && git reset --hard'
 | 
			
		||||
        fi
 | 
			
		||||
else
 | 
			
		||||
        echo "Skipping configure process."
 | 
			
		||||
        echo running bootstrap$no_git...
 | 
			
		||||
        ./bootstrap$no_git --bootstrap-sync && bootstrap_hash > $curr_status \
 | 
			
		||||
            || { echo "Failed to bootstrap, please investigate."; exit 1; }
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
test -n "$NOCONFIGURE" && exit 0
 | 
			
		||||
 | 
			
		||||
cd "$THEDIR"
 | 
			
		||||
 | 
			
		||||
if test "x$OBJ_DIR" != x; then
 | 
			
		||||
    mkdir -p "$OBJ_DIR"
 | 
			
		||||
    cd "$OBJ_DIR"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -z "$*" && test -z "$EXTRA_ARGS" && test -f config.status; then
 | 
			
		||||
    ./config.status --recheck
 | 
			
		||||
else
 | 
			
		||||
    $srcdir/configure $EXTRA_ARGS "$@"
 | 
			
		||||
fi && {
 | 
			
		||||
    echo
 | 
			
		||||
    echo "Now type 'make' to compile libvirt."
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										249
									
								
								bootstrap.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								bootstrap.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,249 @@
 | 
			
		||||
# Bootstrap configuration.
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2010-2014 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
# License as published by the Free Software Foundation; either
 | 
			
		||||
# version 2.1 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 Lesser General Public
 | 
			
		||||
# License along with this library.  If not, see
 | 
			
		||||
# <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
# gnulib modules used by this package.
 | 
			
		||||
gnulib_modules='
 | 
			
		||||
accept
 | 
			
		||||
areadlink
 | 
			
		||||
autobuild
 | 
			
		||||
base64
 | 
			
		||||
bind
 | 
			
		||||
bitrotate
 | 
			
		||||
byteswap
 | 
			
		||||
c-ctype
 | 
			
		||||
c-strcase
 | 
			
		||||
c-strcasestr
 | 
			
		||||
calloc-posix
 | 
			
		||||
canonicalize-lgpl
 | 
			
		||||
chown
 | 
			
		||||
clock-time
 | 
			
		||||
close
 | 
			
		||||
connect
 | 
			
		||||
configmake
 | 
			
		||||
count-leading-zeros
 | 
			
		||||
count-one-bits
 | 
			
		||||
crypto/md5
 | 
			
		||||
crypto/sha256
 | 
			
		||||
dirname-lgpl
 | 
			
		||||
environ
 | 
			
		||||
execinfo
 | 
			
		||||
fclose
 | 
			
		||||
fcntl
 | 
			
		||||
fcntl-h
 | 
			
		||||
fdatasync
 | 
			
		||||
ffs
 | 
			
		||||
ffsl
 | 
			
		||||
fnmatch
 | 
			
		||||
fsync
 | 
			
		||||
func
 | 
			
		||||
getaddrinfo
 | 
			
		||||
getcwd-lgpl
 | 
			
		||||
gethostname
 | 
			
		||||
getpass
 | 
			
		||||
getpeername
 | 
			
		||||
getsockname
 | 
			
		||||
gettext-h
 | 
			
		||||
gettimeofday
 | 
			
		||||
gitlog-to-changelog
 | 
			
		||||
gnumakefile
 | 
			
		||||
ignore-value
 | 
			
		||||
inet_pton
 | 
			
		||||
intprops
 | 
			
		||||
ioctl
 | 
			
		||||
isatty
 | 
			
		||||
largefile
 | 
			
		||||
ldexp
 | 
			
		||||
listen
 | 
			
		||||
localeconv
 | 
			
		||||
maintainer-makefile
 | 
			
		||||
manywarnings
 | 
			
		||||
mgetgroups
 | 
			
		||||
mkdtemp
 | 
			
		||||
mkostemp
 | 
			
		||||
mkostemps
 | 
			
		||||
mktempd
 | 
			
		||||
net_if
 | 
			
		||||
netdb
 | 
			
		||||
nonblocking
 | 
			
		||||
openpty
 | 
			
		||||
passfd
 | 
			
		||||
perror
 | 
			
		||||
physmem
 | 
			
		||||
pipe-posix
 | 
			
		||||
pipe2
 | 
			
		||||
poll
 | 
			
		||||
posix-shell
 | 
			
		||||
pthread
 | 
			
		||||
pthread_sigmask
 | 
			
		||||
recv
 | 
			
		||||
regex
 | 
			
		||||
random_r
 | 
			
		||||
sched
 | 
			
		||||
secure_getenv
 | 
			
		||||
send
 | 
			
		||||
setenv
 | 
			
		||||
setsockopt
 | 
			
		||||
sigaction
 | 
			
		||||
sigpipe
 | 
			
		||||
snprintf
 | 
			
		||||
socket
 | 
			
		||||
stat-time
 | 
			
		||||
stdarg
 | 
			
		||||
stpcpy
 | 
			
		||||
strchrnul
 | 
			
		||||
strdup-posix
 | 
			
		||||
strndup
 | 
			
		||||
strerror
 | 
			
		||||
strerror_r-posix
 | 
			
		||||
strptime
 | 
			
		||||
strsep
 | 
			
		||||
strtok_r
 | 
			
		||||
sys_stat
 | 
			
		||||
sys_wait
 | 
			
		||||
termios
 | 
			
		||||
time_r
 | 
			
		||||
timegm
 | 
			
		||||
ttyname_r
 | 
			
		||||
uname
 | 
			
		||||
useless-if-before-free
 | 
			
		||||
usleep
 | 
			
		||||
vasprintf
 | 
			
		||||
verify
 | 
			
		||||
vc-list-files
 | 
			
		||||
vsnprintf
 | 
			
		||||
waitpid
 | 
			
		||||
warnings
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
# Additional xgettext options to use.  Use "\\\newline" to break lines.
 | 
			
		||||
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
 | 
			
		||||
 --flag=virAsprintf:2:c-format\\\
 | 
			
		||||
 --from-code=UTF-8\\\
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
# This is not a GNU package, so the default bug address is invalid,
 | 
			
		||||
# and the translation project is not in use.
 | 
			
		||||
MSGID_BUGS_ADDRESS=libvir-list@redhat.com
 | 
			
		||||
COPYRIGHT_HOLDER='Red Hat, Inc.'
 | 
			
		||||
SKIP_PO=true
 | 
			
		||||
 | 
			
		||||
# Enable copy-mode for MSYS/MinGW. MSYS' ln doesn't work well in the way
 | 
			
		||||
# bootstrap uses it with relative paths.
 | 
			
		||||
if test -n "$MSYSTEM"; then
 | 
			
		||||
    copy=true
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]"
 | 
			
		||||
# appears in configure.ac, exclude some unnecessary files.
 | 
			
		||||
# Without grep's -E option (not portable enough, pre-configure),
 | 
			
		||||
# the following test is ugly.  Also, this depends on the existence
 | 
			
		||||
# of configure.ac, not the obsolescent-named configure.in.  But if
 | 
			
		||||
# you're using this infrastructure, you should care about such things.
 | 
			
		||||
 | 
			
		||||
gettext_external=0
 | 
			
		||||
grep '^[	 ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null &&
 | 
			
		||||
  gettext_external=1
 | 
			
		||||
grep '^[	 ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null &&
 | 
			
		||||
  gettext_external=1
 | 
			
		||||
 | 
			
		||||
if test $gettext_external = 1; then
 | 
			
		||||
  # Gettext supplies these files, but we don't need them since
 | 
			
		||||
  # we don't have an intl subdirectory.
 | 
			
		||||
  excluded_files='
 | 
			
		||||
      m4/glibc2.m4
 | 
			
		||||
      m4/intdiv0.m4
 | 
			
		||||
      m4/lcmessage.m4
 | 
			
		||||
      m4/uintmax_t.m4
 | 
			
		||||
      m4/ulonglong.m4
 | 
			
		||||
      m4/visibility.m4
 | 
			
		||||
  '
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Tell gnulib to:
 | 
			
		||||
#   require LGPLv2+
 | 
			
		||||
#   apply any local diffs in gnulib/local/ dir
 | 
			
		||||
#   put *.m4 files in m4/ dir
 | 
			
		||||
#   put *.[ch] files in new gnulib/lib/ dir
 | 
			
		||||
#   import gnulib tests in new gnulib/tests/ dir
 | 
			
		||||
gnulib_name=libgnu
 | 
			
		||||
m4_base=m4
 | 
			
		||||
source_base=gnulib/lib
 | 
			
		||||
tests_base=gnulib/tests
 | 
			
		||||
gnulib_tool_option_extras="\
 | 
			
		||||
 --lgpl=2\
 | 
			
		||||
 --with-tests\
 | 
			
		||||
 --makefile-name=gnulib.mk\
 | 
			
		||||
 --avoid=pt_chown\
 | 
			
		||||
 --avoid=lock-tests\
 | 
			
		||||
"
 | 
			
		||||
local_gl_dir=gnulib/local
 | 
			
		||||
 | 
			
		||||
# Build prerequisites
 | 
			
		||||
# Note that some of these programs are only required for 'make dist' to
 | 
			
		||||
# succeed from a fresh git checkout; not all of these programs are
 | 
			
		||||
# required to run 'make dist' on a tarball.  As a special case, we want
 | 
			
		||||
# to require the equivalent of the Fedora python-devel package, but
 | 
			
		||||
# RHEL 5 lacks the witness python-config package; we hack around that
 | 
			
		||||
# old environment below.
 | 
			
		||||
buildreq="\
 | 
			
		||||
autoconf   2.59
 | 
			
		||||
automake   1.9.6
 | 
			
		||||
autopoint  -
 | 
			
		||||
gettext    0.17
 | 
			
		||||
git        1.5.5
 | 
			
		||||
gzip       -
 | 
			
		||||
libtool    -
 | 
			
		||||
patch      -
 | 
			
		||||
perl       5.5
 | 
			
		||||
perl::XML::XPath -
 | 
			
		||||
pkg-config -
 | 
			
		||||
python-config -
 | 
			
		||||
rpcgen     -
 | 
			
		||||
tar        -
 | 
			
		||||
xmllint	   -
 | 
			
		||||
xsltproc   -
 | 
			
		||||
"
 | 
			
		||||
# Use rpm as a fallback to bypass the bootstrap probe for python-config,
 | 
			
		||||
# for the sake of RHEL 5; without requiring it on newer systems that
 | 
			
		||||
# have python-config to begin with.
 | 
			
		||||
if `(${PYTHON_CONFIG-python-config} --version;
 | 
			
		||||
     test $? -lt 126 || rpm -q python-devel) >/dev/null 2>&1`; then
 | 
			
		||||
  PYTHON_CONFIG=true
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Automake requires that ChangeLog and AUTHORS exist.
 | 
			
		||||
touch AUTHORS ChangeLog || exit 1
 | 
			
		||||
 | 
			
		||||
# Override bootstrap's list - we don't use mdate-sh or texinfo.tex.
 | 
			
		||||
gnulib_extra_files="
 | 
			
		||||
        build-aux/install-sh
 | 
			
		||||
        build-aux/depcomp
 | 
			
		||||
        build-aux/config.guess
 | 
			
		||||
        build-aux/config.sub
 | 
			
		||||
        doc/INSTALL
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bootstrap_post_import_hook()
 | 
			
		||||
{
 | 
			
		||||
  # Change paths in gnulib/tests/gnulib.mk from "../../.." to "../..",
 | 
			
		||||
  # and make tests conditional by changing "TESTS" to "GNULIB_TESTS".
 | 
			
		||||
  m=gnulib/tests/gnulib.mk
 | 
			
		||||
  sed 's,\.\./\.\./\.\.,../..,g; s/^TESTS /GNULIB_TESTS /' $m > $m-t
 | 
			
		||||
  mv -f $m-t $m
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								build-aux/augeas-gentest.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										71
									
								
								build-aux/augeas-gentest.pl
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
#!/usr/bin/perl
 | 
			
		||||
#
 | 
			
		||||
# augeas-gentest.pl: Generate an augeas test file, from an
 | 
			
		||||
#                    example config file + test file template
 | 
			
		||||
#
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
# License as published by the Free Software Foundation; either
 | 
			
		||||
# version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This library is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library.  If not, see
 | 
			
		||||
# <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
# Authors:
 | 
			
		||||
#     Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
 | 
			
		||||
die "syntax: $0 CONFIG TEMPLATE AUGTEST\n" unless @ARGV == 3;
 | 
			
		||||
 | 
			
		||||
my $config = shift @ARGV;
 | 
			
		||||
my $template = shift @ARGV;
 | 
			
		||||
my $augtest = shift @ARGV;
 | 
			
		||||
 | 
			
		||||
open AUGTEST, ">", $augtest or die "cannot create $augtest: $!";
 | 
			
		||||
 | 
			
		||||
$SIG{__DIE__} = sub {
 | 
			
		||||
    unlink $augtest;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
open CONFIG, "<", $config or die "cannot read $config: $!";
 | 
			
		||||
open TEMPLATE, "<", $template or die "cannot read $template: $!";
 | 
			
		||||
 | 
			
		||||
my $group = 0;
 | 
			
		||||
while (<TEMPLATE>) {
 | 
			
		||||
    if (/::CONFIG::/) {
 | 
			
		||||
        my $group = 0;
 | 
			
		||||
        print AUGTEST "  let conf = \"";
 | 
			
		||||
        while (<CONFIG>) {
 | 
			
		||||
            if (/^#\w/) {
 | 
			
		||||
                s/^#//;
 | 
			
		||||
                s/\"/\\\"/g;
 | 
			
		||||
                print AUGTEST $_;
 | 
			
		||||
                $group = /\[\s$/;
 | 
			
		||||
            } elsif ($group) {
 | 
			
		||||
                s/\"/\\\"/g;
 | 
			
		||||
                if (/#\s*\]/) {
 | 
			
		||||
                    $group = 0;
 | 
			
		||||
                }
 | 
			
		||||
                if (/^#/) {
 | 
			
		||||
                    s/^#//;
 | 
			
		||||
                    print AUGTEST $_;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        print AUGTEST "\"\n";
 | 
			
		||||
    } else {
 | 
			
		||||
        print AUGTEST $_;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
close TEMPLATE;
 | 
			
		||||
close CONFIG;
 | 
			
		||||
close AUGTEST or die "cannot save $augtest: $!";
 | 
			
		||||
							
								
								
									
										204
									
								
								build-aux/bracket-spacing.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										204
									
								
								build-aux/bracket-spacing.pl
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
#!/usr/bin/perl
 | 
			
		||||
#
 | 
			
		||||
# bracket-spacing.pl: Report any usage of 'function (..args..)'
 | 
			
		||||
# Also check for other syntax issues, such as correct use of ';'
 | 
			
		||||
#
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
# License as published by the Free Software Foundation; either
 | 
			
		||||
# version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This library is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library.  If not, see
 | 
			
		||||
# <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
# Authors:
 | 
			
		||||
#     Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
 | 
			
		||||
my $ret = 0;
 | 
			
		||||
my $incomment = 0;
 | 
			
		||||
 | 
			
		||||
foreach my $file (@ARGV) {
 | 
			
		||||
    # Per-file variables for multiline Curly Bracket (cb_) check
 | 
			
		||||
    my $cb_linenum = 0;
 | 
			
		||||
    my $cb_code = "";
 | 
			
		||||
    my $cb_scolon = 0;
 | 
			
		||||
 | 
			
		||||
    open FILE, $file;
 | 
			
		||||
 | 
			
		||||
    while (defined (my $line = <FILE>)) {
 | 
			
		||||
        my $data = $line;
 | 
			
		||||
        # For temporary modifications
 | 
			
		||||
        my $tmpdata;
 | 
			
		||||
 | 
			
		||||
        # Kill any quoted , ; = or "
 | 
			
		||||
        $data =~ s/'[";,=]'/'X'/g;
 | 
			
		||||
 | 
			
		||||
        # Kill any quoted strings
 | 
			
		||||
        $data =~ s,"([^\\\"]|\\.)*","XXX",g;
 | 
			
		||||
 | 
			
		||||
        # Kill any C++ style comments
 | 
			
		||||
        $data =~ s,//.*$,//,;
 | 
			
		||||
 | 
			
		||||
        next if $data =~ /^#/;
 | 
			
		||||
 | 
			
		||||
        # Kill contents of multi-line comments
 | 
			
		||||
        # and detect end of multi-line comments
 | 
			
		||||
        if ($incomment) {
 | 
			
		||||
            if ($data =~ m,\*/,) {
 | 
			
		||||
                $incomment = 0;
 | 
			
		||||
                $data =~ s,^.*\*/,*/,;
 | 
			
		||||
            } else {
 | 
			
		||||
                $data = "";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Kill single line comments, and detect
 | 
			
		||||
        # start of multi-line comments
 | 
			
		||||
        if ($data =~ m,/\*.*\*/,) {
 | 
			
		||||
            $data =~ s,/\*.*\*/,/* */,;
 | 
			
		||||
        } elsif ($data =~ m,/\*,) {
 | 
			
		||||
            $incomment = 1;
 | 
			
		||||
            $data =~ s,/\*.*,/*,;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # We need to match things like
 | 
			
		||||
        #
 | 
			
		||||
        #  int foo (int bar, bool wizz);
 | 
			
		||||
        #  foo (bar, wizz);
 | 
			
		||||
        #
 | 
			
		||||
        # but not match things like:
 | 
			
		||||
        #
 | 
			
		||||
        #  typedef int (*foo)(bar wizz)
 | 
			
		||||
        #
 | 
			
		||||
        # we can't do this (efficiently) without
 | 
			
		||||
        # missing things like
 | 
			
		||||
        #
 | 
			
		||||
        #  foo (*bar, wizz);
 | 
			
		||||
        #
 | 
			
		||||
        # We also don't want to spoil the $data so it can be used
 | 
			
		||||
        # later on.
 | 
			
		||||
        $tmpdata = $data;
 | 
			
		||||
        while ($tmpdata =~ /(\w+)\s\((?!\*)/) {
 | 
			
		||||
            my $kw = $1;
 | 
			
		||||
 | 
			
		||||
            # Allow space after keywords only
 | 
			
		||||
            if ($kw =~ /^(if|for|while|switch|return)$/) {
 | 
			
		||||
                $tmpdata =~ s/($kw\s\()/XXX(/;
 | 
			
		||||
            } else {
 | 
			
		||||
                print "Whitespace after non-keyword:\n";
 | 
			
		||||
                print "$file:$.: $line";
 | 
			
		||||
                $ret = 1;
 | 
			
		||||
                last;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require whitespace immediately after keywords,
 | 
			
		||||
        # but none after the opening bracket
 | 
			
		||||
        if ($data =~ /\b(if|for|while|switch|return)\(/ ||
 | 
			
		||||
            $data =~ /\b(if|for|while|switch|return)\s+\(\s/) {
 | 
			
		||||
            print "No whitespace after keyword:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Forbid whitespace between )( of a function typedef
 | 
			
		||||
        if ($data =~ /\(\*\w+\)\s+\(/) {
 | 
			
		||||
            print "Whitespace between ')' and '(':\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Forbid whitespace following ( or prior to )
 | 
			
		||||
        if ($data =~ /\S\s+\)/ ||
 | 
			
		||||
            $data =~ /\(\s+\S/) {
 | 
			
		||||
            print "Whitespace after '(' or before ')':\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Forbid whitespace before ";" or ",". Things like below are allowed:
 | 
			
		||||
        #
 | 
			
		||||
        # 1) The expression is empty for "for" loop. E.g.
 | 
			
		||||
        #   for (i = 0; ; i++)
 | 
			
		||||
        #
 | 
			
		||||
        # 2) An empty statement. E.g.
 | 
			
		||||
        #   while (write(statuswrite, &status, 1) == -1 &&
 | 
			
		||||
        #          errno == EINTR)
 | 
			
		||||
        #       ;
 | 
			
		||||
        #
 | 
			
		||||
        if ($data =~ /[^;\s]\s+[;,]/) {
 | 
			
		||||
            print "Whitespace before (semi)colon:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require EOL, macro line continuation, or whitespace after ";".
 | 
			
		||||
        # Allow "for (;;)" as an exception.
 | 
			
		||||
        if ($data =~ /;[^	 \\\n;)]/) {
 | 
			
		||||
            print "Invalid character after semicolon:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require EOL, space, or enum/struct end after comma.
 | 
			
		||||
        if ($data =~ /,[^ \\\n)}]/) {
 | 
			
		||||
            print "Invalid character after comma:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require spaces around assignment '=', compounds and '=='
 | 
			
		||||
        # with the exception of virAssertCmpInt()
 | 
			
		||||
        $tmpdata = $data;
 | 
			
		||||
        $tmpdata =~ s/(virAssertCmpInt\(.* ).?=,/$1op,/;
 | 
			
		||||
        if ($tmpdata =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=[^=]/ ||
 | 
			
		||||
            $tmpdata =~ /=[^= \\\n]/) {
 | 
			
		||||
            print "Spacing around '=' or '==':\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # One line conditional statements with one line bodies should
 | 
			
		||||
        # not use curly brackets.
 | 
			
		||||
        if ($data =~ /^\s*(if|while|for)\b.*\{$/) {
 | 
			
		||||
            $cb_linenum = $.;
 | 
			
		||||
            $cb_code = $line;
 | 
			
		||||
            $cb_scolon = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # We need to check for exactly one semicolon inside the body,
 | 
			
		||||
        # because empty statements (e.g. with comment only) are
 | 
			
		||||
        # allowed
 | 
			
		||||
        if ($cb_linenum == $. - 1 && $data =~ /^[^;]*;[^;]*$/) {
 | 
			
		||||
            $cb_code .= $line;
 | 
			
		||||
            $cb_scolon = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($data =~ /^\s*}\s*$/ &&
 | 
			
		||||
            $cb_linenum == $. - 2 &&
 | 
			
		||||
            $cb_scolon) {
 | 
			
		||||
 | 
			
		||||
            print "Curly brackets around single-line body:\n";
 | 
			
		||||
            print "$file:$cb_linenum-$.:\n$cb_code$line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
 | 
			
		||||
            # There _should_ be no need to reset the values; but to
 | 
			
		||||
            # keep my inner peace...
 | 
			
		||||
            $cb_linenum = 0;
 | 
			
		||||
            $cb_scolon = 0;
 | 
			
		||||
            $cb_code = "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    close FILE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exit $ret;
 | 
			
		||||
@@ -1,198 +0,0 @@
 | 
			
		||||
#!/usr/bin/env perl
 | 
			
		||||
#
 | 
			
		||||
# check-spacing.pl: Report any usage of 'function (..args..)'
 | 
			
		||||
# Also check for other syntax issues, such as correct use of ';'
 | 
			
		||||
#
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
# License as published by the Free Software Foundation; either
 | 
			
		||||
# version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This library is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library.  If not, see
 | 
			
		||||
# <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
 | 
			
		||||
my $ret = 0;
 | 
			
		||||
my $incomment = 0;
 | 
			
		||||
 | 
			
		||||
foreach my $file (@ARGV) {
 | 
			
		||||
    # Per-file variables for multiline Curly Bracket (cb_) check
 | 
			
		||||
    my $cb_linenum = 0;
 | 
			
		||||
    my $cb_code = "";
 | 
			
		||||
    my $cb_scolon = 0;
 | 
			
		||||
 | 
			
		||||
    open FILE, $file;
 | 
			
		||||
 | 
			
		||||
    while (defined (my $line = <FILE>)) {
 | 
			
		||||
        my $data = $line;
 | 
			
		||||
        # For temporary modifications
 | 
			
		||||
        my $tmpdata;
 | 
			
		||||
 | 
			
		||||
        # Kill any quoted , ; = or "
 | 
			
		||||
        $data =~ s/'[";,=]'/'X'/g;
 | 
			
		||||
 | 
			
		||||
        # Kill any quoted strings
 | 
			
		||||
        $data =~ s,"(?:[^\\\"]|\\.)*","XXX",g;
 | 
			
		||||
 | 
			
		||||
        next if $data =~ /^#/;
 | 
			
		||||
 | 
			
		||||
        # Kill contents of multi-line comments
 | 
			
		||||
        # and detect end of multi-line comments
 | 
			
		||||
        if ($incomment) {
 | 
			
		||||
            if ($data =~ m,\*/,) {
 | 
			
		||||
                $incomment = 0;
 | 
			
		||||
                $data =~ s,^.*\*/,*/,;
 | 
			
		||||
            } else {
 | 
			
		||||
                $data = "";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Kill single line comments, and detect
 | 
			
		||||
        # start of multi-line comments
 | 
			
		||||
        if ($data =~ m,/\*.*\*/,) {
 | 
			
		||||
            $data =~ s,/\*.*\*/,/* */,;
 | 
			
		||||
        } elsif ($data =~ m,/\*,) {
 | 
			
		||||
            $incomment = 1;
 | 
			
		||||
            $data =~ s,/\*.*,/*,;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # We need to match things like
 | 
			
		||||
        #
 | 
			
		||||
        #  int foo (int bar, bool wizz);
 | 
			
		||||
        #  foo (bar, wizz);
 | 
			
		||||
        #
 | 
			
		||||
        # but not match things like:
 | 
			
		||||
        #
 | 
			
		||||
        #  typedef int (*foo)(bar wizz)
 | 
			
		||||
        #
 | 
			
		||||
        # we can't do this (efficiently) without
 | 
			
		||||
        # missing things like
 | 
			
		||||
        #
 | 
			
		||||
        #  foo (*bar, wizz);
 | 
			
		||||
        #
 | 
			
		||||
        # We also don't want to spoil the $data so it can be used
 | 
			
		||||
        # later on.
 | 
			
		||||
        $tmpdata = $data;
 | 
			
		||||
        while ($tmpdata =~ /(\w+)\s\((?!\*)/) {
 | 
			
		||||
            my $kw = $1;
 | 
			
		||||
 | 
			
		||||
            # Allow space after keywords only
 | 
			
		||||
            if ($kw =~ /^(?:if|for|while|switch|return)$/) {
 | 
			
		||||
                $tmpdata =~ s/(?:$kw\s\()/XXX(/;
 | 
			
		||||
            } else {
 | 
			
		||||
                print "Whitespace after non-keyword:\n";
 | 
			
		||||
                print "$file:$.: $line";
 | 
			
		||||
                $ret = 1;
 | 
			
		||||
                last;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require whitespace immediately after keywords
 | 
			
		||||
        if ($data =~ /\b(?:if|for|while|switch|return)\(/) {
 | 
			
		||||
            print "No whitespace after keyword:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Forbid whitespace between )( of a function typedef
 | 
			
		||||
        if ($data =~ /\(\*\w+\)\s+\(/) {
 | 
			
		||||
            print "Whitespace between ')' and '(':\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Forbid whitespace following ( or prior to )
 | 
			
		||||
        # but allow whitespace before ) on a single line
 | 
			
		||||
        # (optionally followed by a semicolon)
 | 
			
		||||
        if (($data =~ /\s\)/ && not $data =~ /^\s+\);?$/) ||
 | 
			
		||||
            $data =~ /\((?!$)\s/) {
 | 
			
		||||
            print "Whitespace after '(' or before ')':\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Forbid whitespace before ";" or ",". Things like below are allowed:
 | 
			
		||||
        #
 | 
			
		||||
        # 1) The expression is empty for "for" loop. E.g.
 | 
			
		||||
        #   for (i = 0; ; i++)
 | 
			
		||||
        #
 | 
			
		||||
        # 2) An empty statement. E.g.
 | 
			
		||||
        #   while (write(statuswrite, &status, 1) == -1 &&
 | 
			
		||||
        #          errno == EINTR)
 | 
			
		||||
        #       ;
 | 
			
		||||
        #
 | 
			
		||||
        if ($data =~ /\s[;,]/) {
 | 
			
		||||
            unless ($data =~ /\S; ; / ||
 | 
			
		||||
                    $data =~ /^\s+;/) {
 | 
			
		||||
                print "Whitespace before semicolon or comma:\n";
 | 
			
		||||
                print "$file:$.: $line";
 | 
			
		||||
                $ret = 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require EOL, macro line continuation, or whitespace after ";".
 | 
			
		||||
        # Allow "for (;;)" as an exception.
 | 
			
		||||
        if ($data =~ /;[^	 \\\n;)]/) {
 | 
			
		||||
            print "Invalid character after semicolon:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require EOL, space, or enum/struct end after comma.
 | 
			
		||||
        if ($data =~ /,[^ \\\n)}]/) {
 | 
			
		||||
            print "Invalid character after comma:\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Require spaces around assignment '=', compounds and '=='
 | 
			
		||||
        if ($data =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=/ ||
 | 
			
		||||
            $data =~ /=[^= \\\n]/) {
 | 
			
		||||
            print "Spacing around '=' or '==':\n";
 | 
			
		||||
            print "$file:$.: $line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # One line conditional statements with one line bodies should
 | 
			
		||||
        # not use curly brackets.
 | 
			
		||||
        if ($data =~ /^\s*(if|while|for)\b.*\{$/) {
 | 
			
		||||
            $cb_linenum = $.;
 | 
			
		||||
            $cb_code = $line;
 | 
			
		||||
            $cb_scolon = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # We need to check for exactly one semicolon inside the body,
 | 
			
		||||
        # because empty statements (e.g. with comment only) are
 | 
			
		||||
        # allowed
 | 
			
		||||
        if ($cb_linenum == $. - 1 && $data =~ /^[^;]*;[^;]*$/) {
 | 
			
		||||
            $cb_code .= $line;
 | 
			
		||||
            $cb_scolon = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($data =~ /^\s*}\s*$/ &&
 | 
			
		||||
            $cb_linenum == $. - 2 &&
 | 
			
		||||
            $cb_scolon) {
 | 
			
		||||
 | 
			
		||||
            print "Curly brackets around single-line body:\n";
 | 
			
		||||
            print "$file:$cb_linenum-$.:\n$cb_code$line";
 | 
			
		||||
            $ret = 1;
 | 
			
		||||
 | 
			
		||||
            # There _should_ be no need to reset the values; but to
 | 
			
		||||
            # keep my inner peace...
 | 
			
		||||
            $cb_linenum = 0;
 | 
			
		||||
            $cb_scolon = 0;
 | 
			
		||||
            $cb_code = "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    close FILE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exit $ret;
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,226 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#! -*-perl-*-
 | 
			
		||||
 | 
			
		||||
# Detect instances of "if (p) free (p);".
 | 
			
		||||
# Likewise "if (p != 0)", "if (0 != p)", or with NULL; and with braces.
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2008-2019 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 <https://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
# Written by Jim Meyering
 | 
			
		||||
 | 
			
		||||
# This is a prologue that allows to run a perl script as an executable
 | 
			
		||||
# on systems that are compliant to a POSIX version before POSIX:2017.
 | 
			
		||||
# On such systems, the usual invocation of an executable through execlp()
 | 
			
		||||
# or execvp() fails with ENOEXEC if it is a script that does not start
 | 
			
		||||
# with a #! line.  The script interpreter mentioned in the #! line has
 | 
			
		||||
# to be /bin/sh, because on GuixSD systems that is the only program that
 | 
			
		||||
# has a fixed file name.  The second line is essential for perl and is
 | 
			
		||||
# also useful for editing this file in Emacs.  The next two lines below
 | 
			
		||||
# are valid code in both sh and perl.  When executed by sh, they re-execute
 | 
			
		||||
# the script through the perl program found in $PATH.  The '-x' option
 | 
			
		||||
# is essential as well; without it, perl would re-execute the script
 | 
			
		||||
# through /bin/sh.  When executed by  perl, the next two lines are a no-op.
 | 
			
		||||
eval 'exec perl -wSx "$0" "$@"'
 | 
			
		||||
     if 0;
 | 
			
		||||
 | 
			
		||||
my $VERSION = '2018-03-07 03:47'; # UTC
 | 
			
		||||
# The definition above must lie within the first 8 lines in order
 | 
			
		||||
# for the Emacs time-stamp write hook (at end) to update it.
 | 
			
		||||
# If you change this file with Emacs, please let the write hook
 | 
			
		||||
# do its job.  Otherwise, update this string manually.
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
use Getopt::Long;
 | 
			
		||||
 | 
			
		||||
(my $ME = $0) =~ s|.*/||;
 | 
			
		||||
 | 
			
		||||
# use File::Coda; # https://meyering.net/code/Coda/
 | 
			
		||||
END {
 | 
			
		||||
  defined fileno STDOUT or return;
 | 
			
		||||
  close STDOUT and return;
 | 
			
		||||
  warn "$ME: failed to close standard output: $!\n";
 | 
			
		||||
  $? ||= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub usage ($)
 | 
			
		||||
{
 | 
			
		||||
  my ($exit_code) = @_;
 | 
			
		||||
  my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
 | 
			
		||||
  if ($exit_code != 0)
 | 
			
		||||
    {
 | 
			
		||||
      print $STREAM "Try '$ME --help' for more information.\n";
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      print $STREAM <<EOF;
 | 
			
		||||
Usage: $ME [OPTIONS] FILE...
 | 
			
		||||
 | 
			
		||||
Detect any instance in FILE of a useless "if" test before a free call, e.g.,
 | 
			
		||||
"if (p) free (p);".  Any such test may be safely removed without affecting
 | 
			
		||||
the semantics of the C code in FILE.  Use --name=FOO --name=BAR to also
 | 
			
		||||
detect free-like functions named FOO and BAR.
 | 
			
		||||
 | 
			
		||||
OPTIONS:
 | 
			
		||||
 | 
			
		||||
   --list       print only the name of each matching FILE (\\0-terminated)
 | 
			
		||||
   --name=N     add name N to the list of \'free\'-like functions to detect;
 | 
			
		||||
                  may be repeated
 | 
			
		||||
 | 
			
		||||
   --help       display this help and exit
 | 
			
		||||
   --version    output version information and exit
 | 
			
		||||
 | 
			
		||||
Exit status:
 | 
			
		||||
 | 
			
		||||
  0   one or more matches
 | 
			
		||||
  1   no match
 | 
			
		||||
  2   an error
 | 
			
		||||
 | 
			
		||||
EXAMPLE:
 | 
			
		||||
 | 
			
		||||
For example, this command prints all removable "if" tests before "free"
 | 
			
		||||
and "kfree" calls in the linux kernel sources:
 | 
			
		||||
 | 
			
		||||
    git ls-files -z |xargs -0 $ME --name=kfree
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
    }
 | 
			
		||||
  exit $exit_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub is_NULL ($)
 | 
			
		||||
{
 | 
			
		||||
  my ($expr) = @_;
 | 
			
		||||
  return ($expr eq 'NULL' || $expr eq '0');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  sub EXIT_MATCH {0}
 | 
			
		||||
  sub EXIT_NO_MATCH {1}
 | 
			
		||||
  sub EXIT_ERROR {2}
 | 
			
		||||
  my $err = EXIT_NO_MATCH;
 | 
			
		||||
 | 
			
		||||
  my $list;
 | 
			
		||||
  my @name = qw(free);
 | 
			
		||||
  GetOptions
 | 
			
		||||
    (
 | 
			
		||||
     help => sub { usage 0 },
 | 
			
		||||
     version => sub { print "$ME version $VERSION\n"; exit },
 | 
			
		||||
     list => \$list,
 | 
			
		||||
     'name=s@' => \@name,
 | 
			
		||||
    ) or usage 1;
 | 
			
		||||
 | 
			
		||||
  # Make sure we have the right number of non-option arguments.
 | 
			
		||||
  # Always tell the user why we fail.
 | 
			
		||||
  @ARGV < 1
 | 
			
		||||
    and (warn "$ME: missing FILE argument\n"), usage EXIT_ERROR;
 | 
			
		||||
 | 
			
		||||
  my $or = join '|', @name;
 | 
			
		||||
  my $regexp = qr/(?:$or)/;
 | 
			
		||||
 | 
			
		||||
  # Set the input record separator.
 | 
			
		||||
  # Note: this makes it impractical to print line numbers.
 | 
			
		||||
  $/ = '"';
 | 
			
		||||
 | 
			
		||||
  my $found_match = 0;
 | 
			
		||||
 FILE:
 | 
			
		||||
  foreach my $file (@ARGV)
 | 
			
		||||
    {
 | 
			
		||||
      open FH, '<', $file
 | 
			
		||||
        or (warn "$ME: can't open '$file' for reading: $!\n"),
 | 
			
		||||
          $err = EXIT_ERROR, next;
 | 
			
		||||
      while (defined (my $line = <FH>))
 | 
			
		||||
        {
 | 
			
		||||
          # Skip non-matching lines early to save time
 | 
			
		||||
          $line =~ /\bif\b/
 | 
			
		||||
            or next;
 | 
			
		||||
          while ($line =~
 | 
			
		||||
              /\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
 | 
			
		||||
              #  1          2                  3
 | 
			
		||||
               (?:   \s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;|
 | 
			
		||||
                \s*\{\s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;\s*\}))/sxg)
 | 
			
		||||
            {
 | 
			
		||||
              my $all = $1;
 | 
			
		||||
              my ($lhs, $rhs) = ($2, $3);
 | 
			
		||||
              my ($free_opnd, $braced_free_opnd) = ($4, $5);
 | 
			
		||||
              my $non_NULL;
 | 
			
		||||
              if (!defined $rhs) { $non_NULL = $lhs }
 | 
			
		||||
              elsif (is_NULL $rhs) { $non_NULL = $lhs }
 | 
			
		||||
              elsif (is_NULL $lhs) { $non_NULL = $rhs }
 | 
			
		||||
              else { next }
 | 
			
		||||
 | 
			
		||||
              # Compare the non-NULL part of the "if" expression and the
 | 
			
		||||
              # free'd expression, without regard to white space.
 | 
			
		||||
              $non_NULL =~ tr/ \t//d;
 | 
			
		||||
              my $e2 = defined $free_opnd ? $free_opnd : $braced_free_opnd;
 | 
			
		||||
              $e2 =~ tr/ \t//d;
 | 
			
		||||
              if ($non_NULL eq $e2)
 | 
			
		||||
                {
 | 
			
		||||
                  $found_match = 1;
 | 
			
		||||
                  $list
 | 
			
		||||
                    and (print "$file\0"), next FILE;
 | 
			
		||||
                  print "$file: $all\n";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  continue
 | 
			
		||||
    {
 | 
			
		||||
      close FH;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  $found_match && $err == EXIT_NO_MATCH
 | 
			
		||||
    and $err = EXIT_MATCH;
 | 
			
		||||
 | 
			
		||||
  exit $err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
my $foo = <<'EOF';
 | 
			
		||||
# The above is to *find* them.
 | 
			
		||||
# This adjusts them, removing the unnecessary "if (p)" part.
 | 
			
		||||
 | 
			
		||||
# FIXME: do something like this as an option (doesn't do braces):
 | 
			
		||||
free=xfree
 | 
			
		||||
git grep -l -z "$free *(" \
 | 
			
		||||
  | xargs -0 useless-if-before-free -l --name="$free" \
 | 
			
		||||
  | xargs -0 perl -0x3b -pi -e \
 | 
			
		||||
   's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s+('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\)\s*;)/$2/s'
 | 
			
		||||
 | 
			
		||||
# Use the following to remove redundant uses of kfree inside braces.
 | 
			
		||||
# Note that -0777 puts perl in slurp-whole-file mode;
 | 
			
		||||
# but we have plenty of memory, these days...
 | 
			
		||||
free=kfree
 | 
			
		||||
git grep -l -z "$free *(" \
 | 
			
		||||
  | xargs -0 useless-if-before-free -l --name="$free" \
 | 
			
		||||
  | xargs -0 perl -0777 -pi -e \
 | 
			
		||||
     's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s*\{\s*('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\);)\s*\}[^\n]*$/$2/gms'
 | 
			
		||||
 | 
			
		||||
Be careful that the result of the above transformation is valid.
 | 
			
		||||
If the matched string is followed by "else", then obviously, it won't be.
 | 
			
		||||
 | 
			
		||||
When modifying files, refuse to process anything other than a regular file.
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
## Local Variables:
 | 
			
		||||
## mode: perl
 | 
			
		||||
## indent-tabs-mode: nil
 | 
			
		||||
## eval: (add-hook 'before-save-hook 'time-stamp)
 | 
			
		||||
## time-stamp-line-limit: 50
 | 
			
		||||
## time-stamp-start: "my $VERSION = '"
 | 
			
		||||
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
 | 
			
		||||
## time-stamp-time-zone: "UTC0"
 | 
			
		||||
## time-stamp-end: "'; # UTC"
 | 
			
		||||
## End:
 | 
			
		||||
@@ -1,113 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# List version-controlled file names.
 | 
			
		||||
 | 
			
		||||
# Print a version string.
 | 
			
		||||
scriptversion=2018-03-07.03; # UTC
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2006-2019 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 <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# List the specified version-controlled files.
 | 
			
		||||
# With no argument, list them all.  With a single DIRECTORY argument,
 | 
			
		||||
# list the version-controlled files in that directory.
 | 
			
		||||
 | 
			
		||||
# If there's an argument, it must be a single, "."-relative directory name.
 | 
			
		||||
# cvsu is part of the cvsutils package: http://www.red-bean.com/cvsutils/
 | 
			
		||||
 | 
			
		||||
postprocess=
 | 
			
		||||
case $1 in
 | 
			
		||||
  --help) cat <<EOF
 | 
			
		||||
Usage: $0 [-C SRCDIR] [DIR...]
 | 
			
		||||
 | 
			
		||||
Output a list of version-controlled files in DIR (default .), relative to
 | 
			
		||||
SRCDIR (default .).  SRCDIR must be the top directory of a checkout.
 | 
			
		||||
 | 
			
		||||
Options:
 | 
			
		||||
  --help     print this help, then exit
 | 
			
		||||
  --version  print version number, then exit
 | 
			
		||||
  -C SRCDIR  change directory to SRCDIR before generating list
 | 
			
		||||
 | 
			
		||||
Report bugs and patches to <bug-gnulib@gnu.org>.
 | 
			
		||||
EOF
 | 
			
		||||
    exit ;;
 | 
			
		||||
 | 
			
		||||
  --version)
 | 
			
		||||
    year=`echo "$scriptversion" | sed 's/[^0-9].*//'`
 | 
			
		||||
    cat <<EOF
 | 
			
		||||
vc-list-files $scriptversion
 | 
			
		||||
Copyright (C) $year Free Software Foundation, Inc,
 | 
			
		||||
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
 | 
			
		||||
This is free software: you are free to change and redistribute it.
 | 
			
		||||
There is NO WARRANTY, to the extent permitted by law.
 | 
			
		||||
EOF
 | 
			
		||||
    exit ;;
 | 
			
		||||
 | 
			
		||||
  -C)
 | 
			
		||||
    test "$2" = . || postprocess="| sed 's|^|$2/|'"
 | 
			
		||||
    cd "$2" || exit 1
 | 
			
		||||
    shift; shift ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
test $# = 0 && set .
 | 
			
		||||
 | 
			
		||||
for dir
 | 
			
		||||
do
 | 
			
		||||
  if test -d .git || test -f .git; then
 | 
			
		||||
    test "x$dir" = x. \
 | 
			
		||||
      && dir= sed_esc= \
 | 
			
		||||
      || { dir="$dir/"; sed_esc=`echo "$dir"|env sed 's,\([\\/]\),\\\\\1,g'`; }
 | 
			
		||||
    # Ignore git symlinks - either they point into the tree, in which case
 | 
			
		||||
    # we don't need to visit the target twice, or they point somewhere
 | 
			
		||||
    # else (often into a submodule), in which case the content does not
 | 
			
		||||
    # belong to this package.
 | 
			
		||||
    eval exec git ls-tree -r 'HEAD:"$dir"' \
 | 
			
		||||
      \| sed -n '"s/^100[^	]*./$sed_esc/p"' $postprocess
 | 
			
		||||
  elif test -d .hg; then
 | 
			
		||||
    eval exec hg locate '"$dir/*"' $postprocess
 | 
			
		||||
  elif test -d .bzr; then
 | 
			
		||||
    test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
 | 
			
		||||
    eval exec bzr ls -R --versioned '"$dir"' $postprocess
 | 
			
		||||
  elif test -d CVS; then
 | 
			
		||||
    test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
 | 
			
		||||
    if test -x build-aux/cvsu; then
 | 
			
		||||
      eval build-aux/cvsu --find --types=AFGM '"$dir"' $postprocess
 | 
			
		||||
    elif (cvsu --help) >/dev/null 2>&1; then
 | 
			
		||||
      eval cvsu --find --types=AFGM '"$dir"' $postprocess
 | 
			
		||||
    else
 | 
			
		||||
      eval awk -F/ \''{			\
 | 
			
		||||
          if (!$1 && $3 !~ /^-/) {	\
 | 
			
		||||
            f=FILENAME;			\
 | 
			
		||||
            if (f ~ /CVS\/Entries$/)	\
 | 
			
		||||
              f = substr(f, 1, length(f)-11); \
 | 
			
		||||
            print f $2;			\
 | 
			
		||||
          }}'\''				\
 | 
			
		||||
        `find "$dir" -name Entries -print` /dev/null' $postprocess
 | 
			
		||||
    fi
 | 
			
		||||
  elif test -d .svn; then
 | 
			
		||||
    eval exec svn list -R '"$dir"' $postprocess
 | 
			
		||||
  else
 | 
			
		||||
    echo "$0: Failed to determine type of version control used in `pwd`" 1>&2
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Local variables:
 | 
			
		||||
# eval: (add-hook 'before-save-hook 'time-stamp)
 | 
			
		||||
# time-stamp-start: "scriptversion="
 | 
			
		||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
			
		||||
# time-stamp-time-zone: "UTC0"
 | 
			
		||||
# time-stamp-end: "; # UTC"
 | 
			
		||||
# End:
 | 
			
		||||
							
								
								
									
										273
									
								
								ci/Makefile
									
									
									
									
									
								
							
							
						
						
									
										273
									
								
								ci/Makefile
									
									
									
									
									
								
							@@ -1,273 +0,0 @@
 | 
			
		||||
# -*- makefile -*-
 | 
			
		||||
# vim: filetype=make
 | 
			
		||||
 | 
			
		||||
# The root directory of the libvirt.git checkout
 | 
			
		||||
CI_GIT_ROOT = $(shell git rev-parse --show-toplevel)
 | 
			
		||||
 | 
			
		||||
# The root directory for all CI-related contents
 | 
			
		||||
CI_ROOTDIR = $(CI_GIT_ROOT)/ci
 | 
			
		||||
 | 
			
		||||
# The directory holding content on the host that we will
 | 
			
		||||
# expose to the container.
 | 
			
		||||
CI_SCRATCHDIR = $(CI_ROOTDIR)/scratch
 | 
			
		||||
 | 
			
		||||
# The directory holding the clone of the git repo that
 | 
			
		||||
# we will expose to the container
 | 
			
		||||
CI_HOST_SRCDIR = $(CI_SCRATCHDIR)/src
 | 
			
		||||
 | 
			
		||||
# The directory holding the source inside the
 | 
			
		||||
# container, i.e. where we want to expose
 | 
			
		||||
# the $(CI_HOST_SRCDIR) directory from the host
 | 
			
		||||
CI_CONT_SRCDIR = $(CI_USER_HOME)/libvirt
 | 
			
		||||
 | 
			
		||||
# Relative directory to perform the build in. This
 | 
			
		||||
# defaults to using a separate build dir, but can be
 | 
			
		||||
# set to empty string for an in-source tree build.
 | 
			
		||||
CI_VPATH = build
 | 
			
		||||
 | 
			
		||||
# The directory holding the build output inside the
 | 
			
		||||
# container.
 | 
			
		||||
CI_CONT_BUILDDIR = $(CI_CONT_SRCDIR)/$(CI_VPATH)
 | 
			
		||||
 | 
			
		||||
# Can be overridden with mingw{32,64}-configure if desired
 | 
			
		||||
CI_CONFIGURE = $(CI_CONT_SRCDIR)/configure
 | 
			
		||||
 | 
			
		||||
# Default to using all possible CPUs
 | 
			
		||||
CI_SMP = $(shell getconf _NPROCESSORS_ONLN)
 | 
			
		||||
 | 
			
		||||
# Any extra arguments to pass to make
 | 
			
		||||
CI_MAKE_ARGS =
 | 
			
		||||
 | 
			
		||||
# Any extra arguments to pass to configure
 | 
			
		||||
CI_CONFIGURE_ARGS =
 | 
			
		||||
 | 
			
		||||
# Script containing environment preparation steps
 | 
			
		||||
CI_PREPARE_SCRIPT = $(CI_ROOTDIR)/prepare.sh
 | 
			
		||||
 | 
			
		||||
# Script containing build instructions
 | 
			
		||||
CI_BUILD_SCRIPT = $(CI_ROOTDIR)/build.sh
 | 
			
		||||
 | 
			
		||||
# Location of the container images we're going to pull
 | 
			
		||||
# Can be useful to overridde to use a locally built
 | 
			
		||||
# image instead
 | 
			
		||||
CI_IMAGE_PREFIX = quay.io/libvirt/buildenv-libvirt-
 | 
			
		||||
 | 
			
		||||
# The default tag is ':latest' but if the container
 | 
			
		||||
# repo above uses different conventions this can override it
 | 
			
		||||
CI_IMAGE_TAG = :latest
 | 
			
		||||
 | 
			
		||||
# We delete the virtual root after completion, set
 | 
			
		||||
# to 0 if you need to keep it around for debugging
 | 
			
		||||
CI_CLEAN = 1
 | 
			
		||||
 | 
			
		||||
# We'll always freshly clone the virtual root each
 | 
			
		||||
# time in case it was not cleaned up before. Set
 | 
			
		||||
# to 1 if you want to try restarting a previously
 | 
			
		||||
# preserved env
 | 
			
		||||
CI_REUSE = 0
 | 
			
		||||
 | 
			
		||||
# We need the container process to run with current host IDs
 | 
			
		||||
# so that it can access the passed in build directory
 | 
			
		||||
CI_UID = $(shell id -u)
 | 
			
		||||
CI_GID = $(shell id -g)
 | 
			
		||||
 | 
			
		||||
# We also need the user's login and home directory to prepare the
 | 
			
		||||
# environment the way some programs expect it
 | 
			
		||||
CI_USER_LOGIN = $(shell echo "$$USER")
 | 
			
		||||
CI_USER_HOME = $(shell echo "$$HOME")
 | 
			
		||||
 | 
			
		||||
CI_ENGINE = auto
 | 
			
		||||
# Container engine we are going to use, can be overridden per make
 | 
			
		||||
# invocation, if it is not we try podman and then default to docker.
 | 
			
		||||
ifeq ($(CI_ENGINE),auto)
 | 
			
		||||
	override CI_ENGINE = $(shell podman version >/dev/null 2>&1 && echo podman || echo docker)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# IDs you run as do not need to exist in
 | 
			
		||||
# the container's /etc/passwd & /etc/group files, but
 | 
			
		||||
# if they do not, then libvirt's 'make check' will fail
 | 
			
		||||
# many tests.
 | 
			
		||||
 | 
			
		||||
# We do not directly mount /etc/{passwd,group} as Docker
 | 
			
		||||
# is liable to mess with SELinux labelling which will
 | 
			
		||||
# then prevent the host accessing them. And podman cannot
 | 
			
		||||
# relabel the files due to it running rootless. So
 | 
			
		||||
# copying them first is safer and less error-prone.
 | 
			
		||||
CI_PWDB_MOUNTS = \
 | 
			
		||||
	--volume $(CI_SCRATCHDIR)/group:/etc/group:ro,z \
 | 
			
		||||
	--volume $(CI_SCRATCHDIR)/passwd:/etc/passwd:ro,z \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
CI_HOME_MOUNTS = \
 | 
			
		||||
	--volume $(CI_SCRATCHDIR)/home:$(CI_USER_HOME):z \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
CI_SCRIPT_MOUNTS = \
 | 
			
		||||
	--volume $(CI_SCRATCHDIR)/prepare:$(CI_USER_HOME)/prepare:z \
 | 
			
		||||
	--volume $(CI_SCRATCHDIR)/build:$(CI_USER_HOME)/build:z \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
# Docker containers can have very large ulimits
 | 
			
		||||
# for nofiles - as much as 1048576. This makes
 | 
			
		||||
# libvirt very slow at exec'ing programs.
 | 
			
		||||
CI_ULIMIT_FILES = 1024
 | 
			
		||||
 | 
			
		||||
ifeq ($(CI_ENGINE),podman)
 | 
			
		||||
	# Podman cannot reuse host namespace when running non-root
 | 
			
		||||
	# containers.  Until support for --keep-uid is added we can
 | 
			
		||||
	# just create another mapping that will do that for us.
 | 
			
		||||
	# Beware, that in {uid,git}map=container_id:host_id:range, the
 | 
			
		||||
	# host_id does actually refer to the uid in the first mapping
 | 
			
		||||
	# where 0 (root) is mapped to the current user and rest is
 | 
			
		||||
	# offset.
 | 
			
		||||
	#
 | 
			
		||||
	# In order to set up this mapping, we need to keep all the
 | 
			
		||||
	# user IDs to prevent possible errors as some images might
 | 
			
		||||
	# expect UIDs up to 90000 (looking at you fedora), so we don't
 | 
			
		||||
	# want the overflowuid to be used for them.  For mapping all
 | 
			
		||||
	# the other users properly, some math needs to be done.
 | 
			
		||||
	# Don't worry, it's just addition and subtraction.
 | 
			
		||||
	#
 | 
			
		||||
	# 65536 ought to be enough (tm), but for really rare cases the
 | 
			
		||||
	# maximums might need to be higher, but that only happens when
 | 
			
		||||
	# your /etc/sub{u,g}id allow users to have more IDs.  Unless
 | 
			
		||||
	# --keep-uid is supported, let's do this in a way that should
 | 
			
		||||
	# work for everyone.
 | 
			
		||||
	CI_MAX_UID = $(shell sed -n "s/^$(CI_USER_LOGIN):[^:]\+://p" /etc/subuid)
 | 
			
		||||
	CI_MAX_GID = $(shell sed -n "s/^$(CI_USER_LOGIN):[^:]\+://p" /etc/subgid)
 | 
			
		||||
	ifeq ($(CI_MAX_UID),)
 | 
			
		||||
		CI_MAX_UID = 65536
 | 
			
		||||
	endif
 | 
			
		||||
	ifeq ($(CI_MAX_GID),)
 | 
			
		||||
		CI_MAX_GID = 65536
 | 
			
		||||
	endif
 | 
			
		||||
	CI_UID_OTHER = $(shell echo $$(($(CI_UID)+1)))
 | 
			
		||||
	CI_GID_OTHER = $(shell echo $$(($(CI_GID)+1)))
 | 
			
		||||
	CI_UID_OTHER_RANGE = $(shell echo $$(($(CI_MAX_UID)-$(CI_UID))))
 | 
			
		||||
	CI_GID_OTHER_RANGE = $(shell echo $$(($(CI_MAX_GID)-$(CI_GID))))
 | 
			
		||||
 | 
			
		||||
	CI_PODMAN_ARGS = \
 | 
			
		||||
		--uidmap 0:1:$(CI_UID) \
 | 
			
		||||
		--uidmap $(CI_UID):0:1 \
 | 
			
		||||
		--uidmap $(CI_UID_OTHER):$(CI_UID_OTHER):$(CI_UID_OTHER_RANGE) \
 | 
			
		||||
		--gidmap 0:1:$(CI_GID) \
 | 
			
		||||
		--gidmap $(CI_GID):0:1 \
 | 
			
		||||
		--gidmap $(CI_GID_OTHER):$(CI_GID_OTHER):$(CI_GID_OTHER_RANGE) \
 | 
			
		||||
		$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Args to use when cloning a git repo.
 | 
			
		||||
#  -c  stop it complaining about checking out a random hash
 | 
			
		||||
#  -q  stop it displaying progress info for local clone
 | 
			
		||||
#  --local ensure we don't actually copy files
 | 
			
		||||
CI_GIT_ARGS = \
 | 
			
		||||
	-c advice.detachedHead=false \
 | 
			
		||||
	-q \
 | 
			
		||||
	--local  \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
# Args to use when running the container
 | 
			
		||||
#   --rm      stop inactive containers getting left behind
 | 
			
		||||
#   --user    we execute as the same user & group account
 | 
			
		||||
#             as dev so that file ownership matches host
 | 
			
		||||
#             instead of root:root
 | 
			
		||||
#   --volume  to pass in the cloned git repo & config
 | 
			
		||||
#   --ulimit  lower files limit for performance reasons
 | 
			
		||||
#   --interactive
 | 
			
		||||
#   --tty     Ensure we have ability to Ctrl-C the build
 | 
			
		||||
CI_ENGINE_ARGS = \
 | 
			
		||||
	--rm \
 | 
			
		||||
	--interactive \
 | 
			
		||||
	--tty \
 | 
			
		||||
	$(CI_PODMAN_ARGS) \
 | 
			
		||||
	$(CI_PWDB_MOUNTS) \
 | 
			
		||||
	$(CI_HOME_MOUNTS) \
 | 
			
		||||
	$(CI_SCRIPT_MOUNTS) \
 | 
			
		||||
	--volume $(CI_HOST_SRCDIR):$(CI_CONT_SRCDIR):z \
 | 
			
		||||
	--ulimit nofile=$(CI_ULIMIT_FILES):$(CI_ULIMIT_FILES) \
 | 
			
		||||
	--cap-add=SYS_PTRACE \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
ci-check-engine:
 | 
			
		||||
	@echo -n "Checking if $(CI_ENGINE) is available..." && \
 | 
			
		||||
	$(CI_ENGINE) version 1>/dev/null && echo "yes"
 | 
			
		||||
 | 
			
		||||
ci-prepare-tree: ci-check-engine
 | 
			
		||||
	@test "$(CI_REUSE)" != "1" && rm -rf $(CI_SCRATCHDIR) || :
 | 
			
		||||
	@if ! test -d $(CI_SCRATCHDIR) ; then \
 | 
			
		||||
		mkdir -p $(CI_SCRATCHDIR); \
 | 
			
		||||
		cp /etc/passwd $(CI_SCRATCHDIR); \
 | 
			
		||||
		cp /etc/group $(CI_SCRATCHDIR); \
 | 
			
		||||
		mkdir -p $(CI_SCRATCHDIR)/home; \
 | 
			
		||||
		cp "$(CI_PREPARE_SCRIPT)" $(CI_SCRATCHDIR)/prepare; \
 | 
			
		||||
		cp "$(CI_BUILD_SCRIPT)" $(CI_SCRATCHDIR)/build; \
 | 
			
		||||
		chmod +x "$(CI_SCRATCHDIR)/prepare" "$(CI_SCRATCHDIR)/build"; \
 | 
			
		||||
		echo "Cloning $(CI_GIT_ROOT) to $(CI_HOST_SRCDIR)"; \
 | 
			
		||||
		git clone $(CI_GIT_ARGS) $(CI_GIT_ROOT) $(CI_HOST_SRCDIR) || exit 1; \
 | 
			
		||||
		for mod in $$(git submodule | awk '{ print $$2 }' | sed -E 's,^../,,g') ; \
 | 
			
		||||
		do \
 | 
			
		||||
			test -f $(CI_GIT_ROOT)/$$mod/.git || continue ; \
 | 
			
		||||
			echo "Cloning $(CI_GIT_ROOT)/$$mod to $(CI_HOST_SRCDIR)/$$mod"; \
 | 
			
		||||
			git clone $(CI_GIT_ARGS) $(CI_GIT_ROOT)/$$mod $(CI_HOST_SRCDIR)/$$mod || exit 1; \
 | 
			
		||||
		done ; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
ci-run-command@%: ci-prepare-tree
 | 
			
		||||
	$(CI_ENGINE) run $(CI_ENGINE_ARGS) $(CI_IMAGE_PREFIX)$*$(CI_IMAGE_TAG) \
 | 
			
		||||
		/bin/bash -c ' \
 | 
			
		||||
		$(CI_USER_HOME)/prepare || exit 1; \
 | 
			
		||||
		if test "$$PKG_CONFIG_LIBDIR"; then \
 | 
			
		||||
			pkgconfig_env="PKG_CONFIG_LIBDIR=$$PKG_CONFIG_LIBDIR"; \
 | 
			
		||||
		fi; \
 | 
			
		||||
		sudo \
 | 
			
		||||
		  --login \
 | 
			
		||||
		  --user="#$(CI_UID)" \
 | 
			
		||||
		  --group="#$(CI_GID)" \
 | 
			
		||||
		  CONFIGURE_OPTS="$$CONFIGURE_OPTS" \
 | 
			
		||||
		  $$pkgconfig_env \
 | 
			
		||||
		  CI_CONT_SRCDIR="$(CI_CONT_SRCDIR)" \
 | 
			
		||||
		  CI_CONT_BUILDDIR="$(CI_CONT_BUILDDIR)" \
 | 
			
		||||
		  CI_SMP="$(CI_SMP)" \
 | 
			
		||||
		  CI_CONFIGURE="$(CI_CONFIGURE)" \
 | 
			
		||||
		  CI_CONFIGURE_ARGS="$(CI_CONFIGURE_ARGS)" \
 | 
			
		||||
		  CI_MAKE_ARGS="$(CI_MAKE_ARGS)" \
 | 
			
		||||
		  $(CI_COMMAND) || exit 1'
 | 
			
		||||
	@test "$(CI_CLEAN)" = "1" && rm -rf $(CI_SCRATCHDIR) || :
 | 
			
		||||
 | 
			
		||||
ci-shell@%:
 | 
			
		||||
	$(MAKE) -C $(CI_ROOTDIR) ci-run-command@$* CI_COMMAND="/bin/bash"
 | 
			
		||||
 | 
			
		||||
ci-build@%:
 | 
			
		||||
	$(MAKE) -C $(CI_ROOTDIR) ci-run-command@$* CI_COMMAND="$(CI_USER_HOME)/build"
 | 
			
		||||
 | 
			
		||||
ci-check@%:
 | 
			
		||||
	$(MAKE) -C $(CI_ROOTDIR) ci-build@$* CI_MAKE_ARGS="check"
 | 
			
		||||
 | 
			
		||||
ci-list-images:
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "Available x86 container images:"
 | 
			
		||||
	@echo
 | 
			
		||||
	@sh list-images.sh "$(CI_ENGINE)" "$(CI_IMAGE_PREFIX)" | grep -v cross
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "Available cross-compiler container images:"
 | 
			
		||||
	@echo
 | 
			
		||||
	@sh list-images.sh "$(CI_ENGINE)" "$(CI_IMAGE_PREFIX)" | grep cross
 | 
			
		||||
	@echo
 | 
			
		||||
 | 
			
		||||
ci-help:
 | 
			
		||||
	@echo "Build libvirt inside containers used for CI"
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "Available targets:"
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "    ci-build@\$$IMAGE - run a default 'make'"
 | 
			
		||||
	@echo "    ci-check@\$$IMAGE - run a 'make check'"
 | 
			
		||||
	@echo "    ci-shell@\$$IMAGE - run an interactive shell"
 | 
			
		||||
	@echo "    ci-list-images  - list available images"
 | 
			
		||||
	@echo "    ci-help         - show this help message"
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "Available make variables:"
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "    CI_CLEAN=0     - do not delete '$(CI_SCRATCHDIR)' after completion"
 | 
			
		||||
	@echo "    CI_REUSE=1     - re-use existing '$(CI_SCRATCHDIR)' content"
 | 
			
		||||
	@echo "    CI_ENGINE=auto - container engine to use (podman, docker)"
 | 
			
		||||
	@echo
 | 
			
		||||
							
								
								
									
										38
									
								
								ci/build.sh
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								ci/build.sh
									
									
									
									
									
								
							@@ -1,38 +0,0 @@
 | 
			
		||||
# This script is used to build libvirt inside the container.
 | 
			
		||||
#
 | 
			
		||||
# You can customize it to your liking, or alternatively use a
 | 
			
		||||
# completely different script by passing
 | 
			
		||||
#
 | 
			
		||||
#  CI_BUILD_SCRIPT=/path/to/your/build/script
 | 
			
		||||
#
 | 
			
		||||
# to make.
 | 
			
		||||
 | 
			
		||||
mkdir -p "$CI_CONT_BUILDDIR" || exit 1
 | 
			
		||||
cd "$CI_CONT_BUILDDIR"
 | 
			
		||||
 | 
			
		||||
export VIR_TEST_DEBUG=1
 | 
			
		||||
NOCONFIGURE=1 "$CI_CONT_SRCDIR/autogen.sh" || exit 1
 | 
			
		||||
 | 
			
		||||
# $CONFIGURE_OPTS is a env that can optionally be set in the container,
 | 
			
		||||
# populated at build time from the Dockerfile. A typical use case would
 | 
			
		||||
# be to pass --host/--target args to trigger cross-compilation
 | 
			
		||||
#
 | 
			
		||||
# This can be augmented by make local args in $CI_CONFIGURE_ARGS
 | 
			
		||||
"$CI_CONFIGURE" $CONFIGURE_OPTS $CI_CONFIGURE_ARGS
 | 
			
		||||
if test $? != 0; then
 | 
			
		||||
    test -f config.log && cat config.log
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
find -name test-suite.log -delete
 | 
			
		||||
 | 
			
		||||
make -j"$CI_SMP" $CI_MAKE_ARGS
 | 
			
		||||
 | 
			
		||||
if test $? != 0; then \
 | 
			
		||||
    LOGS=$(find -name test-suite.log)
 | 
			
		||||
    if test "$LOGS"; then
 | 
			
		||||
        echo "=== LOG FILE(S) START ==="
 | 
			
		||||
        cat $LOGS
 | 
			
		||||
        echo "=== LOG FILE(S) END ==="
 | 
			
		||||
    fi
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
engine="$1"
 | 
			
		||||
prefix="$2"
 | 
			
		||||
 | 
			
		||||
do_podman() {
 | 
			
		||||
    # Podman freaks out if the search term ends with a dash, which ours
 | 
			
		||||
    # by default does, so let's strip it. The repository name is the
 | 
			
		||||
    # second field in the output, and it already starts with the registry
 | 
			
		||||
    podman search --limit 100 "${prefix%-}" | while read _ repo _; do
 | 
			
		||||
        echo "$repo"
 | 
			
		||||
    done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
do_docker() {
 | 
			
		||||
    # Docker doesn't include the registry name in the output, so we have
 | 
			
		||||
    # to add it. The repository name is the first field in the output
 | 
			
		||||
    registry="${prefix%%/*}"
 | 
			
		||||
    docker search --limit 100 "$prefix" | while read repo _; do
 | 
			
		||||
        echo "$registry/$repo"
 | 
			
		||||
    done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
"do_$engine" | grep "^$prefix" | sed "s,^$prefix,,g" | while read repo; do
 | 
			
		||||
    echo "    $repo"
 | 
			
		||||
done | sort -u
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
# This script is used to prepare the environment that will be used
 | 
			
		||||
# to build libvirt inside the container.
 | 
			
		||||
#
 | 
			
		||||
# You can customize it to your liking, or alternatively use a
 | 
			
		||||
# completely different script by passing
 | 
			
		||||
#
 | 
			
		||||
#  CI_PREPARE_SCRIPT=/path/to/your/prepare/script
 | 
			
		||||
#
 | 
			
		||||
# to make.
 | 
			
		||||
#
 | 
			
		||||
# Note that this script will have root privileges inside the
 | 
			
		||||
# container, so it can be used for things like installing additional
 | 
			
		||||
# packages.
 | 
			
		||||
@@ -16,43 +16,30 @@
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __GNUC__
 | 
			
		||||
# error "Libvirt requires GCC >= 4.8, or CLang"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Define __GNUC_PREREQ to a sane default if it isn't yet defined.
 | 
			
		||||
 * This is done here so that it's included as early as possible;
 | 
			
		||||
 * Since virt-login-shell will be setuid, we must do everything
 | 
			
		||||
 * we can to avoid linking to other libraries. Many of them do
 | 
			
		||||
 * unsafe things in functions marked __atttribute__((constructor)).
 | 
			
		||||
 * The only way avoid to avoid such deps is to re-compile the
 | 
			
		||||
 * functions with the code in question disabled, and for that we
 | 
			
		||||
 * must override the main config.h rules. Hence this file :-(
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __GNUC_PREREQ
 | 
			
		||||
# define __GNUC_PREREQ(maj, min) \
 | 
			
		||||
    ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
 | 
			
		||||
 | 
			
		||||
#ifdef LIBVIRT_SETUID_RPC_CLIENT
 | 
			
		||||
# undef HAVE_LIBDEVMAPPER_H
 | 
			
		||||
# undef HAVE_LIBNL
 | 
			
		||||
# undef HAVE_LIBNL3
 | 
			
		||||
# undef HAVE_LIBSASL2
 | 
			
		||||
# undef WITH_CAPNG
 | 
			
		||||
# undef WITH_CURL
 | 
			
		||||
# undef WITH_DTRACE_PROBES
 | 
			
		||||
# undef WITH_GNUTLS
 | 
			
		||||
# undef WITH_GNUTLS_GCRYPT
 | 
			
		||||
# undef WITH_MACVTAP
 | 
			
		||||
# undef WITH_NUMACTL
 | 
			
		||||
# undef WITH_SASL
 | 
			
		||||
# undef WITH_SSH2
 | 
			
		||||
# undef WITH_VIRTUALPORT
 | 
			
		||||
# undef WITH_YAJL
 | 
			
		||||
# undef WITH_YAJL2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__clang_major__) && defined(__clang_minor__)
 | 
			
		||||
# ifdef __apple_build_version__
 | 
			
		||||
#  if __clang_major__ < 5 || (__clang_major__ == 5 && __clang_minor__ < 1)
 | 
			
		||||
#   error You need at least XCode Clang v5.1 to compile QEMU
 | 
			
		||||
#  endif
 | 
			
		||||
# else
 | 
			
		||||
#  if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 4)
 | 
			
		||||
#   error You need at least Clang v3.4 to compile QEMU
 | 
			
		||||
#  endif
 | 
			
		||||
# endif
 | 
			
		||||
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
 | 
			
		||||
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
 | 
			
		||||
#  error You need at least GCC v4.8 to compile QEMU
 | 
			
		||||
# endif
 | 
			
		||||
#else
 | 
			
		||||
# error You either need at least GCC 4.8 or Clang 3.4 or XCode Clang 5.1 to compile libvirt
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Ask for warnings for anything that was marked deprecated in
 | 
			
		||||
 * the defined version, or before. It is a candidate for rewrite.
 | 
			
		||||
 */
 | 
			
		||||
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_48
 | 
			
		||||
 | 
			
		||||
/* Ask for warnings if code tries to use function that did not
 | 
			
		||||
 * exist in the defined version. These risk breaking builds
 | 
			
		||||
 */
 | 
			
		||||
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_48
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2890
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										2890
									
								
								configure.ac
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										538
									
								
								daemon/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										538
									
								
								daemon/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,538 @@
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
## Copyright (C) 2005-2015 Red Hat, Inc.
 | 
			
		||||
##
 | 
			
		||||
## This library is free software; you can redistribute it and/or
 | 
			
		||||
## modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
## License as published by the Free Software Foundation; either
 | 
			
		||||
## version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
##
 | 
			
		||||
## This library is distributed in the hope that it will be useful,
 | 
			
		||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
## Lesser General Public License for more details.
 | 
			
		||||
##
 | 
			
		||||
## You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
## License along with this library.  If not, see
 | 
			
		||||
## <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
INCLUDES = \
 | 
			
		||||
	-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
 | 
			
		||||
	-I$(top_srcdir) \
 | 
			
		||||
	-I$(top_builddir)/include -I$(top_srcdir)/include \
 | 
			
		||||
	-I$(top_builddir)/src -I$(top_srcdir)/src \
 | 
			
		||||
	-I$(top_srcdir)/src/util \
 | 
			
		||||
	-I$(top_srcdir)/src/conf \
 | 
			
		||||
	-I$(top_srcdir)/src/rpc \
 | 
			
		||||
	-I$(top_srcdir)/src/remote \
 | 
			
		||||
	-I$(top_srcdir)/src/admin \
 | 
			
		||||
	-I$(top_srcdir)/src/access \
 | 
			
		||||
	$(GETTEXT_CPPFLAGS)
 | 
			
		||||
 | 
			
		||||
CLEANFILES =
 | 
			
		||||
 | 
			
		||||
DAEMON_GENERATED =			\
 | 
			
		||||
		remote_dispatch.h	\
 | 
			
		||||
		lxc_dispatch.h		\
 | 
			
		||||
		qemu_dispatch.h		\
 | 
			
		||||
		admin_dispatch.h	\
 | 
			
		||||
		$(NULL)
 | 
			
		||||
 | 
			
		||||
DAEMON_SOURCES =					\
 | 
			
		||||
		libvirtd.c libvirtd.h			\
 | 
			
		||||
		remote.c remote.h			\
 | 
			
		||||
		stream.c stream.h			\
 | 
			
		||||
		$(DAEMON_GENERATED)
 | 
			
		||||
 | 
			
		||||
LIBVIRTD_CONF_SOURCES = libvirtd-config.c libvirtd-config.h
 | 
			
		||||
 | 
			
		||||
DISTCLEANFILES =
 | 
			
		||||
EXTRA_DIST =						\
 | 
			
		||||
	remote_dispatch.h				\
 | 
			
		||||
	lxc_dispatch.h					\
 | 
			
		||||
	qemu_dispatch.h					\
 | 
			
		||||
	admin_dispatch.h				\
 | 
			
		||||
	libvirtd.conf					\
 | 
			
		||||
	libvirtd.init.in				\
 | 
			
		||||
	libvirtd.upstart				\
 | 
			
		||||
	libvirtd.policy.in				\
 | 
			
		||||
	libvirt.rules					\
 | 
			
		||||
	libvirtd.sasl					\
 | 
			
		||||
	libvirtd.service.in				\
 | 
			
		||||
	libvirtd.socket.in				\
 | 
			
		||||
	libvirtd.sysconf				\
 | 
			
		||||
	libvirtd.sysctl					\
 | 
			
		||||
	libvirtd.aug                                    \
 | 
			
		||||
	libvirtd.logrotate.in                           \
 | 
			
		||||
	libvirtd.qemu.logrotate.in                      \
 | 
			
		||||
	libvirtd.lxc.logrotate.in                       \
 | 
			
		||||
	libvirtd.libxl.logrotate.in                     \
 | 
			
		||||
	libvirtd.uml.logrotate.in                       \
 | 
			
		||||
	test_libvirtd.aug.in                             \
 | 
			
		||||
	THREADS.txt					\
 | 
			
		||||
	libvirtd.pod.in					\
 | 
			
		||||
	libvirtd.8.in					\
 | 
			
		||||
	$(DAEMON_SOURCES)				\
 | 
			
		||||
	$(LIBVIRTD_CONF_SOURCES)			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES =
 | 
			
		||||
 | 
			
		||||
REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
 | 
			
		||||
LXC_PROTOCOL = $(top_srcdir)/src/remote/lxc_protocol.x
 | 
			
		||||
QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
 | 
			
		||||
ADMIN_PROTOCOL = $(top_srcdir)/src/admin/admin_protocol.x
 | 
			
		||||
 | 
			
		||||
remote_dispatch.h: $(top_srcdir)/src/rpc/gendispatch.pl \
 | 
			
		||||
		$(REMOTE_PROTOCOL)
 | 
			
		||||
	$(AM_V_GEN)$(PERL) -w $(top_srcdir)/src/rpc/gendispatch.pl \
 | 
			
		||||
	  --mode=server remote REMOTE $(REMOTE_PROTOCOL) \
 | 
			
		||||
	  > $(srcdir)/remote_dispatch.h
 | 
			
		||||
 | 
			
		||||
lxc_dispatch.h: $(top_srcdir)/src/rpc/gendispatch.pl \
 | 
			
		||||
		$(LXC_PROTOCOL)
 | 
			
		||||
	$(AM_V_GEN)$(PERL) -w $(top_srcdir)/src/rpc/gendispatch.pl \
 | 
			
		||||
	  --mode=server lxc LXC $(LXC_PROTOCOL) \
 | 
			
		||||
	  > $(srcdir)/lxc_dispatch.h
 | 
			
		||||
 | 
			
		||||
qemu_dispatch.h: $(top_srcdir)/src/rpc/gendispatch.pl \
 | 
			
		||||
		$(QEMU_PROTOCOL)
 | 
			
		||||
	$(AM_V_GEN)$(PERL) -w $(top_srcdir)/src/rpc/gendispatch.pl \
 | 
			
		||||
	  --mode=server qemu QEMU $(QEMU_PROTOCOL) \
 | 
			
		||||
	  > $(srcdir)/qemu_dispatch.h
 | 
			
		||||
 | 
			
		||||
admin_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
 | 
			
		||||
		$(ADMIN_PROTOCOL)
 | 
			
		||||
	$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \
 | 
			
		||||
	  --mode=server admin ADMIN $(ADMIN_PROTOCOL) \
 | 
			
		||||
	  > $(srcdir)/admin_dispatch.h
 | 
			
		||||
 | 
			
		||||
if WITH_LIBVIRTD
 | 
			
		||||
 | 
			
		||||
# Build a convenience library, for reuse in tests/libvirtdconftest
 | 
			
		||||
noinst_LTLIBRARIES = libvirtd_conf.la
 | 
			
		||||
libvirtd_conf_la_SOURCES = $(LIBVIRTD_CONF_SOURCES)
 | 
			
		||||
libvirtd_conf_la_CFLAGS = \
 | 
			
		||||
	$(LIBXML_CFLAGS) \
 | 
			
		||||
	$(XDR_CFLAGS) \
 | 
			
		||||
	$(WARN_CFLAGS) $(PIE_CFLAGS) \
 | 
			
		||||
	$(COVERAGE_CFLAGS) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
libvirtd_conf_la_LDFLAGS =				\
 | 
			
		||||
	$(RELRO_LDFLAGS)				\
 | 
			
		||||
	$(PIE_LDFLAGS)					\
 | 
			
		||||
	$(COVERAGE_LDFLAGS)				\
 | 
			
		||||
	$(NO_INDIRECT_LDFLAGS)				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
libvirtd_conf_la_LIBADD = $(LIBXML_LIBS)
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES += libvirtd_admin.la
 | 
			
		||||
libvirtd_admin_la_SOURCES = \
 | 
			
		||||
		admin_server.c admin_server.h
 | 
			
		||||
 | 
			
		||||
libvirtd_admin_la_CFLAGS = \
 | 
			
		||||
		$(AM_CFLAGS)		\
 | 
			
		||||
		$(XDR_CFLAGS)		\
 | 
			
		||||
		$(PIE_CFLAGS)		\
 | 
			
		||||
		$(WARN_CFLAGS)		\
 | 
			
		||||
		$(LIBXML_CFLAGS)	\
 | 
			
		||||
		$(COVERAGE_CFLAGS)
 | 
			
		||||
 | 
			
		||||
libvirtd_admin_la_LDFLAGS = \
 | 
			
		||||
		$(PIE_LDFLAGS)		\
 | 
			
		||||
		$(RELRO_LDFLAGS)	\
 | 
			
		||||
		$(COVERAGE_LDFLAGS)	\
 | 
			
		||||
		$(NO_INDIRECT_LDFLAGS)
 | 
			
		||||
 | 
			
		||||
libvirtd_admin_la_LIBADD =	\
 | 
			
		||||
		../src/libvirt-admin.la
 | 
			
		||||
 | 
			
		||||
man8_MANS = libvirtd.8
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
CLEANFILES += test_libvirtd.aug
 | 
			
		||||
 | 
			
		||||
libvirtd.8: $(srcdir)/libvirtd.8.in
 | 
			
		||||
	$(AM_V_GEN)sed \
 | 
			
		||||
	    -e 's|[@]sysconfdir[@]|$(sysconfdir)|g' \
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g' \
 | 
			
		||||
	    < $< > $@-t && \
 | 
			
		||||
	mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd_SOURCES = $(DAEMON_SOURCES)
 | 
			
		||||
 | 
			
		||||
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
 | 
			
		||||
libvirtd_CFLAGS = \
 | 
			
		||||
	$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
 | 
			
		||||
	$(XDR_CFLAGS) $(DBUS_CFLAGS) $(LIBNL_CFLAGS) \
 | 
			
		||||
	$(WARN_CFLAGS) $(PIE_CFLAGS) \
 | 
			
		||||
	$(COVERAGE_CFLAGS) \
 | 
			
		||||
	-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\""
 | 
			
		||||
 | 
			
		||||
libvirtd_LDFLAGS =					\
 | 
			
		||||
	$(RELRO_LDFLAGS)				\
 | 
			
		||||
	$(PIE_LDFLAGS)					\
 | 
			
		||||
	$(COVERAGE_LDFLAGS)				\
 | 
			
		||||
	$(NO_INDIRECT_LDFLAGS)				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libvirtd_LDADD =					\
 | 
			
		||||
	$(LIBXML_LIBS)					\
 | 
			
		||||
	$(GNUTLS_LIBS)					\
 | 
			
		||||
	$(SASL_LIBS)					\
 | 
			
		||||
	$(DBUS_LIBS)					\
 | 
			
		||||
	$(LIBNL_LIBS)
 | 
			
		||||
 | 
			
		||||
if WITH_DTRACE_PROBES
 | 
			
		||||
libvirtd_LDADD += ../src/libvirt_probes.lo
 | 
			
		||||
endif WITH_DTRACE_PROBES
 | 
			
		||||
 | 
			
		||||
libvirtd_LDADD += \
 | 
			
		||||
	libvirtd_conf.la \
 | 
			
		||||
	libvirtd_admin.la \
 | 
			
		||||
	../src/libvirt-lxc.la \
 | 
			
		||||
	../src/libvirt-qemu.la \
 | 
			
		||||
	../src/libvirt_driver_remote.la \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if ! WITH_DRIVER_MODULES
 | 
			
		||||
if WITH_QEMU
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_qemu.la
 | 
			
		||||
if WITH_DTRACE_PROBES
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_qemu_probes.lo
 | 
			
		||||
endif WITH_DTRACE_PROBES
 | 
			
		||||
endif WITH_QEMU
 | 
			
		||||
 | 
			
		||||
if WITH_LXC
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_lxc.la
 | 
			
		||||
endif WITH_LXC
 | 
			
		||||
 | 
			
		||||
if WITH_XEN
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_xen.la
 | 
			
		||||
endif WITH_XEN
 | 
			
		||||
 | 
			
		||||
if WITH_LIBXL
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_libxl.la
 | 
			
		||||
endif WITH_LIBXL
 | 
			
		||||
 | 
			
		||||
if WITH_UML
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_uml.la
 | 
			
		||||
endif WITH_UML
 | 
			
		||||
 | 
			
		||||
if WITH_VBOX
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_vbox.la
 | 
			
		||||
endif WITH_VBOX
 | 
			
		||||
 | 
			
		||||
if WITH_STORAGE
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_storage.la
 | 
			
		||||
endif WITH_STORAGE
 | 
			
		||||
 | 
			
		||||
if WITH_NETWORK
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_network.la
 | 
			
		||||
endif WITH_NETWORK
 | 
			
		||||
 | 
			
		||||
if WITH_INTERFACE
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_interface.la
 | 
			
		||||
endif WITH_INTERFACE
 | 
			
		||||
 | 
			
		||||
if WITH_NODE_DEVICES
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_nodedev.la
 | 
			
		||||
endif WITH_NODE_DEVICES
 | 
			
		||||
 | 
			
		||||
if WITH_SECRETS
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_secret.la
 | 
			
		||||
endif WITH_SECRETS
 | 
			
		||||
 | 
			
		||||
if WITH_NWFILTER
 | 
			
		||||
    libvirtd_LDADD += ../src/libvirt_driver_nwfilter.la
 | 
			
		||||
endif WITH_NWFILTER
 | 
			
		||||
endif ! WITH_DRIVER_MODULES
 | 
			
		||||
 | 
			
		||||
libvirtd_LDADD += ../src/libvirt.la
 | 
			
		||||
 | 
			
		||||
if WITH_POLKIT
 | 
			
		||||
if WITH_POLKIT0
 | 
			
		||||
policydir = $(datadir)/PolicyKit/policy
 | 
			
		||||
policyauth = auth_admin_keep_session
 | 
			
		||||
else ! WITH_POLKIT0
 | 
			
		||||
policydir = $(datadir)/polkit-1/actions
 | 
			
		||||
policyauth = auth_admin_keep
 | 
			
		||||
rulesdir = $(datadir)/polkit-1/rules.d
 | 
			
		||||
rulesfile = libvirt.rules
 | 
			
		||||
endif ! WITH_POLKIT0
 | 
			
		||||
endif WITH_POLKIT
 | 
			
		||||
 | 
			
		||||
libvirtd.policy: libvirtd.policy.in $(top_builddir)/config.status
 | 
			
		||||
	$(AM_V_GEN) sed \
 | 
			
		||||
	    -e 's|[@]authaction[@]|$(policyauth)|g' \
 | 
			
		||||
	    < $< > $@-t && \
 | 
			
		||||
	mv $@-t $@
 | 
			
		||||
BUILT_SOURCES += libvirtd.policy
 | 
			
		||||
 | 
			
		||||
install-data-local: install-init-redhat install-init-systemd \
 | 
			
		||||
		install-init-upstart \
 | 
			
		||||
		install-data-sasl install-data-polkit \
 | 
			
		||||
		install-logrotate install-sysctl
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt \
 | 
			
		||||
		   $(DESTDIR)$(localstatedir)/run/libvirt \
 | 
			
		||||
		   $(DESTDIR)$(localstatedir)/lib/libvirt
 | 
			
		||||
 | 
			
		||||
uninstall-local:: uninstall-init-redhat uninstall-init-systemd \
 | 
			
		||||
		uninstall-init-upstart \
 | 
			
		||||
		uninstall-data-sasl uninstall-data-polkit \
 | 
			
		||||
		uninstall-logrotate uninstall-sysctl
 | 
			
		||||
	rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
 | 
			
		||||
	rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
 | 
			
		||||
	rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
 | 
			
		||||
 | 
			
		||||
if WITH_POLKIT
 | 
			
		||||
install-data-polkit::
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(policydir)
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.policy $(DESTDIR)$(policydir)/org.libvirt.unix.policy
 | 
			
		||||
if ! WITH_POLKIT0
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(rulesdir)
 | 
			
		||||
	$(INSTALL_DATA) $(srcdir)/$(rulesfile) $(DESTDIR)$(rulesdir)/50-libvirt.rules
 | 
			
		||||
endif ! WITH_POLKIT0
 | 
			
		||||
 | 
			
		||||
uninstall-data-polkit::
 | 
			
		||||
	rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
 | 
			
		||||
	rmdir $(DESTDIR)$(policydir) || :
 | 
			
		||||
if ! WITH_POLKIT0
 | 
			
		||||
	rm -f $(DESTDIR)$(rulesdir)/50-libvirt.rules
 | 
			
		||||
	rmdir $(DESTDIR)$(rulesdir) || :
 | 
			
		||||
endif ! WITH_POLKIT0
 | 
			
		||||
 | 
			
		||||
else ! WITH_POLKIT
 | 
			
		||||
install-data-polkit::
 | 
			
		||||
uninstall-data-polkit::
 | 
			
		||||
endif ! WITH_POLKIT
 | 
			
		||||
 | 
			
		||||
remote.c: $(DAEMON_GENERATED)
 | 
			
		||||
remote.h: $(DAEMON_GENERATED)
 | 
			
		||||
admin_server.c: $(DAEMON_GENERATED)
 | 
			
		||||
 | 
			
		||||
LOGROTATE_CONFS = libvirtd.qemu.logrotate libvirtd.lxc.logrotate \
 | 
			
		||||
		  libvirtd.libxl.logrotate libvirtd.uml.logrotate \
 | 
			
		||||
		  libvirtd.logrotate
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES += $(LOGROTATE_CONFS)
 | 
			
		||||
 | 
			
		||||
libvirtd.logrotate: libvirtd.logrotate.in
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    < $< > $@-t && \
 | 
			
		||||
	mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd.qemu.logrotate: libvirtd.qemu.logrotate.in
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    < $< > $@-t && \
 | 
			
		||||
	mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd.lxc.logrotate: libvirtd.lxc.logrotate.in
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    < $< > $@-t &&					\
 | 
			
		||||
	    mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd.libxl.logrotate: libvirtd.libxl.logrotate.in
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    < $< > $@-t &&					\
 | 
			
		||||
	    mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd.uml.logrotate: libvirtd.uml.logrotate.in
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    < $< > $@-t &&					\
 | 
			
		||||
	    mv $@-t $@
 | 
			
		||||
 | 
			
		||||
install-logrotate: $(LOGROTATE_CONFS)
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt/qemu/ \
 | 
			
		||||
		   $(DESTDIR)$(localstatedir)/log/libvirt/lxc/ \
 | 
			
		||||
		   $(DESTDIR)$(localstatedir)/log/libvirt/uml/ \
 | 
			
		||||
		   $(DESTDIR)$(sysconfdir)/logrotate.d/
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.logrotate \
 | 
			
		||||
		$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.qemu.logrotate \
 | 
			
		||||
		$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.lxc.logrotate \
 | 
			
		||||
		$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.libxl.logrotate \
 | 
			
		||||
		$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.libxl
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.uml.logrotate \
 | 
			
		||||
		$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
 | 
			
		||||
 | 
			
		||||
uninstall-logrotate:
 | 
			
		||||
	rm -f $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd \
 | 
			
		||||
	      $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu \
 | 
			
		||||
	      $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc \
 | 
			
		||||
	      $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.libxl \
 | 
			
		||||
	      $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
 | 
			
		||||
	rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
 | 
			
		||||
	rmdir $(DESTDIR)$(localstatedir)/log/libvirt/lxc || :
 | 
			
		||||
	rmdir $(DESTDIR)$(localstatedir)/log/libvirt/uml || :
 | 
			
		||||
	rmdir $(DESTDIR)$(sysconfdir)/logrotate.d || :
 | 
			
		||||
 | 
			
		||||
install-sysconfig:
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sysconfig
 | 
			
		||||
	$(INSTALL_DATA) $(srcdir)/libvirtd.sysconf \
 | 
			
		||||
	  $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
 | 
			
		||||
uninstall-sysconfig:
 | 
			
		||||
	rm -f $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
 | 
			
		||||
	rmdir $(DESTDIR)$(sysconfdir)/sysconfig || :
 | 
			
		||||
 | 
			
		||||
if WITH_SYSCTL
 | 
			
		||||
# Use $(prefix)/lib rather than $(libdir), since man sysctl.d insists on
 | 
			
		||||
# /usr/lib/sysctl.d/ even when libdir is /usr/lib64
 | 
			
		||||
install-sysctl:
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(prefix)/lib/sysctl.d
 | 
			
		||||
	$(INSTALL_DATA) $(srcdir)/libvirtd.sysctl \
 | 
			
		||||
	  $(DESTDIR)$(prefix)/lib/sysctl.d/60-libvirtd.conf
 | 
			
		||||
 | 
			
		||||
uninstall-sysctl:
 | 
			
		||||
	rm -f $(DESTDIR)$(prefix)/lib/sysctl.d/60-libvirtd.conf
 | 
			
		||||
	rmdir $(DESTDIR)$(prefix)/lib/sysctl.d || :
 | 
			
		||||
else ! WITH_SYSCTL
 | 
			
		||||
install-sysctl:
 | 
			
		||||
uninstall-sysctl:
 | 
			
		||||
endif ! WITH_SYSCTL
 | 
			
		||||
 | 
			
		||||
if LIBVIRT_INIT_SCRIPT_RED_HAT
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES += libvirtd.init
 | 
			
		||||
 | 
			
		||||
install-init-redhat: install-sysconfig libvirtd.init
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(sysconfdir)/rc.d/init.d
 | 
			
		||||
	$(INSTALL_SCRIPT) libvirtd.init \
 | 
			
		||||
	  $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
 | 
			
		||||
 | 
			
		||||
uninstall-init-redhat: uninstall-sysconfig
 | 
			
		||||
	rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
 | 
			
		||||
	rmdir $(DESTDIR)$(sysconfdir)/rc.d/init.d || :
 | 
			
		||||
else ! LIBVIRT_INIT_SCRIPT_RED_HAT
 | 
			
		||||
install-init-redhat:
 | 
			
		||||
uninstall-init-redhat:
 | 
			
		||||
endif ! LIBVIRT_INIT_SCRIPT_RED_HAT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if LIBVIRT_INIT_SCRIPT_UPSTART
 | 
			
		||||
 | 
			
		||||
install-init-upstart: install-sysconfig
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(sysconfdir)/event.d
 | 
			
		||||
	$(INSTALL_SCRIPT) libvirtd.upstart \
 | 
			
		||||
	  $(DESTDIR)$(sysconfdir)/event.d/libvirtd
 | 
			
		||||
 | 
			
		||||
uninstall-init-upstart: uninstall-sysconfig
 | 
			
		||||
	rm -f $(DESTDIR)$(sysconfdir)/event.d/libvirtd
 | 
			
		||||
	rmdir $(DESTDIR)$(sysconfdir)/event.d || :
 | 
			
		||||
else ! LIBVIRT_INIT_SCRIPT_UPSTART
 | 
			
		||||
install-init-upstart:
 | 
			
		||||
uninstall-init-upstart:
 | 
			
		||||
endif ! LIBVIRT_INIT_SCRIPT_UPSTART
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if LIBVIRT_INIT_SCRIPT_SYSTEMD
 | 
			
		||||
 | 
			
		||||
SYSTEMD_UNIT_DIR = $(prefix)/lib/systemd/system
 | 
			
		||||
BUILT_SOURCES += libvirtd.service libvirtd.socket
 | 
			
		||||
 | 
			
		||||
install-init-systemd: install-sysconfig libvirtd.service libvirtd.socket
 | 
			
		||||
	$(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR)
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.service \
 | 
			
		||||
	  $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
 | 
			
		||||
	$(INSTALL_DATA) libvirtd.socket \
 | 
			
		||||
	  $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.socket
 | 
			
		||||
 | 
			
		||||
uninstall-init-systemd: uninstall-sysconfig
 | 
			
		||||
	rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
 | 
			
		||||
	rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.socket
 | 
			
		||||
	rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || :
 | 
			
		||||
else ! LIBVIRT_INIT_SCRIPT_SYSTEMD
 | 
			
		||||
install-init-systemd:
 | 
			
		||||
uninstall-init-systemd:
 | 
			
		||||
endif ! LIBVIRT_INIT_SCRIPT_SYSTEMD
 | 
			
		||||
 | 
			
		||||
libvirtd.init: libvirtd.init.in $(top_builddir)/config.status
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    -e 's|[@]sbindir[@]|$(sbindir)|g'			\
 | 
			
		||||
	    -e 's|[@]sysconfdir[@]|$(sysconfdir)|g'		\
 | 
			
		||||
	    < $< > $@-t &&					\
 | 
			
		||||
	    chmod a+x $@-t &&					\
 | 
			
		||||
	    mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd.service: libvirtd.service.in $(top_builddir)/config.status
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]localstatedir[@]|$(localstatedir)|g'	\
 | 
			
		||||
	    -e 's|[@]sbindir[@]|$(sbindir)|g'			\
 | 
			
		||||
	    -e 's|[@]sysconfdir[@]|$(sysconfdir)|g'		\
 | 
			
		||||
	    < $< > $@-t &&					\
 | 
			
		||||
	    mv $@-t $@
 | 
			
		||||
 | 
			
		||||
libvirtd.socket: libvirtd.socket.in $(top_builddir)/config.status
 | 
			
		||||
	$(AM_V_GEN)sed						\
 | 
			
		||||
	    -e 's|[@]runstatedir[@]|$(runstatedir)|g'		\
 | 
			
		||||
	    < $< > $@-t &&					\
 | 
			
		||||
	    mv $@-t $@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
check-local: check-augeas
 | 
			
		||||
 | 
			
		||||
AUG_GENTEST = $(PERL) $(top_srcdir)/build-aux/augeas-gentest.pl
 | 
			
		||||
 | 
			
		||||
test_libvirtd.aug: test_libvirtd.aug.in $(srcdir)/libvirtd.conf
 | 
			
		||||
	$(AM_V_GEN)$(AUG_GENTEST) $(srcdir)/libvirtd.conf $< $@
 | 
			
		||||
 | 
			
		||||
check-augeas: test_libvirtd.aug
 | 
			
		||||
	$(AM_V_GEN)if test -x '$(AUGPARSE)'; then \
 | 
			
		||||
	  '$(AUGPARSE)' -I $(srcdir) test_libvirtd.aug; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
POD2MAN = pod2man -c "Virtualization Support" \
 | 
			
		||||
			-r "$(PACKAGE)-$(VERSION)" -s 8
 | 
			
		||||
 | 
			
		||||
$(srcdir)/libvirtd.8.in: libvirtd.pod.in $(top_srcdir)/configure.ac
 | 
			
		||||
	$(AM_V_GEN)$(POD2MAN) --name LIBVIRTD $< $@ \
 | 
			
		||||
	    && if grep 'POD ERROR' $@ ; then rm $@; exit 1; fi
 | 
			
		||||
 | 
			
		||||
# This is needed for clients too, so can't wrap in
 | 
			
		||||
# the WITH_LIBVIRTD conditional
 | 
			
		||||
if WITH_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 ! WITH_SASL
 | 
			
		||||
install-data-sasl:
 | 
			
		||||
uninstall-data-sasl:
 | 
			
		||||
endif ! WITH_SASL
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CLEANFILES += $(BUILT_SOURCES) $(man8_MANS)
 | 
			
		||||
CLEANFILES += *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
 | 
			
		||||
MAINTAINERCLEANFILES = $(srcdir)/libvirtd.8.in $(DAEMON_GENERATED)
 | 
			
		||||
							
								
								
									
										52
									
								
								daemon/THREADS.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								daemon/THREADS.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
 | 
			
		||||
     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 on 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
 | 
			
		||||
							
								
								
									
										117
									
								
								daemon/admin_server.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								daemon/admin_server.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
/*
 | 
			
		||||
 * admin_server.c:
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2014-2015 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library.  If not, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Martin Kletzander <mkletzan@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
#include "libvirtd.h"
 | 
			
		||||
#include "libvirt_internal.h"
 | 
			
		||||
 | 
			
		||||
#include "admin_protocol.h"
 | 
			
		||||
#include "admin_server.h"
 | 
			
		||||
#include "datatypes.h"
 | 
			
		||||
#include "viralloc.h"
 | 
			
		||||
#include "virerror.h"
 | 
			
		||||
#include "virlog.h"
 | 
			
		||||
#include "virnetdaemon.h"
 | 
			
		||||
#include "virnetserver.h"
 | 
			
		||||
#include "virstring.h"
 | 
			
		||||
#include "virthreadjob.h"
 | 
			
		||||
 | 
			
		||||
#define VIR_FROM_THIS VIR_FROM_ADMIN
 | 
			
		||||
 | 
			
		||||
VIR_LOG_INIT("daemon.admin");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
remoteAdmClientFreeFunc(void *data)
 | 
			
		||||
{
 | 
			
		||||
    struct daemonAdmClientPrivate *priv = data;
 | 
			
		||||
 | 
			
		||||
    virMutexDestroy(&priv->lock);
 | 
			
		||||
    virObjectUnref(priv->dmn);
 | 
			
		||||
    VIR_FREE(priv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
remoteAdmClientInitHook(virNetServerClientPtr client ATTRIBUTE_UNUSED,
 | 
			
		||||
                        void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    struct daemonAdmClientPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    if (VIR_ALLOC(priv) < 0)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    if (virMutexInit(&priv->lock) < 0) {
 | 
			
		||||
        VIR_FREE(priv);
 | 
			
		||||
        virReportSystemError(errno, "%s", _("unable to init mutex"));
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * We don't necessarily need to ref this object right now as there
 | 
			
		||||
     * must be one ref being held throughout the life of the daemon,
 | 
			
		||||
     * but let's just be safe for future.
 | 
			
		||||
     */
 | 
			
		||||
    priv->dmn = virObjectRef(opaque);
 | 
			
		||||
 | 
			
		||||
    return priv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Functions */
 | 
			
		||||
static int
 | 
			
		||||
adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
 | 
			
		||||
                         virNetServerClientPtr client,
 | 
			
		||||
                         virNetMessagePtr msg ATTRIBUTE_UNUSED,
 | 
			
		||||
                         virNetMessageErrorPtr rerr,
 | 
			
		||||
                         struct admin_connect_open_args *args)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int flags;
 | 
			
		||||
    struct daemonAdmClientPrivate *priv =
 | 
			
		||||
        virNetServerClientGetPrivateData(client);
 | 
			
		||||
    int ret = -1;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("priv=%p dmn=%p", priv, priv->dmn);
 | 
			
		||||
    virMutexLock(&priv->lock);
 | 
			
		||||
 | 
			
		||||
    flags = args->flags;
 | 
			
		||||
    virCheckFlagsGoto(0, cleanup);
 | 
			
		||||
 | 
			
		||||
    ret = 0;
 | 
			
		||||
 cleanup:
 | 
			
		||||
    if (ret < 0)
 | 
			
		||||
        virNetMessageSaveError(rerr);
 | 
			
		||||
    virMutexUnlock(&priv->lock);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
adminDispatchConnectClose(virNetServerPtr server ATTRIBUTE_UNUSED,
 | 
			
		||||
                          virNetServerClientPtr client,
 | 
			
		||||
                          virNetMessagePtr msg ATTRIBUTE_UNUSED,
 | 
			
		||||
                          virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
    virNetServerClientDelayedClose(client);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "admin_dispatch.h"
 | 
			
		||||
							
								
								
									
										36
									
								
								daemon/admin_server.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								daemon/admin_server.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
/*
 | 
			
		||||
 * admin_server.h
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2014 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library.  If not, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Martin Kletzander <mkletzan@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __LIBVIRTD_ADMIN_H__
 | 
			
		||||
# define __LIBVIRTD_ADMIN_H__
 | 
			
		||||
 | 
			
		||||
# include "rpc/virnetserverprogram.h"
 | 
			
		||||
# include "rpc/virnetserverclient.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern virNetServerProgramProc adminProcs[];
 | 
			
		||||
extern size_t adminNProcs;
 | 
			
		||||
 | 
			
		||||
void remoteAdmClientFreeFunc(void *data);
 | 
			
		||||
void *remoteAdmClientInitHook(virNetServerClientPtr client, void *opaque);
 | 
			
		||||
 | 
			
		||||
#endif /* __ADMIN_REMOTE_H__ */
 | 
			
		||||
							
								
								
									
										526
									
								
								daemon/libvirtd-config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										526
									
								
								daemon/libvirtd-config.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,526 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libvirtd-config.c: daemon start of day, guest process & i/o management
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006-2012, 2014, 2015 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, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "libvirtd-config.h"
 | 
			
		||||
#include "virconf.h"
 | 
			
		||||
#include "viralloc.h"
 | 
			
		||||
#include "virerror.h"
 | 
			
		||||
#include "virlog.h"
 | 
			
		||||
#include "rpc/virnetserver.h"
 | 
			
		||||
#include "configmake.h"
 | 
			
		||||
#include "remote/remote_protocol.h"
 | 
			
		||||
#include "remote/remote_driver.h"
 | 
			
		||||
#include "virstring.h"
 | 
			
		||||
#include "virutil.h"
 | 
			
		||||
 | 
			
		||||
#define VIR_FROM_THIS VIR_FROM_CONF
 | 
			
		||||
 | 
			
		||||
VIR_LOG_INIT("daemon.libvirtd-config");
 | 
			
		||||
 | 
			
		||||
/* Allocate an array of malloc'd strings from the config file, filename
 | 
			
		||||
 * (used only in diagnostics), using handle "conf".  Upon error, return -1
 | 
			
		||||
 * and free any allocated memory.  Otherwise, save the array in *list_arg
 | 
			
		||||
 * and return 0.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
 | 
			
		||||
                          const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    char **list;
 | 
			
		||||
    virConfValuePtr p = virConfGetValue(conf, key);
 | 
			
		||||
    if (!p)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    switch (p->type) {
 | 
			
		||||
    case VIR_CONF_STRING:
 | 
			
		||||
        if (VIR_ALLOC_N(list, 2) < 0) {
 | 
			
		||||
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
                           _("failed to allocate memory for %s config list"),
 | 
			
		||||
                           key);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        if (VIR_STRDUP(list[0], p->str) < 0) {
 | 
			
		||||
            VIR_FREE(list);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        list[1] = NULL;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case VIR_CONF_LIST: {
 | 
			
		||||
        int len = 0;
 | 
			
		||||
        size_t i;
 | 
			
		||||
        virConfValuePtr pp;
 | 
			
		||||
        for (pp = p->list; pp; pp = pp->next)
 | 
			
		||||
            len++;
 | 
			
		||||
        if (VIR_ALLOC_N(list, 1+len) < 0) {
 | 
			
		||||
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
                           _("failed to allocate memory for %s config list"),
 | 
			
		||||
                           key);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
 | 
			
		||||
            if (pp->type != VIR_CONF_STRING) {
 | 
			
		||||
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
                               _("remoteReadConfigFile: %s: %s:"
 | 
			
		||||
                                 " must be a string or list of strings"),
 | 
			
		||||
                               filename, key);
 | 
			
		||||
                VIR_FREE(list);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
            if (VIR_STRDUP(list[i], pp->str) < 0) {
 | 
			
		||||
                size_t j;
 | 
			
		||||
                for (j = 0; j < i; j++)
 | 
			
		||||
                    VIR_FREE(list[j]);
 | 
			
		||||
                VIR_FREE(list);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        list[i] = NULL;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
                       _("remoteReadConfigFile: %s: %s:"
 | 
			
		||||
                         " must be a string or list of strings"),
 | 
			
		||||
                       filename, key);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *list_arg = list;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* A helper function used by each of the following macros.  */
 | 
			
		||||
static int
 | 
			
		||||
checkType(virConfValuePtr p, const char *filename,
 | 
			
		||||
          const char *key, virConfType required_type)
 | 
			
		||||
{
 | 
			
		||||
    if (p->type != required_type) {
 | 
			
		||||
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
                       _("remoteReadConfigFile: %s: %s: invalid type:"
 | 
			
		||||
                         " got %s; expected %s"), filename, key,
 | 
			
		||||
                       virConfTypeToString(p->type),
 | 
			
		||||
                       virConfTypeToString(required_type));
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* If there is no config data for the key, #var_name, then do nothing.
 | 
			
		||||
   If there is valid data of type VIR_CONF_STRING, and VIR_STRDUP succeeds,
 | 
			
		||||
   store the result in var_name.  Otherwise, (i.e. invalid type, or VIR_STRDUP
 | 
			
		||||
   failure), give a diagnostic and "goto" the cleanup-and-fail label.  */
 | 
			
		||||
#define GET_CONF_STR(conf, filename, var_name)                          \
 | 
			
		||||
    do {                                                                \
 | 
			
		||||
        virConfValuePtr p = virConfGetValue(conf, #var_name);           \
 | 
			
		||||
        if (p) {                                                        \
 | 
			
		||||
            if (checkType(p, filename, #var_name, VIR_CONF_STRING) < 0) \
 | 
			
		||||
                goto error;                                             \
 | 
			
		||||
            VIR_FREE(data->var_name);                                   \
 | 
			
		||||
            if (VIR_STRDUP(data->var_name, p->str) < 0)                 \
 | 
			
		||||
                goto error;                                             \
 | 
			
		||||
        }                                                               \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
/* Like GET_CONF_STR, but for signed integral values.  */
 | 
			
		||||
#define GET_CONF_INT(conf, filename, var_name)                          \
 | 
			
		||||
    do {                                                                \
 | 
			
		||||
        virConfValuePtr p = virConfGetValue(conf, #var_name);           \
 | 
			
		||||
        if (p) {                                                        \
 | 
			
		||||
            if (p->type != VIR_CONF_ULONG &&                            \
 | 
			
		||||
                checkType(p, filename, #var_name, VIR_CONF_LONG) < 0)   \
 | 
			
		||||
                goto error;                                             \
 | 
			
		||||
            data->var_name = p->l;                                      \
 | 
			
		||||
        }                                                               \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
/* Like GET_CONF_STR, but for unsigned integral values.  */
 | 
			
		||||
#define GET_CONF_UINT(conf, filename, var_name)                         \
 | 
			
		||||
    do {                                                                \
 | 
			
		||||
        virConfValuePtr p = virConfGetValue(conf, #var_name);           \
 | 
			
		||||
        if (p) {                                                        \
 | 
			
		||||
            if (checkType(p, filename, #var_name, VIR_CONF_ULONG) < 0)  \
 | 
			
		||||
                goto error;                                             \
 | 
			
		||||
            data->var_name = p->l;                                      \
 | 
			
		||||
        }                                                               \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
remoteConfigGetAuth(virConfPtr conf,
 | 
			
		||||
                    const char *key,
 | 
			
		||||
                    int *auth,
 | 
			
		||||
                    const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    virConfValuePtr p;
 | 
			
		||||
 | 
			
		||||
    p = virConfGetValue(conf, key);
 | 
			
		||||
    if (!p)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    if (checkType(p, filename, key, VIR_CONF_STRING) < 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    if (!p->str)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    if (STREQ(p->str, "none")) {
 | 
			
		||||
        *auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
 | 
			
		||||
#if WITH_SASL
 | 
			
		||||
    } else if (STREQ(p->str, "sasl")) {
 | 
			
		||||
        *auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
 | 
			
		||||
#endif
 | 
			
		||||
    } else if (STREQ(p->str, "polkit")) {
 | 
			
		||||
        *auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
 | 
			
		||||
    } else {
 | 
			
		||||
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
                       _("remoteReadConfigFile: %s: %s: unsupported auth %s"),
 | 
			
		||||
                       filename, key, p->str);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
daemonConfigFilePath(bool privileged, char **configfile)
 | 
			
		||||
{
 | 
			
		||||
    if (privileged) {
 | 
			
		||||
        if (VIR_STRDUP(*configfile, SYSCONFDIR "/libvirt/libvirtd.conf") < 0)
 | 
			
		||||
            goto error;
 | 
			
		||||
    } else {
 | 
			
		||||
        char *configdir = NULL;
 | 
			
		||||
 | 
			
		||||
        if (!(configdir = virGetUserConfigDirectory()))
 | 
			
		||||
            goto error;
 | 
			
		||||
 | 
			
		||||
        if (virAsprintf(configfile, "%s/libvirtd.conf", configdir) < 0) {
 | 
			
		||||
            VIR_FREE(configdir);
 | 
			
		||||
            goto error;
 | 
			
		||||
        }
 | 
			
		||||
        VIR_FREE(configdir);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
 error:
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct daemonConfig*
 | 
			
		||||
daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
    struct daemonConfig *data;
 | 
			
		||||
    char *localhost;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    if (VIR_ALLOC(data) < 0)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    data->listen_tls = 1;
 | 
			
		||||
    data->listen_tcp = 0;
 | 
			
		||||
 | 
			
		||||
    if (VIR_STRDUP(data->tls_port, LIBVIRTD_TLS_PORT) < 0 ||
 | 
			
		||||
        VIR_STRDUP(data->tcp_port, LIBVIRTD_TCP_PORT) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
    /* Only default to PolicyKit if running as root */
 | 
			
		||||
#if WITH_POLKIT
 | 
			
		||||
    if (privileged) {
 | 
			
		||||
        data->auth_unix_rw = REMOTE_AUTH_POLKIT;
 | 
			
		||||
        data->auth_unix_ro = REMOTE_AUTH_POLKIT;
 | 
			
		||||
    } else {
 | 
			
		||||
#endif
 | 
			
		||||
        data->auth_unix_rw = REMOTE_AUTH_NONE;
 | 
			
		||||
        data->auth_unix_ro = REMOTE_AUTH_NONE;
 | 
			
		||||
#if WITH_POLKIT
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (VIR_STRDUP(data->unix_sock_rw_perms,
 | 
			
		||||
                   data->auth_unix_rw == REMOTE_AUTH_POLKIT ? "0777" : "0700") < 0 ||
 | 
			
		||||
        VIR_STRDUP(data->unix_sock_ro_perms, "0777") < 0 ||
 | 
			
		||||
        VIR_STRDUP(data->unix_sock_admin_perms, "0700") < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
#if WITH_SASL
 | 
			
		||||
    data->auth_tcp = REMOTE_AUTH_SASL;
 | 
			
		||||
#else
 | 
			
		||||
    data->auth_tcp = REMOTE_AUTH_NONE;
 | 
			
		||||
#endif
 | 
			
		||||
    data->auth_tls = REMOTE_AUTH_NONE;
 | 
			
		||||
 | 
			
		||||
    data->mdns_adv = 0;
 | 
			
		||||
 | 
			
		||||
    data->min_workers = 5;
 | 
			
		||||
    data->max_workers = 20;
 | 
			
		||||
    data->max_clients = 5000;
 | 
			
		||||
    data->max_anonymous_clients = 20;
 | 
			
		||||
 | 
			
		||||
    data->prio_workers = 5;
 | 
			
		||||
 | 
			
		||||
    data->max_requests = 20;
 | 
			
		||||
    data->max_client_requests = 5;
 | 
			
		||||
 | 
			
		||||
    data->audit_level = 1;
 | 
			
		||||
    data->audit_logging = 0;
 | 
			
		||||
 | 
			
		||||
    data->keepalive_interval = 5;
 | 
			
		||||
    data->keepalive_count = 5;
 | 
			
		||||
    data->keepalive_required = 0;
 | 
			
		||||
 | 
			
		||||
    data->admin_min_workers = 5;
 | 
			
		||||
    data->admin_max_workers = 20;
 | 
			
		||||
    data->admin_max_clients = 5000;
 | 
			
		||||
    data->admin_max_queued_clients = 20;
 | 
			
		||||
    data->admin_max_client_requests = 5;
 | 
			
		||||
 | 
			
		||||
    data->admin_keepalive_interval = 5;
 | 
			
		||||
    data->admin_keepalive_count = 5;
 | 
			
		||||
    data->admin_keepalive_required = 0;
 | 
			
		||||
 | 
			
		||||
    localhost = virGetHostname();
 | 
			
		||||
    if (localhost == NULL) {
 | 
			
		||||
        /* we couldn't resolve the hostname; assume that we are
 | 
			
		||||
         * running in disconnected operation, and report a less
 | 
			
		||||
         * useful Avahi string
 | 
			
		||||
         */
 | 
			
		||||
        ret = VIR_STRDUP(data->mdns_name, "Virtualization Host");
 | 
			
		||||
    } else {
 | 
			
		||||
        char *tmp;
 | 
			
		||||
        /* Extract the host part of the potentially FQDN */
 | 
			
		||||
        if ((tmp = strchr(localhost, '.')))
 | 
			
		||||
            *tmp = '\0';
 | 
			
		||||
        ret = virAsprintf(&data->mdns_name, "Virtualization Host %s",
 | 
			
		||||
                          localhost);
 | 
			
		||||
    }
 | 
			
		||||
    VIR_FREE(localhost);
 | 
			
		||||
    if (ret < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
    return data;
 | 
			
		||||
 | 
			
		||||
 error:
 | 
			
		||||
    daemonConfigFree(data);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
daemonConfigFree(struct daemonConfig *data)
 | 
			
		||||
{
 | 
			
		||||
    char **tmp;
 | 
			
		||||
 | 
			
		||||
    if (!data)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    VIR_FREE(data->listen_addr);
 | 
			
		||||
    VIR_FREE(data->tls_port);
 | 
			
		||||
    VIR_FREE(data->tcp_port);
 | 
			
		||||
    tmp = data->access_drivers;
 | 
			
		||||
    while (tmp && *tmp) {
 | 
			
		||||
        VIR_FREE(*tmp);
 | 
			
		||||
        tmp++;
 | 
			
		||||
    }
 | 
			
		||||
    VIR_FREE(data->access_drivers);
 | 
			
		||||
 | 
			
		||||
    VIR_FREE(data->unix_sock_admin_perms);
 | 
			
		||||
    VIR_FREE(data->unix_sock_ro_perms);
 | 
			
		||||
    VIR_FREE(data->unix_sock_rw_perms);
 | 
			
		||||
    VIR_FREE(data->unix_sock_group);
 | 
			
		||||
    VIR_FREE(data->unix_sock_dir);
 | 
			
		||||
    VIR_FREE(data->mdns_name);
 | 
			
		||||
 | 
			
		||||
    tmp = data->tls_allowed_dn_list;
 | 
			
		||||
    while (tmp && *tmp) {
 | 
			
		||||
        VIR_FREE(*tmp);
 | 
			
		||||
        tmp++;
 | 
			
		||||
    }
 | 
			
		||||
    VIR_FREE(data->tls_allowed_dn_list);
 | 
			
		||||
 | 
			
		||||
    tmp = data->sasl_allowed_username_list;
 | 
			
		||||
    while (tmp && *tmp) {
 | 
			
		||||
        VIR_FREE(*tmp);
 | 
			
		||||
        tmp++;
 | 
			
		||||
    }
 | 
			
		||||
    VIR_FREE(data->sasl_allowed_username_list);
 | 
			
		||||
 | 
			
		||||
    VIR_FREE(data->key_file);
 | 
			
		||||
    VIR_FREE(data->ca_file);
 | 
			
		||||
    VIR_FREE(data->cert_file);
 | 
			
		||||
    VIR_FREE(data->crl_file);
 | 
			
		||||
 | 
			
		||||
    VIR_FREE(data->host_uuid);
 | 
			
		||||
    VIR_FREE(data->log_filters);
 | 
			
		||||
    VIR_FREE(data->log_outputs);
 | 
			
		||||
 | 
			
		||||
    VIR_FREE(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
daemonConfigLoadOptions(struct daemonConfig *data,
 | 
			
		||||
                        const char *filename,
 | 
			
		||||
                        virConfPtr conf)
 | 
			
		||||
{
 | 
			
		||||
    GET_CONF_UINT(conf, filename, listen_tcp);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, listen_tls);
 | 
			
		||||
    GET_CONF_STR(conf, filename, tls_port);
 | 
			
		||||
    GET_CONF_STR(conf, filename, tcp_port);
 | 
			
		||||
    GET_CONF_STR(conf, filename, listen_addr);
 | 
			
		||||
 | 
			
		||||
    if (remoteConfigGetAuth(conf, "auth_unix_rw", &data->auth_unix_rw, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
#if WITH_POLKIT
 | 
			
		||||
    /* Change default perms to be wide-open if PolicyKit is enabled.
 | 
			
		||||
     * Admin can always override in config file
 | 
			
		||||
     */
 | 
			
		||||
    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
 | 
			
		||||
        VIR_FREE(data->unix_sock_rw_perms);
 | 
			
		||||
        if (VIR_STRDUP(data->unix_sock_rw_perms, "0777") < 0)
 | 
			
		||||
            goto error;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
    if (remoteConfigGetAuth(conf, "auth_tcp", &data->auth_tcp, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
    if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
    if (remoteConfigGetStringList(conf, "access_drivers",
 | 
			
		||||
                                  &data->access_drivers, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
    GET_CONF_STR(conf, filename, unix_sock_group);
 | 
			
		||||
    GET_CONF_STR(conf, filename, unix_sock_admin_perms);
 | 
			
		||||
    GET_CONF_STR(conf, filename, unix_sock_ro_perms);
 | 
			
		||||
    GET_CONF_STR(conf, filename, unix_sock_rw_perms);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_STR(conf, filename, unix_sock_dir);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, mdns_adv);
 | 
			
		||||
    GET_CONF_STR(conf, filename, mdns_name);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, tls_no_sanity_certificate);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, tls_no_verify_certificate);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_STR(conf, filename, key_file);
 | 
			
		||||
    GET_CONF_STR(conf, filename, cert_file);
 | 
			
		||||
    GET_CONF_STR(conf, filename, ca_file);
 | 
			
		||||
    GET_CONF_STR(conf, filename, crl_file);
 | 
			
		||||
 | 
			
		||||
    if (remoteConfigGetStringList(conf, "tls_allowed_dn_list",
 | 
			
		||||
                                  &data->tls_allowed_dn_list, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (remoteConfigGetStringList(conf, "sasl_allowed_username_list",
 | 
			
		||||
                                  &data->sasl_allowed_username_list, filename) < 0)
 | 
			
		||||
        goto error;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, min_workers);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, max_workers);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, max_clients);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, max_queued_clients);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, max_anonymous_clients);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, prio_workers);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_INT(conf, filename, max_requests);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, max_client_requests);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_min_workers);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_max_workers);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_max_clients);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_max_queued_clients);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_max_client_requests);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, audit_level);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, audit_logging);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_STR(conf, filename, host_uuid);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_UINT(conf, filename, log_level);
 | 
			
		||||
    GET_CONF_STR(conf, filename, log_filters);
 | 
			
		||||
    GET_CONF_STR(conf, filename, log_outputs);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_INT(conf, filename, keepalive_interval);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, keepalive_count);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, keepalive_required);
 | 
			
		||||
 | 
			
		||||
    GET_CONF_INT(conf, filename, admin_keepalive_interval);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_keepalive_count);
 | 
			
		||||
    GET_CONF_UINT(conf, filename, admin_keepalive_required);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
 error:
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Read the config file if it exists.
 | 
			
		||||
 * Only used in the remote case, hence the name.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
daemonConfigLoadFile(struct daemonConfig *data,
 | 
			
		||||
                     const char *filename,
 | 
			
		||||
                     bool allow_missing)
 | 
			
		||||
{
 | 
			
		||||
    virConfPtr conf;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    if (allow_missing &&
 | 
			
		||||
        access(filename, R_OK) == -1 &&
 | 
			
		||||
        errno == ENOENT)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    conf = virConfReadFile(filename, 0);
 | 
			
		||||
    if (!conf)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    ret = daemonConfigLoadOptions(data, filename, conf);
 | 
			
		||||
    virConfFree(conf);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int daemonConfigLoadData(struct daemonConfig *data,
 | 
			
		||||
                         const char *filename,
 | 
			
		||||
                         const char *filedata)
 | 
			
		||||
{
 | 
			
		||||
    virConfPtr conf;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    conf = virConfReadMem(filedata, strlen(filedata), 0);
 | 
			
		||||
    if (!conf)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    ret = daemonConfigLoadOptions(data, filename, conf);
 | 
			
		||||
    virConfFree(conf);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								daemon/libvirtd-config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								daemon/libvirtd-config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libvirtd-config.h: daemon start of day, guest process & i/o management
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006-2012, 2015 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, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __LIBVIRTD_CONFIG_H__
 | 
			
		||||
# define __LIBVIRTD_CONFIG_H__
 | 
			
		||||
 | 
			
		||||
# include "internal.h"
 | 
			
		||||
 | 
			
		||||
struct daemonConfig {
 | 
			
		||||
    char *host_uuid;
 | 
			
		||||
 | 
			
		||||
    int listen_tls;
 | 
			
		||||
    int listen_tcp;
 | 
			
		||||
    char *listen_addr;
 | 
			
		||||
    char *tls_port;
 | 
			
		||||
    char *tcp_port;
 | 
			
		||||
 | 
			
		||||
    char *unix_sock_admin_perms;
 | 
			
		||||
    char *unix_sock_ro_perms;
 | 
			
		||||
    char *unix_sock_rw_perms;
 | 
			
		||||
    char *unix_sock_group;
 | 
			
		||||
    char *unix_sock_dir;
 | 
			
		||||
 | 
			
		||||
    int auth_unix_rw;
 | 
			
		||||
    int auth_unix_ro;
 | 
			
		||||
    int auth_tcp;
 | 
			
		||||
    int auth_tls;
 | 
			
		||||
 | 
			
		||||
    char **access_drivers;
 | 
			
		||||
 | 
			
		||||
    int mdns_adv;
 | 
			
		||||
    char *mdns_name;
 | 
			
		||||
 | 
			
		||||
    int tls_no_verify_certificate;
 | 
			
		||||
    int tls_no_sanity_certificate;
 | 
			
		||||
    char **tls_allowed_dn_list;
 | 
			
		||||
    char **sasl_allowed_username_list;
 | 
			
		||||
 | 
			
		||||
    char *key_file;
 | 
			
		||||
    char *cert_file;
 | 
			
		||||
    char *ca_file;
 | 
			
		||||
    char *crl_file;
 | 
			
		||||
 | 
			
		||||
    int min_workers;
 | 
			
		||||
    int max_workers;
 | 
			
		||||
    int max_clients;
 | 
			
		||||
    int max_queued_clients;
 | 
			
		||||
    int max_anonymous_clients;
 | 
			
		||||
 | 
			
		||||
    int prio_workers;
 | 
			
		||||
 | 
			
		||||
    int max_requests;
 | 
			
		||||
    int max_client_requests;
 | 
			
		||||
 | 
			
		||||
    int log_level;
 | 
			
		||||
    char *log_filters;
 | 
			
		||||
    char *log_outputs;
 | 
			
		||||
 | 
			
		||||
    int audit_level;
 | 
			
		||||
    int audit_logging;
 | 
			
		||||
 | 
			
		||||
    int keepalive_interval;
 | 
			
		||||
    unsigned int keepalive_count;
 | 
			
		||||
    int keepalive_required;
 | 
			
		||||
 | 
			
		||||
    int admin_min_workers;
 | 
			
		||||
    int admin_max_workers;
 | 
			
		||||
    int admin_max_clients;
 | 
			
		||||
    int admin_max_queued_clients;
 | 
			
		||||
    int admin_max_client_requests;
 | 
			
		||||
 | 
			
		||||
    int admin_keepalive_interval;
 | 
			
		||||
    unsigned int admin_keepalive_count;
 | 
			
		||||
    int admin_keepalive_required;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int daemonConfigFilePath(bool privileged, char **configfile);
 | 
			
		||||
struct daemonConfig* daemonConfigNew(bool privileged);
 | 
			
		||||
void daemonConfigFree(struct daemonConfig *data);
 | 
			
		||||
int daemonConfigLoadFile(struct daemonConfig *data,
 | 
			
		||||
                         const char *filename,
 | 
			
		||||
                         bool allow_missing);
 | 
			
		||||
int daemonConfigLoadData(struct daemonConfig *data,
 | 
			
		||||
                         const char *filename,
 | 
			
		||||
                         const char *filedata);
 | 
			
		||||
 | 
			
		||||
#endif /* __LIBVIRTD_CONFIG_H__ */
 | 
			
		||||
							
								
								
									
										113
									
								
								daemon/libvirtd.aug
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								daemon/libvirtd.aug
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
(* /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_admin_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"
 | 
			
		||||
                           | bool_entry "tls_no_sanity_certificate"
 | 
			
		||||
                           | str_array_entry "tls_allowed_dn_list"
 | 
			
		||||
                           | str_array_entry "sasl_allowed_username_list"
 | 
			
		||||
                           | str_array_entry "access_drivers"
 | 
			
		||||
 | 
			
		||||
   let processing_entry = int_entry "min_workers"
 | 
			
		||||
                        | int_entry "max_workers"
 | 
			
		||||
                        | int_entry "max_clients"
 | 
			
		||||
                        | int_entry "max_queued_clients"
 | 
			
		||||
                        | int_entry "max_anonymous_clients"
 | 
			
		||||
                        | int_entry "max_requests"
 | 
			
		||||
                        | int_entry "max_client_requests"
 | 
			
		||||
                        | int_entry "prio_workers"
 | 
			
		||||
 | 
			
		||||
   let admin_processing_entry = int_entry "admin_min_workers"
 | 
			
		||||
                              | int_entry "admin_max_workers"
 | 
			
		||||
                              | int_entry "admin_max_clients"
 | 
			
		||||
                              | int_entry "admin_max_queued_clients"
 | 
			
		||||
                              | int_entry "admin_max_client_requests"
 | 
			
		||||
 | 
			
		||||
   let logging_entry = int_entry "log_level"
 | 
			
		||||
                     | str_entry "log_filters"
 | 
			
		||||
                     | str_entry "log_outputs"
 | 
			
		||||
                     | int_entry "log_buffer_size"
 | 
			
		||||
 | 
			
		||||
   let auditing_entry = int_entry "audit_level"
 | 
			
		||||
                      | bool_entry "audit_logging"
 | 
			
		||||
 | 
			
		||||
   let keepalive_entry = int_entry "keepalive_interval"
 | 
			
		||||
                       | int_entry "keepalive_count"
 | 
			
		||||
                       | bool_entry "keepalive_required"
 | 
			
		||||
 | 
			
		||||
   let admin_keepalive_entry = int_entry "admin_keepalive_interval"
 | 
			
		||||
                             | int_entry "admin_keepalive_count"
 | 
			
		||||
                             | bool_entry "admin_keepalive_required"
 | 
			
		||||
 | 
			
		||||
   let misc_entry = str_entry "host_uuid"
 | 
			
		||||
 | 
			
		||||
   (* 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
 | 
			
		||||
             | admin_processing_entry
 | 
			
		||||
             | logging_entry
 | 
			
		||||
             | auditing_entry
 | 
			
		||||
             | keepalive_entry
 | 
			
		||||
             | admin_keepalive_entry
 | 
			
		||||
             | misc_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
 | 
			
		||||
							
								
								
									
										1625
									
								
								daemon/libvirtd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1625
									
								
								daemon/libvirtd.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										453
									
								
								daemon/libvirtd.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										453
									
								
								daemon/libvirtd.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,453 @@
 | 
			
		||||
# 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
 | 
			
		||||
#
 | 
			
		||||
# If the libvirtd service is started in parallel with network
 | 
			
		||||
# startup (e.g. with systemd), binding to addresses other than
 | 
			
		||||
# the wildcards (0.0.0.0/::) might not be available yet.
 | 
			
		||||
#
 | 
			
		||||
#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 disabled by default, uncomment this to enable it
 | 
			
		||||
#mdns_adv = 1
 | 
			
		||||
 | 
			
		||||
# Override the default mDNS advertizement name. This must be
 | 
			
		||||
# unique on the immediate broadcast network.
 | 
			
		||||
#
 | 
			
		||||
# The default is "Virtualization Host HOSTNAME", where HOSTNAME
 | 
			
		||||
# is substituted for the short hostname of the machine (without domain)
 | 
			
		||||
#
 | 
			
		||||
#mdns_name = "Virtualization Host Joe Demo"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#################################################################
 | 
			
		||||
#
 | 
			
		||||
# UNIX socket access controls
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Beware that if you are changing *any* of these options, and you use
 | 
			
		||||
# socket activation with systemd, you need to adjust the settings in
 | 
			
		||||
# the libvirtd.socket file as well since it could impose a security
 | 
			
		||||
# risk if you rely on file permission checking only.
 | 
			
		||||
 | 
			
		||||
# Set the UNIX domain socket group ownership. This can be used to
 | 
			
		||||
# allow a 'trusted' set of users access to management capabilities
 | 
			
		||||
# without becoming root.
 | 
			
		||||
#
 | 
			
		||||
# 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, you may want to
 | 
			
		||||
# restrict this too.
 | 
			
		||||
#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 too.
 | 
			
		||||
#unix_sock_rw_perms = "0770"
 | 
			
		||||
 | 
			
		||||
# Set the UNIX socket permissions for the admin interface socket.
 | 
			
		||||
#
 | 
			
		||||
# Default allows only owner (root), do not change it unless you are
 | 
			
		||||
# sure to whom you are exposing the access to.
 | 
			
		||||
#unix_sock_admin_perms = "0700"
 | 
			
		||||
 | 
			
		||||
# 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"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Change the API access control scheme
 | 
			
		||||
#
 | 
			
		||||
# By default an authenticated user is allowed access
 | 
			
		||||
# to all APIs. Access drivers can place restrictions
 | 
			
		||||
# on this. By default the 'nop' driver is enabled,
 | 
			
		||||
# meaning no access control checks are done once a
 | 
			
		||||
# client has authenticated with libvirtd
 | 
			
		||||
#
 | 
			
		||||
#access_drivers = [ "polkit" ]
 | 
			
		||||
 | 
			
		||||
#################################################################
 | 
			
		||||
#
 | 
			
		||||
# 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 our own server certificates
 | 
			
		||||
#
 | 
			
		||||
# When libvirtd starts it performs some sanity checks against
 | 
			
		||||
# its own certificates.
 | 
			
		||||
#
 | 
			
		||||
# Default is to always run sanity checks. Uncommenting this
 | 
			
		||||
# will disable sanity checks which is not a good idea
 | 
			
		||||
#tls_no_sanity_certificate = 1
 | 
			
		||||
 | 
			
		||||
# 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 = 5000
 | 
			
		||||
 | 
			
		||||
# The maximum length of queue of connections waiting to be
 | 
			
		||||
# accepted by the daemon. Note, that some protocols supporting
 | 
			
		||||
# retransmission may obey this so that a later reattempt at
 | 
			
		||||
# connection succeeds.
 | 
			
		||||
#max_queued_clients = 1000
 | 
			
		||||
 | 
			
		||||
# The maximum length of queue of accepted but not yet
 | 
			
		||||
# authenticated clients. The default value is zero, meaning
 | 
			
		||||
# the feature is disabled.
 | 
			
		||||
#max_anonymous_clients = 20
 | 
			
		||||
 | 
			
		||||
# The minimum limit sets the number of workers to start up
 | 
			
		||||
# initially. If the number of active clients exceeds this,
 | 
			
		||||
# then more threads are spawned, up to max_workers limit.
 | 
			
		||||
# Typically you'd want max_workers to equal maximum number
 | 
			
		||||
# of clients allowed
 | 
			
		||||
#min_workers = 5
 | 
			
		||||
#max_workers = 20
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# The number of priority workers. If all workers from above
 | 
			
		||||
# pool are stuck, some calls marked as high priority
 | 
			
		||||
# (notably domainDestroy) can be executed in this pool.
 | 
			
		||||
#prio_workers = 5
 | 
			
		||||
 | 
			
		||||
# 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 impacts
 | 
			
		||||
# memory usage, currently each request requires 256 KB of
 | 
			
		||||
# memory. So by default up to 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
 | 
			
		||||
 | 
			
		||||
# Same processing controls, but this time for the admin interface.
 | 
			
		||||
# For description of each option, be so kind to scroll few lines
 | 
			
		||||
# upwards.
 | 
			
		||||
 | 
			
		||||
#admin_min_workers = 1
 | 
			
		||||
#admin_max_workers = 5
 | 
			
		||||
#admin_max_clients = 5
 | 
			
		||||
#admin_max_queued_clients = 5
 | 
			
		||||
#admin_max_client_requests = 5
 | 
			
		||||
 | 
			
		||||
#################################################################
 | 
			
		||||
#
 | 
			
		||||
# Logging controls
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Logging level: 4 errors, 3 warnings, 2 information, 1 debug
 | 
			
		||||
# basically 1 will log everything possible
 | 
			
		||||
# Note: Journald may employ rate limiting of the messages logged
 | 
			
		||||
# and thus lock up the libvirt daemon. To use the debug level with
 | 
			
		||||
# journald you have to specify it explicitly in 'log_outputs', otherwise
 | 
			
		||||
# only information level messages will be logged.
 | 
			
		||||
#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 one of:
 | 
			
		||||
#    x:name
 | 
			
		||||
#    x:+name
 | 
			
		||||
#      where name is a string which is matched against source file name,
 | 
			
		||||
#      e.g., "remote", "qemu", or "util/json", the optional "+" prefix
 | 
			
		||||
#      tells libvirt to log stack trace for each message matching name,
 | 
			
		||||
#      and x is the minimal level where matching messages should be logged:
 | 
			
		||||
#    1: DEBUG
 | 
			
		||||
#    2: INFO
 | 
			
		||||
#    3: WARNING
 | 
			
		||||
#    4: ERROR
 | 
			
		||||
#
 | 
			
		||||
# Multiple filters can be defined in a single @filters, they just need to be
 | 
			
		||||
# separated by spaces.
 | 
			
		||||
#
 | 
			
		||||
# e.g. to only get warning or errors from the remote layer and only errors
 | 
			
		||||
# from the event layer:
 | 
			
		||||
#log_filters="3:remote 4:event"
 | 
			
		||||
 | 
			
		||||
# Logging outputs:
 | 
			
		||||
# An output is one of the places to save logging information
 | 
			
		||||
# 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
 | 
			
		||||
#    x:journald
 | 
			
		||||
#      output to journald logging system
 | 
			
		||||
# In all case the x prefix is the minimal level, acting as a filter
 | 
			
		||||
#    1: DEBUG
 | 
			
		||||
#    2: INFO
 | 
			
		||||
#    3: WARNING
 | 
			
		||||
#    4: ERROR
 | 
			
		||||
#
 | 
			
		||||
# Multiple outputs can be defined, they just need to be separated by spaces.
 | 
			
		||||
# e.g. to log all warnings and errors to syslog under the libvirtd ident:
 | 
			
		||||
#log_outputs="3:syslog:libvirtd"
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Log debug buffer size:
 | 
			
		||||
#
 | 
			
		||||
# This configuration option is no longer used, since the global
 | 
			
		||||
# log buffer functionality has been removed. Please configure
 | 
			
		||||
# suitable log_outputs/log_filters settings to obtain logs.
 | 
			
		||||
#log_buffer_size = 64
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##################################################################
 | 
			
		||||
#
 | 
			
		||||
# Auditing
 | 
			
		||||
#
 | 
			
		||||
# This setting allows usage of the auditing subsystem to be altered:
 | 
			
		||||
#
 | 
			
		||||
#   audit_level == 0  -> disable all auditing
 | 
			
		||||
#   audit_level == 1  -> enable auditing, only if enabled on host (default)
 | 
			
		||||
#   audit_level == 2  -> enable auditing, and exit if disabled on host
 | 
			
		||||
#
 | 
			
		||||
#audit_level = 2
 | 
			
		||||
#
 | 
			
		||||
# If set to 1, then audit messages will also be sent
 | 
			
		||||
# via libvirt logging infrastructure. Defaults to 0
 | 
			
		||||
#
 | 
			
		||||
#audit_logging = 1
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
# UUID of the host:
 | 
			
		||||
# Provide the UUID of the host here in case the command
 | 
			
		||||
# 'dmidecode -s system-uuid' does not provide a valid uuid. In case
 | 
			
		||||
# 'dmidecode' does not provide a valid UUID and none is provided here, a
 | 
			
		||||
# temporary UUID will be generated.
 | 
			
		||||
# Keep the format of the example UUID below. UUID must not have all digits
 | 
			
		||||
# be the same.
 | 
			
		||||
 | 
			
		||||
# NB This default all-zeros UUID will not work. Replace
 | 
			
		||||
# it with the output of the 'uuidgen' command and then
 | 
			
		||||
# uncomment this entry
 | 
			
		||||
#host_uuid = "00000000-0000-0000-0000-000000000000"
 | 
			
		||||
 | 
			
		||||
###################################################################
 | 
			
		||||
# Keepalive protocol:
 | 
			
		||||
# This allows libvirtd to detect broken client connections or even
 | 
			
		||||
# dead clients.  A keepalive message is sent to a client after
 | 
			
		||||
# keepalive_interval seconds of inactivity to check if the client is
 | 
			
		||||
# still responding; keepalive_count is a maximum number of keepalive
 | 
			
		||||
# messages that are allowed to be sent to the client without getting
 | 
			
		||||
# any response before the connection is considered broken.  In other
 | 
			
		||||
# words, the connection is automatically closed approximately after
 | 
			
		||||
# keepalive_interval * (keepalive_count + 1) seconds since the last
 | 
			
		||||
# message received from the client.  If keepalive_interval is set to
 | 
			
		||||
# -1, libvirtd will never send keepalive requests; however clients
 | 
			
		||||
# can still send them and the daemon will send responses.  When
 | 
			
		||||
# keepalive_count is set to 0, connections will be automatically
 | 
			
		||||
# closed after keepalive_interval seconds of inactivity without
 | 
			
		||||
# sending any keepalive messages.
 | 
			
		||||
#
 | 
			
		||||
#keepalive_interval = 5
 | 
			
		||||
#keepalive_count = 5
 | 
			
		||||
#
 | 
			
		||||
# If set to 1, libvirtd will refuse to talk to clients that do not
 | 
			
		||||
# support keepalive protocol.  Defaults to 0.
 | 
			
		||||
#
 | 
			
		||||
#keepalive_required = 1
 | 
			
		||||
 | 
			
		||||
# Keepalive settings for the admin interface
 | 
			
		||||
#admin_keepalive_interval = 5
 | 
			
		||||
#admin_keepalive_count = 5
 | 
			
		||||
#
 | 
			
		||||
#admin_keepalive_required = 1
 | 
			
		||||
							
								
								
									
										92
									
								
								daemon/libvirtd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								daemon/libvirtd.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * libvirtd.h: daemon data structure definitions
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006-2015 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, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef LIBVIRTD_H__
 | 
			
		||||
# define LIBVIRTD_H__
 | 
			
		||||
 | 
			
		||||
# define VIR_ENUM_SENTINELS
 | 
			
		||||
 | 
			
		||||
# include <rpc/types.h>
 | 
			
		||||
# include <rpc/xdr.h>
 | 
			
		||||
# include "remote_protocol.h"
 | 
			
		||||
# include "admin_protocol.h"
 | 
			
		||||
# include "lxc_protocol.h"
 | 
			
		||||
# include "qemu_protocol.h"
 | 
			
		||||
# include "virthread.h"
 | 
			
		||||
 | 
			
		||||
# if WITH_SASL
 | 
			
		||||
#  include "virnetsaslcontext.h"
 | 
			
		||||
# endif
 | 
			
		||||
# include "virnetserverprogram.h"
 | 
			
		||||
 | 
			
		||||
typedef struct daemonClientStream daemonClientStream;
 | 
			
		||||
typedef daemonClientStream *daemonClientStreamPtr;
 | 
			
		||||
typedef struct daemonClientPrivate daemonClientPrivate;
 | 
			
		||||
typedef daemonClientPrivate *daemonClientPrivatePtr;
 | 
			
		||||
typedef struct daemonAdmClientPrivate daemonAdmClientPrivate;
 | 
			
		||||
typedef daemonAdmClientPrivate *daemonAdmClientPrivatePtr;
 | 
			
		||||
typedef struct daemonClientEventCallback daemonClientEventCallback;
 | 
			
		||||
typedef daemonClientEventCallback *daemonClientEventCallbackPtr;
 | 
			
		||||
 | 
			
		||||
/* Stores the per-client connection state */
 | 
			
		||||
struct daemonClientPrivate {
 | 
			
		||||
    /* Hold while accessing any data except conn */
 | 
			
		||||
    virMutex lock;
 | 
			
		||||
 | 
			
		||||
    daemonClientEventCallbackPtr *domainEventCallbacks;
 | 
			
		||||
    size_t ndomainEventCallbacks;
 | 
			
		||||
    daemonClientEventCallbackPtr *networkEventCallbacks;
 | 
			
		||||
    size_t nnetworkEventCallbacks;
 | 
			
		||||
    daemonClientEventCallbackPtr *qemuEventCallbacks;
 | 
			
		||||
    size_t nqemuEventCallbacks;
 | 
			
		||||
 | 
			
		||||
# if WITH_SASL
 | 
			
		||||
    virNetSASLSessionPtr sasl;
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
    /* 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;
 | 
			
		||||
 | 
			
		||||
    daemonClientStreamPtr streams;
 | 
			
		||||
    bool keepalive_supported;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Separate private data for admin connection */
 | 
			
		||||
struct daemonAdmClientPrivate {
 | 
			
		||||
    /* Just a placeholder, not that there is anything to be locked */
 | 
			
		||||
    virMutex lock;
 | 
			
		||||
 | 
			
		||||
    virNetDaemonPtr dmn;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
# if WITH_SASL
 | 
			
		||||
extern virNetSASLContextPtr saslCtxt;
 | 
			
		||||
# endif
 | 
			
		||||
extern virNetServerProgramPtr remoteProgram;
 | 
			
		||||
extern virNetServerProgramPtr qemuProgram;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										125
									
								
								daemon/libvirtd.init.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								daemon/libvirtd.init.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
#!/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: avahi-daemon
 | 
			
		||||
# Should-Start: virtlockd
 | 
			
		||||
# Required-Stop: $network messagebus
 | 
			
		||||
# Should-Stop: $named
 | 
			
		||||
# Default-Start: 3 4 5
 | 
			
		||||
# Default-Stop: 0 1 2 6
 | 
			
		||||
# 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
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
export QEMU_AUDIO_DRV
 | 
			
		||||
export SDL_AUDIODRIVER
 | 
			
		||||
 | 
			
		||||
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/*
 | 
			
		||||
 | 
			
		||||
    # LIBVIRTD_NOFILES_LIMIT from /etc/sysconfig/libvirtd is not handled
 | 
			
		||||
    # automatically
 | 
			
		||||
    if [ -n "$LIBVIRTD_NOFILES_LIMIT" ]; then
 | 
			
		||||
        ulimit -n "$LIBVIRTD_NOFILES_LIMIT"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    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 -rf @localstatedir@/cache/libvirt/*
 | 
			
		||||
    else
 | 
			
		||||
        exit $RETVAL
 | 
			
		||||
    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|force-reload|try-restart}"
 | 
			
		||||
        exit 2
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
exit $RETVAL
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
@localstatedir@/log/libvirt/libxl/*.log {
 | 
			
		||||
        size 2097153
 | 
			
		||||
        weekly
 | 
			
		||||
        missingok
 | 
			
		||||
        rotate 4
 | 
			
		||||
        compress
 | 
			
		||||
        delaycompress
 | 
			
		||||
        copytruncate
 | 
			
		||||
        minsize 100k
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
@localstatedir@/log/libvirt/lxc/*.log {
 | 
			
		||||
        size 2097153
 | 
			
		||||
        weekly
 | 
			
		||||
        missingok
 | 
			
		||||
        rotate 4
 | 
			
		||||
        compress
 | 
			
		||||
        delaycompress
 | 
			
		||||
        copytruncate
 | 
			
		||||
        minsize 100k
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										208
									
								
								daemon/libvirtd.pod.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								daemon/libvirtd.pod.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,208 @@
 | 
			
		||||
=head1 NAME
 | 
			
		||||
 | 
			
		||||
libvirtd - libvirtd management daemon
 | 
			
		||||
 | 
			
		||||
=head1 SYNOPSIS
 | 
			
		||||
 | 
			
		||||
B<libvirtd> [ -dlv ] [ -f config_file ] [ -p pid_file ] [ -t timeout_seconds ]
 | 
			
		||||
 | 
			
		||||
B<libvirtd> --version
 | 
			
		||||
 | 
			
		||||
=head1 DESCRIPTION
 | 
			
		||||
 | 
			
		||||
The B<libvirtd> program is the server side daemon component of the libvirt
 | 
			
		||||
virtualization management system.
 | 
			
		||||
 | 
			
		||||
This daemon runs on host servers and performs required management tasks for
 | 
			
		||||
virtualized guests.  This includes activities such as starting, stopping
 | 
			
		||||
and migrating guests between host servers, configuring and manipulating
 | 
			
		||||
networking, and managing storage for use by guests.
 | 
			
		||||
 | 
			
		||||
The libvirt client libraries and utilities connect to this daemon to issue
 | 
			
		||||
tasks and collect information about the configuration and resources of the host
 | 
			
		||||
system and guests.
 | 
			
		||||
 | 
			
		||||
By default, the libvirtd daemon listens for requests on a local Unix domain
 | 
			
		||||
socket.  Using the B<-l>|B<--listen> command line option, the libvirtd daemon
 | 
			
		||||
can be instructed to additionally listen on a TCP/IP socket.  The TCP/IP socket
 | 
			
		||||
to use is defined in the libvirtd configuration file.
 | 
			
		||||
 | 
			
		||||
Restarting libvirtd does not impact running guests.  Guests continue to operate
 | 
			
		||||
and will be picked up automatically if their XML configuration has been
 | 
			
		||||
defined.  Any guests whose XML configuration has not been defined will be lost
 | 
			
		||||
from the configuration.
 | 
			
		||||
 | 
			
		||||
=head1 OPTIONS
 | 
			
		||||
 | 
			
		||||
=over
 | 
			
		||||
 | 
			
		||||
=item B<-h, --help>
 | 
			
		||||
 | 
			
		||||
Display command line help usage then exit.
 | 
			
		||||
 | 
			
		||||
=item B<-d, --daemon>
 | 
			
		||||
 | 
			
		||||
Run as a daemon & write PID file.
 | 
			
		||||
 | 
			
		||||
=item B<-f, --config> I<FILE>
 | 
			
		||||
 | 
			
		||||
Use this configuration file, overriding the default value.
 | 
			
		||||
 | 
			
		||||
=item B<-l, --listen>
 | 
			
		||||
 | 
			
		||||
Listen for TCP/IP connections.
 | 
			
		||||
 | 
			
		||||
=item B<-p, --pid-file> I<FILE>
 | 
			
		||||
 | 
			
		||||
Use this name for the PID file, overriding the default value.
 | 
			
		||||
 | 
			
		||||
=item B<-t, --timeout> I<SECONDS>
 | 
			
		||||
 | 
			
		||||
Exit after timeout period (in seconds) elapse with no client connections
 | 
			
		||||
or registered resources.  Be aware that resources such as autostart
 | 
			
		||||
networks will result in never reaching the timeout, even when there are
 | 
			
		||||
no client connections.
 | 
			
		||||
 | 
			
		||||
=item B<-v, --verbose>
 | 
			
		||||
 | 
			
		||||
Enable output of verbose messages.
 | 
			
		||||
 | 
			
		||||
=item B<    --version>
 | 
			
		||||
 | 
			
		||||
Display version information then exit.
 | 
			
		||||
 | 
			
		||||
=back
 | 
			
		||||
 | 
			
		||||
=head1 SIGNALS
 | 
			
		||||
 | 
			
		||||
On receipt of B<SIGHUP> libvirtd will reload its configuration.
 | 
			
		||||
 | 
			
		||||
=head1 FILES
 | 
			
		||||
 | 
			
		||||
=head2 When run as B<root>.
 | 
			
		||||
 | 
			
		||||
=over
 | 
			
		||||
 | 
			
		||||
=item F<SYSCONFDIR/libvirtd.conf>
 | 
			
		||||
 | 
			
		||||
The default configuration file used by libvirtd, unless overridden on the
 | 
			
		||||
command line using the B<-f>|B<--config> option.
 | 
			
		||||
 | 
			
		||||
=item F<LOCALSTATEDIR/run/libvirt/libvirt-sock>
 | 
			
		||||
 | 
			
		||||
=item F<LOCALSTATEDIR/run/libvirt/libvirt-sock-ro>
 | 
			
		||||
 | 
			
		||||
The sockets libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<SYSCONFDIR/pki/CA/cacert.pem>
 | 
			
		||||
 | 
			
		||||
The TLS B<Certificate Authority> certificate libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<SYSCONFDIR/pki/libvirt/servercert.pem>
 | 
			
		||||
 | 
			
		||||
The TLS B<Server> certificate libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<SYSCONFDIR/pki/libvirt/private/serverkey.pem>
 | 
			
		||||
 | 
			
		||||
The TLS B<Server> private key libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<LOCALSTATEDIR/run/libvirtd.pid>
 | 
			
		||||
 | 
			
		||||
The PID file to use, unless overridden by the B<-p>|B<--pid-file> option.
 | 
			
		||||
 | 
			
		||||
=back
 | 
			
		||||
 | 
			
		||||
=head2 When run as B<non-root>.
 | 
			
		||||
 | 
			
		||||
=over
 | 
			
		||||
 | 
			
		||||
=item F<$XDG_CONFIG_HOME/libvirtd.conf>
 | 
			
		||||
 | 
			
		||||
The default configuration file used by libvirtd, unless overridden on the
 | 
			
		||||
command line using the B<-f>|B<--config> option.
 | 
			
		||||
 | 
			
		||||
=item F<$XDG_RUNTIME_DIR/libvirt/libvirt-sock>
 | 
			
		||||
 | 
			
		||||
The socket libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<$HOME/.pki/libvirt/cacert.pem>
 | 
			
		||||
 | 
			
		||||
The TLS B<Certificate Authority> certificate libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<$HOME/.pki/libvirt/servercert.pem>
 | 
			
		||||
 | 
			
		||||
The TLS B<Server> certificate libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<$HOME/.pki/libvirt/serverkey.pem>
 | 
			
		||||
 | 
			
		||||
The TLS B<Server> private key libvirtd will use.
 | 
			
		||||
 | 
			
		||||
=item F<$XDG_RUNTIME_DIR/libvirt/libvirtd.pid>
 | 
			
		||||
 | 
			
		||||
The PID file to use, unless overridden by the B<-p>|B<--pid-file> option.
 | 
			
		||||
 | 
			
		||||
=item If $XDG_CONFIG_HOME is not set in your environment, libvirtd will use F<$HOME/.config>
 | 
			
		||||
 | 
			
		||||
=item If $XDG_RUNTIME_DIR is not set in your environment, libvirtd will use F<$HOME/.cache>
 | 
			
		||||
 | 
			
		||||
=back
 | 
			
		||||
 | 
			
		||||
=head1 EXAMPLES
 | 
			
		||||
 | 
			
		||||
To retrieve the version of libvirtd:
 | 
			
		||||
 | 
			
		||||
 # libvirtd --version
 | 
			
		||||
 libvirtd (libvirt) 0.8.2
 | 
			
		||||
 #
 | 
			
		||||
 | 
			
		||||
To start libvirtd, instructing it to daemonize and create a PID file:
 | 
			
		||||
 | 
			
		||||
 # libvirtd -d
 | 
			
		||||
 # ls -la LOCALSTATEDIR/run/libvirtd.pid
 | 
			
		||||
 -rw-r--r-- 1 root root 6 Jul  9 02:40 LOCALSTATEDIR/run/libvirtd.pid
 | 
			
		||||
 #
 | 
			
		||||
 | 
			
		||||
=head1 BUGS
 | 
			
		||||
 | 
			
		||||
Please report all bugs you discover.  This should be done via either:
 | 
			
		||||
 | 
			
		||||
=over
 | 
			
		||||
 | 
			
		||||
=item a) the mailing list
 | 
			
		||||
 | 
			
		||||
L<http://libvirt.org/contact.html>
 | 
			
		||||
 | 
			
		||||
=item or,
 | 
			
		||||
 | 
			
		||||
B<>
 | 
			
		||||
 | 
			
		||||
=item b) the bug tracker
 | 
			
		||||
 | 
			
		||||
L<http://libvirt.org/bugs.html>
 | 
			
		||||
 | 
			
		||||
=item Alternatively, you may report bugs to your software distributor / vendor.
 | 
			
		||||
 | 
			
		||||
=back
 | 
			
		||||
 | 
			
		||||
=head1 AUTHORS
 | 
			
		||||
 | 
			
		||||
Please refer to the AUTHORS file distributed with libvirt.
 | 
			
		||||
 | 
			
		||||
=head1 COPYRIGHT
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2006-2012 Red Hat, Inc., and the authors listed in the
 | 
			
		||||
libvirt AUTHORS file.
 | 
			
		||||
 | 
			
		||||
=head1 LICENSE
 | 
			
		||||
 | 
			
		||||
libvirtd is distributed under the terms of the GNU LGPL v2.1+.
 | 
			
		||||
This is free software; see the source for copying conditions. There
 | 
			
		||||
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE
 | 
			
		||||
 | 
			
		||||
=head1 SEE ALSO
 | 
			
		||||
 | 
			
		||||
L<virsh(1)>, L<virt-install(1)>, L<virt-xml-validate(1)>, L<virt-top(1)>,
 | 
			
		||||
L<virt-df(1)>, L<http://www.libvirt.org/>
 | 
			
		||||
 | 
			
		||||
=cut
 | 
			
		||||
							
								
								
									
										51
									
								
								daemon/libvirtd.policy.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								daemon/libvirtd.policy.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!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) 2012 Red Hat, Inc.
 | 
			
		||||
Copyright (C) 2007 Daniel P. Berrange <berrange redhat com>
 | 
			
		||||
 | 
			
		||||
This library is free software; you can redistribute it and/or
 | 
			
		||||
modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
License as published by the Free Software Foundation; either
 | 
			
		||||
version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This library is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
License along with this library.  If not, see
 | 
			
		||||
<http://www.gnu.org/licenses/>.
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
        <!-- Any program can use libvirt in read/write mode if they
 | 
			
		||||
             provide the root password -->
 | 
			
		||||
        <allow_any>@authaction@</allow_any>
 | 
			
		||||
        <allow_inactive>@authaction@</allow_inactive>
 | 
			
		||||
        <allow_active>@authaction@</allow_active>
 | 
			
		||||
      </defaults>
 | 
			
		||||
    </action>
 | 
			
		||||
</policyconfig>
 | 
			
		||||
							
								
								
									
										9
									
								
								daemon/libvirtd.qemu.logrotate.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								daemon/libvirtd.qemu.logrotate.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
@localstatedir@/log/libvirt/qemu/*.log {
 | 
			
		||||
        weekly
 | 
			
		||||
        missingok
 | 
			
		||||
        rotate 4
 | 
			
		||||
        compress
 | 
			
		||||
        delaycompress
 | 
			
		||||
        copytruncate
 | 
			
		||||
        minsize 100k
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								daemon/libvirtd.sasl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								daemon/libvirtd.sasl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
# Some older builds of MIT kerberos on Linux ignore this option &
 | 
			
		||||
# instead need KRB5_KTNAME env var.
 | 
			
		||||
# For modern Linux, and other OS, this should be sufficient
 | 
			
		||||
#
 | 
			
		||||
# There is no default value here, uncomment if you need this
 | 
			
		||||
#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 -f [sasldb_path]' to browse it
 | 
			
		||||
sasldb_path: /etc/libvirt/passwd.db
 | 
			
		||||
							
								
								
									
										22
									
								
								daemon/libvirtd.service.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								daemon/libvirtd.service.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Virtualization daemon
 | 
			
		||||
Before=libvirt-guests.service
 | 
			
		||||
After=network.target
 | 
			
		||||
After=dbus.service
 | 
			
		||||
After=iscsid.service
 | 
			
		||||
After=apparmor.service
 | 
			
		||||
Documentation=man:libvirtd(8)
 | 
			
		||||
Documentation=http://libvirt.org
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type=notify
 | 
			
		||||
EnvironmentFile=-/etc/sysconfig/libvirtd
 | 
			
		||||
ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
 | 
			
		||||
ExecReload=/bin/kill -HUP $MAINPID
 | 
			
		||||
KillMode=process
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
# Override the maximum number of opened files
 | 
			
		||||
#LimitNOFILE=2048
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
							
								
								
									
										11
									
								
								daemon/libvirtd.socket.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								daemon/libvirtd.socket.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
[Socket]
 | 
			
		||||
ListenStream=@runstatedir@/libvirt/libvirt-sock
 | 
			
		||||
ListenStream=@runstatedir@/libvirt/libvirt-sock-ro
 | 
			
		||||
 | 
			
		||||
; The following settings must match libvirtd.conf file in order to
 | 
			
		||||
; work as expected because libvirtd can't change them later.
 | 
			
		||||
; SocketMode=0777 is safe only if authentication on the socket is set
 | 
			
		||||
; up.  For further information, please see the libvirtd.conf file.
 | 
			
		||||
SocketMode=0777
 | 
			
		||||
SocketUser=root
 | 
			
		||||
SocketGroup=root
 | 
			
		||||
							
								
								
									
										33
									
								
								daemon/libvirtd.sysconf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								daemon/libvirtd.sysconf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
# Override the default config file
 | 
			
		||||
# NOTE: This setting is no longer honoured if using
 | 
			
		||||
# systemd. Set '--config /etc/libvirt/libvirtd.conf'
 | 
			
		||||
# in LIBVIRTD_ARGS instead.
 | 
			
		||||
#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, unless vnc_allow_host_audio
 | 
			
		||||
# is enabled in /etc/libvirt/qemu.conf
 | 
			
		||||
#QEMU_AUDIO_DRV=sdl
 | 
			
		||||
#
 | 
			
		||||
#SDL_AUDIODRIVER=pulse
 | 
			
		||||
 | 
			
		||||
# Override the maximum number of opened files.
 | 
			
		||||
# This only works with traditional init scripts.
 | 
			
		||||
# In the systemd world, the limit can only be changed by overriding
 | 
			
		||||
# LimitNOFILE for libvirtd.service. To do that, just create a *.conf
 | 
			
		||||
# file in /etc/systemd/system/libvirtd.service.d/ (for example
 | 
			
		||||
# /etc/systemd/system/libvirtd.service.d/openfiles.conf) and write
 | 
			
		||||
# the following two lines in it:
 | 
			
		||||
#   [Service]
 | 
			
		||||
#   LimitNOFILE=2048
 | 
			
		||||
#
 | 
			
		||||
#LIBVIRTD_NOFILES_LIMIT=2048
 | 
			
		||||
							
								
								
									
										9
									
								
								daemon/libvirtd.uml.logrotate.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								daemon/libvirtd.uml.logrotate.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
@localstatedir@/log/libvirt/uml/*.log {
 | 
			
		||||
        weekly
 | 
			
		||||
        missingok
 | 
			
		||||
        rotate 4
 | 
			
		||||
        compress
 | 
			
		||||
        delaycompress
 | 
			
		||||
        copytruncate
 | 
			
		||||
        minsize 100k
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								daemon/libvirtd.upstart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								daemon/libvirtd.upstart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
# libvirtd upstart job
 | 
			
		||||
#
 | 
			
		||||
# XXX wait for rc to get all dependent initscripts started
 | 
			
		||||
# from sysv libvirtd initscript: Required-Start: $network messagebus
 | 
			
		||||
start on stopped rc RUNLEVEL=[345]
 | 
			
		||||
stop on runlevel [!345]
 | 
			
		||||
 | 
			
		||||
respawn
 | 
			
		||||
 | 
			
		||||
script
 | 
			
		||||
    LIBVIRTD_CONFIG=
 | 
			
		||||
    LIBVIRTD_ARGS=
 | 
			
		||||
    KRB5_KTNAME=/etc/libvirt/krb5.tab
 | 
			
		||||
 | 
			
		||||
    if [ -f /etc/sysconfig/libvirtd ]; then
 | 
			
		||||
        . /etc/sysconfig/libvirtd
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    export QEMU_AUDIO_DRV
 | 
			
		||||
    export SDL_AUDIODRIVER
 | 
			
		||||
    export KRB5_KTNAME
 | 
			
		||||
 | 
			
		||||
    LIBVIRTD_CONFIG_ARGS=
 | 
			
		||||
    if [ -n "$LIBVIRTD_CONFIG" ]; then
 | 
			
		||||
        LIBVIRTD_CONFIG_ARGS="--config $LIBVIRTD_CONFIG"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    # DAEMON_COREFILE_LIMIT from /etc/sysconfig/libvirtd is not handled
 | 
			
		||||
    # automatically
 | 
			
		||||
    if [ -n "$DAEMON_COREFILE_LIMIT" ]; then
 | 
			
		||||
        ulimit -c "$DAEMON_COREFILE_LIMIT"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    # LIBVIRTD_NOFILES_LIMIT from /etc/sysconfig/libvirtd is not handled
 | 
			
		||||
    # automatically
 | 
			
		||||
    if [ -n "$LIBVIRTD_NOFILES_LIMIT" ]; then
 | 
			
		||||
        ulimit -n "$LIBVIRTD_NOFILES_LIMIT"
 | 
			
		||||
    fi
 | 
			
		||||
    mkdir -p /var/cache/libvirt
 | 
			
		||||
    rm -rf /var/cache/libvirt/*
 | 
			
		||||
 | 
			
		||||
    exec /usr/sbin/libvirtd $LIBVIRTD_CONFIG_ARGS $LIBVIRTD_ARGS
 | 
			
		||||
end script
 | 
			
		||||
 | 
			
		||||
post-stop script
 | 
			
		||||
    rm -rf /var/cache/libvirt/*
 | 
			
		||||
end script
 | 
			
		||||
							
								
								
									
										6834
									
								
								daemon/remote.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6834
									
								
								daemon/remote.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										45
									
								
								daemon/remote.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								daemon/remote.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Richard W.M. Jones <rjones@redhat.com>
 | 
			
		||||
 * Author: Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __LIBVIRTD_REMOTE_H__
 | 
			
		||||
# define __LIBVIRTD_REMOTE_H__
 | 
			
		||||
 | 
			
		||||
# include "remote_protocol.h"
 | 
			
		||||
# include "rpc/virnetserverprogram.h"
 | 
			
		||||
# include "rpc/virnetserverclient.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern virNetServerProgramProc remoteProcs[];
 | 
			
		||||
extern size_t remoteNProcs;
 | 
			
		||||
 | 
			
		||||
extern virNetServerProgramProc lxcProcs[];
 | 
			
		||||
extern size_t lxcNProcs;
 | 
			
		||||
 | 
			
		||||
extern virNetServerProgramProc qemuProcs[];
 | 
			
		||||
extern size_t qemuNProcs;
 | 
			
		||||
 | 
			
		||||
void remoteClientFreeFunc(void *data);
 | 
			
		||||
void *remoteClientInitHook(virNetServerClientPtr client,
 | 
			
		||||
                           void *opaque);
 | 
			
		||||
 | 
			
		||||
#endif /* __LIBVIRTD_REMOTE_H__ */
 | 
			
		||||
							
								
								
									
										777
									
								
								daemon/stream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										777
									
								
								daemon/stream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,777 @@
 | 
			
		||||
/*
 | 
			
		||||
 * stream.c: APIs for managing client streams
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2009-2014 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library.  If not, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "stream.h"
 | 
			
		||||
#include "remote.h"
 | 
			
		||||
#include "viralloc.h"
 | 
			
		||||
#include "virlog.h"
 | 
			
		||||
#include "virnetserverclient.h"
 | 
			
		||||
#include "virerror.h"
 | 
			
		||||
 | 
			
		||||
#define VIR_FROM_THIS VIR_FROM_STREAMS
 | 
			
		||||
 | 
			
		||||
VIR_LOG_INIT("daemon.stream");
 | 
			
		||||
 | 
			
		||||
struct daemonClientStream {
 | 
			
		||||
    daemonClientPrivatePtr priv;
 | 
			
		||||
    int refs;
 | 
			
		||||
 | 
			
		||||
    virNetServerProgramPtr prog;
 | 
			
		||||
 | 
			
		||||
    virStreamPtr st;
 | 
			
		||||
    int procedure;
 | 
			
		||||
    int serial;
 | 
			
		||||
 | 
			
		||||
    unsigned int recvEOF : 1;
 | 
			
		||||
    unsigned int closed : 1;
 | 
			
		||||
 | 
			
		||||
    int filterID;
 | 
			
		||||
 | 
			
		||||
    virNetMessagePtr rx;
 | 
			
		||||
    int tx;
 | 
			
		||||
 | 
			
		||||
    daemonClientStreamPtr next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleWrite(virNetServerClientPtr client,
 | 
			
		||||
                        daemonClientStream *stream);
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleRead(virNetServerClientPtr client,
 | 
			
		||||
                       daemonClientStream *stream);
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleFinish(virNetServerClientPtr client,
 | 
			
		||||
                         daemonClientStream *stream,
 | 
			
		||||
                         virNetMessagePtr msg);
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleAbort(virNetServerClientPtr client,
 | 
			
		||||
                        daemonClientStream *stream,
 | 
			
		||||
                        virNetMessagePtr msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
daemonStreamUpdateEvents(daemonClientStream *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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
daemonStreamMessageFinished(virNetMessagePtr msg ATTRIBUTE_UNUSED,
 | 
			
		||||
                            void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    daemonClientStream *stream = opaque;
 | 
			
		||||
    VIR_DEBUG("stream=%p proc=%d serial=%d",
 | 
			
		||||
              stream, msg->header.proc, msg->header.serial);
 | 
			
		||||
 | 
			
		||||
    stream->tx = 1;
 | 
			
		||||
    daemonStreamUpdateEvents(stream);
 | 
			
		||||
 | 
			
		||||
    daemonFreeClientStream(NULL, stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Callback that gets invoked when a stream becomes writable/readable
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
daemonStreamEvent(virStreamPtr st, int events, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    virNetServerClientPtr client = opaque;
 | 
			
		||||
    daemonClientStream *stream;
 | 
			
		||||
    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
 | 
			
		||||
 | 
			
		||||
    virMutexLock(&priv->lock);
 | 
			
		||||
 | 
			
		||||
    stream = priv->streams;
 | 
			
		||||
    while (stream) {
 | 
			
		||||
        if (stream->st == st)
 | 
			
		||||
            break;
 | 
			
		||||
        stream = stream->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!stream) {
 | 
			
		||||
        VIR_WARN("event for client=%p stream st=%p, but missing stream state", client, st);
 | 
			
		||||
        virStreamEventRemoveCallback(st);
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("st=%p events=%d EOF=%d closed=%d", st, events, stream->recvEOF, stream->closed);
 | 
			
		||||
 | 
			
		||||
    if (!stream->closed &&
 | 
			
		||||
        (events & VIR_STREAM_EVENT_WRITABLE)) {
 | 
			
		||||
        if (daemonStreamHandleWrite(client, stream) < 0) {
 | 
			
		||||
            daemonRemoveClientStream(client, stream);
 | 
			
		||||
            virNetServerClientClose(client);
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!stream->closed && !stream->recvEOF &&
 | 
			
		||||
        (events & (VIR_STREAM_EVENT_READABLE))) {
 | 
			
		||||
        events = events & ~(VIR_STREAM_EVENT_READABLE);
 | 
			
		||||
        if (daemonStreamHandleRead(client, stream) < 0) {
 | 
			
		||||
            daemonRemoveClientStream(client, stream);
 | 
			
		||||
            virNetServerClientClose(client);
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
        /* If we detected EOF during read processing,
 | 
			
		||||
         * then clear hangup/error conditions, since
 | 
			
		||||
         * we want the client to see the EOF message
 | 
			
		||||
         * we just sent them
 | 
			
		||||
         */
 | 
			
		||||
        if (stream->recvEOF)
 | 
			
		||||
            events = events & ~(VIR_STREAM_EVENT_HANGUP |
 | 
			
		||||
                                VIR_STREAM_EVENT_ERROR);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If we have a completion/abort message, always process it */
 | 
			
		||||
    if (stream->rx) {
 | 
			
		||||
        virNetMessagePtr msg = stream->rx;
 | 
			
		||||
        switch (msg->header.status) {
 | 
			
		||||
        case VIR_NET_CONTINUE:
 | 
			
		||||
            /* nada */
 | 
			
		||||
            break;
 | 
			
		||||
        case VIR_NET_OK:
 | 
			
		||||
            virNetMessageQueueServe(&stream->rx);
 | 
			
		||||
            if (daemonStreamHandleFinish(client, stream, msg) < 0) {
 | 
			
		||||
                virNetMessageFree(msg);
 | 
			
		||||
                daemonRemoveClientStream(client, stream);
 | 
			
		||||
                virNetServerClientClose(client);
 | 
			
		||||
                goto cleanup;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case VIR_NET_ERROR:
 | 
			
		||||
        default:
 | 
			
		||||
            virNetMessageQueueServe(&stream->rx);
 | 
			
		||||
            if (daemonStreamHandleAbort(client, stream, msg) < 0) {
 | 
			
		||||
                virNetMessageFree(msg);
 | 
			
		||||
                daemonRemoveClientStream(client, stream);
 | 
			
		||||
                virNetServerClientClose(client);
 | 
			
		||||
                goto cleanup;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* If we got HANGUP, we need to only send an empty
 | 
			
		||||
     * packet so the client sees an EOF and cleans up
 | 
			
		||||
     */
 | 
			
		||||
    if (!stream->closed && !stream->recvEOF &&
 | 
			
		||||
        (events & VIR_STREAM_EVENT_HANGUP)) {
 | 
			
		||||
        virNetMessagePtr msg;
 | 
			
		||||
        events &= ~(VIR_STREAM_EVENT_HANGUP);
 | 
			
		||||
        stream->tx = 0;
 | 
			
		||||
        stream->recvEOF = 1;
 | 
			
		||||
        if (!(msg = virNetMessageNew(false))) {
 | 
			
		||||
            daemonRemoveClientStream(client, stream);
 | 
			
		||||
            virNetServerClientClose(client);
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
        msg->cb = daemonStreamMessageFinished;
 | 
			
		||||
        msg->opaque = stream;
 | 
			
		||||
        stream->refs++;
 | 
			
		||||
        if (virNetServerProgramSendStreamData(remoteProgram,
 | 
			
		||||
                                              client,
 | 
			
		||||
                                              msg,
 | 
			
		||||
                                              stream->procedure,
 | 
			
		||||
                                              stream->serial,
 | 
			
		||||
                                              "", 0) < 0) {
 | 
			
		||||
            virNetMessageFree(msg);
 | 
			
		||||
            daemonRemoveClientStream(client, stream);
 | 
			
		||||
            virNetServerClientClose(client);
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!stream->closed &&
 | 
			
		||||
        (events & (VIR_STREAM_EVENT_ERROR | VIR_STREAM_EVENT_HANGUP))) {
 | 
			
		||||
        int ret;
 | 
			
		||||
        virNetMessagePtr msg;
 | 
			
		||||
        virNetMessageError rerr;
 | 
			
		||||
 | 
			
		||||
        memset(&rerr, 0, sizeof(rerr));
 | 
			
		||||
        stream->closed = 1;
 | 
			
		||||
        virStreamEventRemoveCallback(stream->st);
 | 
			
		||||
        virStreamAbort(stream->st);
 | 
			
		||||
        if (events & VIR_STREAM_EVENT_HANGUP)
 | 
			
		||||
            virReportError(VIR_ERR_RPC,
 | 
			
		||||
                           "%s", _("stream had unexpected termination"));
 | 
			
		||||
        else
 | 
			
		||||
            virReportError(VIR_ERR_RPC,
 | 
			
		||||
                           "%s", _("stream had I/O failure"));
 | 
			
		||||
 | 
			
		||||
        msg = virNetMessageNew(false);
 | 
			
		||||
        if (!msg) {
 | 
			
		||||
            ret = -1;
 | 
			
		||||
        } else {
 | 
			
		||||
            ret = virNetServerProgramSendStreamError(remoteProgram,
 | 
			
		||||
                                                     client,
 | 
			
		||||
                                                     msg,
 | 
			
		||||
                                                     &rerr,
 | 
			
		||||
                                                     stream->procedure,
 | 
			
		||||
                                                     stream->serial);
 | 
			
		||||
        }
 | 
			
		||||
        daemonRemoveClientStream(client, stream);
 | 
			
		||||
        if (ret < 0)
 | 
			
		||||
            virNetServerClientClose(client);
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (stream->closed) {
 | 
			
		||||
        daemonRemoveClientStream(client, stream);
 | 
			
		||||
    } else {
 | 
			
		||||
        daemonStreamUpdateEvents(stream);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 cleanup:
 | 
			
		||||
    virMutexUnlock(&priv->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
 | 
			
		||||
daemonStreamFilter(virNetServerClientPtr client ATTRIBUTE_UNUSED,
 | 
			
		||||
                   virNetMessagePtr msg,
 | 
			
		||||
                   void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    daemonClientStream *stream = opaque;
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
    virMutexLock(&stream->priv->lock);
 | 
			
		||||
 | 
			
		||||
    if (msg->header.type != VIR_NET_STREAM)
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
 | 
			
		||||
    if (!virNetServerProgramMatches(stream->prog, msg))
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
 | 
			
		||||
    if (msg->header.proc != stream->procedure ||
 | 
			
		||||
        msg->header.serial != stream->serial)
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("Incoming client=%p, rx=%p, serial=%d, proc=%d, status=%d",
 | 
			
		||||
              client, stream->rx, msg->header.proc,
 | 
			
		||||
              msg->header.serial, msg->header.status);
 | 
			
		||||
 | 
			
		||||
    virNetMessageQueuePush(&stream->rx, msg);
 | 
			
		||||
    daemonStreamUpdateEvents(stream);
 | 
			
		||||
    ret = 1;
 | 
			
		||||
 | 
			
		||||
 cleanup:
 | 
			
		||||
    virMutexUnlock(&stream->priv->lock);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @conn: a connection object to associate the stream with
 | 
			
		||||
 * @header: the method call to associate with the stream
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new stream for this conn
 | 
			
		||||
 *
 | 
			
		||||
 * Returns a new stream object, or NULL upon OOM
 | 
			
		||||
 */
 | 
			
		||||
daemonClientStream *
 | 
			
		||||
daemonCreateClientStream(virNetServerClientPtr client,
 | 
			
		||||
                         virStreamPtr st,
 | 
			
		||||
                         virNetServerProgramPtr prog,
 | 
			
		||||
                         virNetMessageHeaderPtr header)
 | 
			
		||||
{
 | 
			
		||||
    daemonClientStream *stream;
 | 
			
		||||
    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
 | 
			
		||||
              client, header->proc, header->serial, st);
 | 
			
		||||
 | 
			
		||||
    if (VIR_ALLOC(stream) < 0)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    stream->refs = 1;
 | 
			
		||||
    stream->priv = priv;
 | 
			
		||||
    stream->prog = virObjectRef(prog);
 | 
			
		||||
    stream->procedure = header->proc;
 | 
			
		||||
    stream->serial = header->serial;
 | 
			
		||||
    stream->filterID = -1;
 | 
			
		||||
    stream->st = st;
 | 
			
		||||
 | 
			
		||||
    return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @stream: an unused client stream
 | 
			
		||||
 *
 | 
			
		||||
 * Frees the memory associated with this inactive client
 | 
			
		||||
 * stream
 | 
			
		||||
 */
 | 
			
		||||
int daemonFreeClientStream(virNetServerClientPtr client,
 | 
			
		||||
                           daemonClientStream *stream)
 | 
			
		||||
{
 | 
			
		||||
    virNetMessagePtr msg;
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
    if (!stream)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    stream->refs--;
 | 
			
		||||
    if (stream->refs)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("client=%p, proc=%d, serial=%d",
 | 
			
		||||
              client, stream->procedure, stream->serial);
 | 
			
		||||
 | 
			
		||||
    virObjectUnref(stream->prog);
 | 
			
		||||
 | 
			
		||||
    msg = stream->rx;
 | 
			
		||||
    while (msg) {
 | 
			
		||||
        virNetMessagePtr tmp = msg->next;
 | 
			
		||||
        if (client) {
 | 
			
		||||
            /* Send a dummy reply to free up 'msg' & unblock client rx */
 | 
			
		||||
            virNetMessageClear(msg);
 | 
			
		||||
            msg->header.type = VIR_NET_REPLY;
 | 
			
		||||
            if (virNetServerClientSendMessage(client, msg) < 0) {
 | 
			
		||||
                virNetServerClientImmediateClose(client);
 | 
			
		||||
                virNetMessageFree(msg);
 | 
			
		||||
                ret = -1;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            virNetMessageFree(msg);
 | 
			
		||||
        }
 | 
			
		||||
        msg = tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virObjectUnref(stream->st);
 | 
			
		||||
    VIR_FREE(stream);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @client: a locked client to add the stream to
 | 
			
		||||
 * @stream: a stream to add
 | 
			
		||||
 */
 | 
			
		||||
int daemonAddClientStream(virNetServerClientPtr client,
 | 
			
		||||
                          daemonClientStream *stream,
 | 
			
		||||
                          bool transmit)
 | 
			
		||||
{
 | 
			
		||||
    VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p, transmit=%d",
 | 
			
		||||
              client, stream->procedure, stream->serial, stream->st, transmit);
 | 
			
		||||
    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
 | 
			
		||||
 | 
			
		||||
    if (stream->filterID != -1) {
 | 
			
		||||
        VIR_WARN("Filter already added to client %p", client);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (virStreamEventAddCallback(stream->st, 0,
 | 
			
		||||
                                  daemonStreamEvent, client,
 | 
			
		||||
                                  virObjectFreeCallback) < 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    virObjectRef(client);
 | 
			
		||||
 | 
			
		||||
    if ((stream->filterID = virNetServerClientAddFilter(client,
 | 
			
		||||
                                                        daemonStreamFilter,
 | 
			
		||||
                                                        stream)) < 0) {
 | 
			
		||||
        virStreamEventRemoveCallback(stream->st);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (transmit)
 | 
			
		||||
        stream->tx = 1;
 | 
			
		||||
 | 
			
		||||
    virMutexLock(&priv->lock);
 | 
			
		||||
    stream->next = priv->streams;
 | 
			
		||||
    priv->streams = stream;
 | 
			
		||||
 | 
			
		||||
    daemonStreamUpdateEvents(stream);
 | 
			
		||||
 | 
			
		||||
    virMutexUnlock(&priv->lock);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @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
 | 
			
		||||
daemonRemoveClientStream(virNetServerClientPtr client,
 | 
			
		||||
                         daemonClientStream *stream)
 | 
			
		||||
{
 | 
			
		||||
    VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
 | 
			
		||||
              client, stream->procedure, stream->serial, stream->st);
 | 
			
		||||
    daemonClientPrivatePtr priv = virNetServerClientGetPrivateData(client);
 | 
			
		||||
    daemonClientStream *curr = priv->streams;
 | 
			
		||||
    daemonClientStream *prev = NULL;
 | 
			
		||||
 | 
			
		||||
    if (stream->filterID != -1) {
 | 
			
		||||
        virNetServerClientRemoveFilter(client,
 | 
			
		||||
                                       stream->filterID);
 | 
			
		||||
        stream->filterID = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!stream->closed) {
 | 
			
		||||
        virStreamEventRemoveCallback(stream->st);
 | 
			
		||||
        virStreamAbort(stream->st);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (curr) {
 | 
			
		||||
        if (curr == stream) {
 | 
			
		||||
            if (prev)
 | 
			
		||||
                prev->next = curr->next;
 | 
			
		||||
            else
 | 
			
		||||
                priv->streams = curr->next;
 | 
			
		||||
            return daemonFreeClientStream(client, stream);
 | 
			
		||||
        }
 | 
			
		||||
        prev = curr;
 | 
			
		||||
        curr = curr->next;
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
daemonRemoveAllClientStreams(daemonClientStream *stream)
 | 
			
		||||
{
 | 
			
		||||
    daemonClientStream *tmp;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("stream=%p", stream);
 | 
			
		||||
 | 
			
		||||
    while (stream) {
 | 
			
		||||
        tmp = stream->next;
 | 
			
		||||
 | 
			
		||||
        if (!stream->closed) {
 | 
			
		||||
            virStreamEventRemoveCallback(stream->st);
 | 
			
		||||
            virStreamAbort(stream->st);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        daemonFreeClientStream(NULL, stream);
 | 
			
		||||
 | 
			
		||||
        VIR_DEBUG("next stream=%p", tmp);
 | 
			
		||||
        stream = tmp;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *   -1  if fatal error occurred
 | 
			
		||||
 *    0  if message was fully processed
 | 
			
		||||
 *    1  if message is still being processed
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleWriteData(virNetServerClientPtr client,
 | 
			
		||||
                            daemonClientStream *stream,
 | 
			
		||||
                            virNetMessagePtr msg)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d, len=%zu, offset=%zu",
 | 
			
		||||
              client, stream, msg->header.proc, msg->header.serial,
 | 
			
		||||
              msg->bufferLength, msg->bufferOffset);
 | 
			
		||||
 | 
			
		||||
    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 {
 | 
			
		||||
        virNetMessageError rerr;
 | 
			
		||||
 | 
			
		||||
        memset(&rerr, 0, sizeof(rerr));
 | 
			
		||||
 | 
			
		||||
        VIR_INFO("Stream send failed");
 | 
			
		||||
        stream->closed = 1;
 | 
			
		||||
        return virNetServerProgramSendReplyError(stream->prog,
 | 
			
		||||
                                                 client,
 | 
			
		||||
                                                 msg,
 | 
			
		||||
                                                 &rerr,
 | 
			
		||||
                                                 &msg->header);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process a finish handshake from the client.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns a VIR_NET_OK confirmation if successful, or a VIR_NET_ERROR
 | 
			
		||||
 * if there was a stream error
 | 
			
		||||
 *
 | 
			
		||||
 * Returns 0 if successfully sent RPC reply, -1 upon fatal error
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleFinish(virNetServerClientPtr client,
 | 
			
		||||
                         daemonClientStream *stream,
 | 
			
		||||
                         virNetMessagePtr msg)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d",
 | 
			
		||||
              client, stream, msg->header.proc, msg->header.serial);
 | 
			
		||||
 | 
			
		||||
    stream->closed = 1;
 | 
			
		||||
    virStreamEventRemoveCallback(stream->st);
 | 
			
		||||
    ret = virStreamFinish(stream->st);
 | 
			
		||||
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        virNetMessageError rerr;
 | 
			
		||||
        memset(&rerr, 0, sizeof(rerr));
 | 
			
		||||
        return virNetServerProgramSendReplyError(stream->prog,
 | 
			
		||||
                                                 client,
 | 
			
		||||
                                                 msg,
 | 
			
		||||
                                                 &rerr,
 | 
			
		||||
                                                 &msg->header);
 | 
			
		||||
    } else {
 | 
			
		||||
        /* Send zero-length confirm */
 | 
			
		||||
        return virNetServerProgramSendStreamData(stream->prog,
 | 
			
		||||
                                                 client,
 | 
			
		||||
                                                 msg,
 | 
			
		||||
                                                 stream->procedure,
 | 
			
		||||
                                                 stream->serial,
 | 
			
		||||
                                                 NULL, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process an abort request from the client.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns 0 if successfully aborted, -1 upon error
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
daemonStreamHandleAbort(virNetServerClientPtr client,
 | 
			
		||||
                        daemonClientStream *stream,
 | 
			
		||||
                        virNetMessagePtr msg)
 | 
			
		||||
{
 | 
			
		||||
    VIR_DEBUG("client=%p, stream=%p, proc=%d, serial=%d",
 | 
			
		||||
              client, stream, msg->header.proc, msg->header.serial);
 | 
			
		||||
    virNetMessageError rerr;
 | 
			
		||||
 | 
			
		||||
    memset(&rerr, 0, sizeof(rerr));
 | 
			
		||||
 | 
			
		||||
    stream->closed = 1;
 | 
			
		||||
    virStreamEventRemoveCallback(stream->st);
 | 
			
		||||
    virStreamAbort(stream->st);
 | 
			
		||||
 | 
			
		||||
    if (msg->header.status == VIR_NET_ERROR) {
 | 
			
		||||
        virReportError(VIR_ERR_RPC,
 | 
			
		||||
                       "%s", _("stream aborted at client request"));
 | 
			
		||||
    } else {
 | 
			
		||||
        VIR_WARN("unexpected stream status %d", msg->header.status);
 | 
			
		||||
        virReportError(VIR_ERR_RPC,
 | 
			
		||||
                       _("stream aborted with unexpected status %d"),
 | 
			
		||||
                       msg->header.status);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return virNetServerProgramSendReplyError(remoteProgram,
 | 
			
		||||
                                             client,
 | 
			
		||||
                                             msg,
 | 
			
		||||
                                             &rerr,
 | 
			
		||||
                                             &msg->header);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
daemonStreamHandleWrite(virNetServerClientPtr client,
 | 
			
		||||
                        daemonClientStream *stream)
 | 
			
		||||
{
 | 
			
		||||
    VIR_DEBUG("client=%p, stream=%p", client, stream);
 | 
			
		||||
 | 
			
		||||
    while (stream->rx && !stream->closed) {
 | 
			
		||||
        virNetMessagePtr msg = stream->rx;
 | 
			
		||||
        int ret;
 | 
			
		||||
 | 
			
		||||
        switch (msg->header.status) {
 | 
			
		||||
        case VIR_NET_OK:
 | 
			
		||||
            ret = daemonStreamHandleFinish(client, stream, msg);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case VIR_NET_CONTINUE:
 | 
			
		||||
            ret = daemonStreamHandleWriteData(client, stream, msg);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case VIR_NET_ERROR:
 | 
			
		||||
        default:
 | 
			
		||||
            ret = daemonStreamHandleAbort(client, stream, msg);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ret > 0)
 | 
			
		||||
            break;  /* still processing data from msg */
 | 
			
		||||
 | 
			
		||||
        virNetMessageQueueServe(&stream->rx);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            virNetMessageFree(msg);
 | 
			
		||||
            virNetServerClientImmediateClose(client);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 'CONTINUE' messages don't send a reply (unless error
 | 
			
		||||
         * occurred), so to release the 'msg' object we need to
 | 
			
		||||
         * send a fake zero-length reply. Nothing actually gets
 | 
			
		||||
         * onto the wire, but this causes the client to reset
 | 
			
		||||
         * its active request count / throttling
 | 
			
		||||
         */
 | 
			
		||||
        if (msg->header.status == VIR_NET_CONTINUE) {
 | 
			
		||||
            virNetMessageClear(msg);
 | 
			
		||||
            msg->header.type = VIR_NET_REPLY;
 | 
			
		||||
            if (virNetServerClientSendMessage(client, msg) < 0) {
 | 
			
		||||
                virNetMessageFree(msg);
 | 
			
		||||
                virNetServerClientImmediateClose(client);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Invoked when a stream is signalled as having data
 | 
			
		||||
 * available to read. This reads up to 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
 | 
			
		||||
daemonStreamHandleRead(virNetServerClientPtr client,
 | 
			
		||||
                       daemonClientStream *stream)
 | 
			
		||||
{
 | 
			
		||||
    char *buffer;
 | 
			
		||||
    size_t bufferLen = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
 | 
			
		||||
              client, stream, stream->tx, stream->closed);
 | 
			
		||||
 | 
			
		||||
    /* We might have had an event pending before we shut
 | 
			
		||||
     * down the stream, so if we're marked as closed,
 | 
			
		||||
     * then do nothing
 | 
			
		||||
     */
 | 
			
		||||
    if (stream->closed)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    /* 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) {
 | 
			
		||||
        virNetMessagePtr msg;
 | 
			
		||||
        virNetMessageError rerr;
 | 
			
		||||
 | 
			
		||||
        memset(&rerr, 0, sizeof(rerr));
 | 
			
		||||
 | 
			
		||||
        if (!(msg = virNetMessageNew(false)))
 | 
			
		||||
            ret = -1;
 | 
			
		||||
        else
 | 
			
		||||
            ret = virNetServerProgramSendStreamError(remoteProgram,
 | 
			
		||||
                                                     client,
 | 
			
		||||
                                                     msg,
 | 
			
		||||
                                                     &rerr,
 | 
			
		||||
                                                     stream->procedure,
 | 
			
		||||
                                                     stream->serial);
 | 
			
		||||
    } else {
 | 
			
		||||
        virNetMessagePtr msg;
 | 
			
		||||
        stream->tx = 0;
 | 
			
		||||
        if (ret == 0)
 | 
			
		||||
            stream->recvEOF = 1;
 | 
			
		||||
        if (!(msg = virNetMessageNew(false)))
 | 
			
		||||
            ret = -1;
 | 
			
		||||
 | 
			
		||||
        if (msg) {
 | 
			
		||||
            msg->cb = daemonStreamMessageFinished;
 | 
			
		||||
            msg->opaque = stream;
 | 
			
		||||
            stream->refs++;
 | 
			
		||||
            ret = virNetServerProgramSendStreamData(remoteProgram,
 | 
			
		||||
                                                    client,
 | 
			
		||||
                                                    msg,
 | 
			
		||||
                                                    stream->procedure,
 | 
			
		||||
                                                    stream->serial,
 | 
			
		||||
                                                    buffer, ret);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VIR_FREE(buffer);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								daemon/stream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								daemon/stream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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, see
 | 
			
		||||
 * <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Daniel P. Berrange <berrange@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __LIBVIRTD_STREAM_H__
 | 
			
		||||
# define __LIBVIRTD_STREAM_H__
 | 
			
		||||
 | 
			
		||||
# include "libvirtd.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
daemonClientStream *
 | 
			
		||||
daemonCreateClientStream(virNetServerClientPtr client,
 | 
			
		||||
                         virStreamPtr st,
 | 
			
		||||
                         virNetServerProgramPtr prog,
 | 
			
		||||
                         virNetMessageHeaderPtr hdr);
 | 
			
		||||
 | 
			
		||||
int daemonFreeClientStream(virNetServerClientPtr client,
 | 
			
		||||
                           daemonClientStream *stream);
 | 
			
		||||
 | 
			
		||||
int daemonAddClientStream(virNetServerClientPtr client,
 | 
			
		||||
                          daemonClientStream *stream,
 | 
			
		||||
                          bool transmit);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
daemonRemoveClientStream(virNetServerClientPtr client,
 | 
			
		||||
                         daemonClientStream *stream);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
daemonRemoveAllClientStreams(daemonClientStream *stream);
 | 
			
		||||
 | 
			
		||||
#endif /* __LIBVIRTD_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										63
									
								
								daemon/test_libvirtd.aug.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								daemon/test_libvirtd.aug.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
module Test_libvirtd =
 | 
			
		||||
   ::CONFIG::
 | 
			
		||||
 | 
			
		||||
   test Libvirtd.lns get conf =
 | 
			
		||||
        { "listen_tls" = "0" }
 | 
			
		||||
        { "listen_tcp" = "1" }
 | 
			
		||||
        { "tls_port" = "16514" }
 | 
			
		||||
        { "tcp_port" = "16509" }
 | 
			
		||||
        { "listen_addr" = "192.168.0.1" }
 | 
			
		||||
        { "mdns_adv" = "1" }
 | 
			
		||||
        { "mdns_name" = "Virtualization Host Joe Demo" }
 | 
			
		||||
        { "unix_sock_group" = "libvirt" }
 | 
			
		||||
        { "unix_sock_ro_perms" = "0777" }
 | 
			
		||||
        { "unix_sock_rw_perms" = "0770" }
 | 
			
		||||
        { "unix_sock_admin_perms" = "0700" }
 | 
			
		||||
        { "unix_sock_dir" = "/var/run/libvirt" }
 | 
			
		||||
        { "auth_unix_ro" = "none" }
 | 
			
		||||
        { "auth_unix_rw" = "none" }
 | 
			
		||||
        { "auth_tcp" = "sasl" }
 | 
			
		||||
        { "auth_tls" = "none" }
 | 
			
		||||
        { "access_drivers"
 | 
			
		||||
             { "1" = "polkit" }
 | 
			
		||||
        }
 | 
			
		||||
        { "key_file" = "/etc/pki/libvirt/private/serverkey.pem" }
 | 
			
		||||
        { "cert_file" = "/etc/pki/libvirt/servercert.pem" }
 | 
			
		||||
        { "ca_file" = "/etc/pki/CA/cacert.pem" }
 | 
			
		||||
        { "crl_file" = "/etc/pki/CA/crl.pem" }
 | 
			
		||||
        { "tls_no_sanity_certificate" = "1" }
 | 
			
		||||
        { "tls_no_verify_certificate" = "1" }
 | 
			
		||||
        { "tls_allowed_dn_list"
 | 
			
		||||
             { "1" = "DN1"}
 | 
			
		||||
             { "2" = "DN2"}
 | 
			
		||||
        }
 | 
			
		||||
        { "sasl_allowed_username_list"
 | 
			
		||||
             { "1" = "joe@EXAMPLE.COM" }
 | 
			
		||||
             { "2" = "fred@EXAMPLE.COM" }
 | 
			
		||||
        }
 | 
			
		||||
        { "max_clients" = "5000" }
 | 
			
		||||
        { "max_queued_clients" = "1000" }
 | 
			
		||||
        { "max_anonymous_clients" = "20" }
 | 
			
		||||
        { "min_workers" = "5" }
 | 
			
		||||
        { "max_workers" = "20" }
 | 
			
		||||
        { "prio_workers" = "5" }
 | 
			
		||||
        { "max_requests" = "20" }
 | 
			
		||||
        { "max_client_requests" = "5" }
 | 
			
		||||
        { "admin_min_workers" = "1" }
 | 
			
		||||
        { "admin_max_workers" = "5" }
 | 
			
		||||
        { "admin_max_clients" = "5" }
 | 
			
		||||
        { "admin_max_queued_clients" = "5" }
 | 
			
		||||
        { "admin_max_client_requests" = "5" }
 | 
			
		||||
        { "log_level" = "3" }
 | 
			
		||||
        { "log_filters" = "3:remote 4:event" }
 | 
			
		||||
        { "log_outputs" = "3:syslog:libvirtd" }
 | 
			
		||||
        { "log_buffer_size" = "64" }
 | 
			
		||||
        { "audit_level" = "2" }
 | 
			
		||||
        { "audit_logging" = "1" }
 | 
			
		||||
        { "host_uuid" = "00000000-0000-0000-0000-000000000000" }
 | 
			
		||||
        { "keepalive_interval" = "5" }
 | 
			
		||||
        { "keepalive_count" = "5" }
 | 
			
		||||
        { "keepalive_required" = "1" }
 | 
			
		||||
        { "admin_keepalive_interval" = "5" }
 | 
			
		||||
        { "admin_keepalive_count" = "5" }
 | 
			
		||||
        { "admin_keepalive_required" = "1" }
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>404 page not found</h1>
 | 
			
		||||
@@ -9,11 +9,16 @@
 | 
			
		||||
      page you were looking for. You might want to try
 | 
			
		||||
    </p>
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li>going back to the <a href="https://libvirt.org/">home page</a> to find
 | 
			
		||||
      <li>going back to the <a href="http://libvirt.org/">home page</a> to find
 | 
			
		||||
        a collection of links to interesting pages on this site</li>
 | 
			
		||||
      <li>using the search box at the top right corner of the screen to
 | 
			
		||||
        locate the content on this site or mailing list archives</li>
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    <p class="image">
 | 
			
		||||
      <img src="/libvirtLogo404.png" alt="libvirt Logo"/>
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										642
									
								
								docs/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										642
									
								
								docs/Makefile.am
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
## Copyright (C) 2005-2016 Red Hat, Inc.
 | 
			
		||||
## Copyright (C) 2005-2015 Red Hat, Inc.
 | 
			
		||||
##
 | 
			
		||||
## This library is free software; you can redistribute it and/or
 | 
			
		||||
## modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
@@ -16,151 +16,74 @@
 | 
			
		||||
## License along with this library.  If not, see
 | 
			
		||||
## <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
HTML_DIR = $(docdir)/html
 | 
			
		||||
SUBDIRS= schemas
 | 
			
		||||
 | 
			
		||||
modules = \
 | 
			
		||||
	libvirt-common \
 | 
			
		||||
	libvirt-domain \
 | 
			
		||||
	libvirt-domain-checkpoint \
 | 
			
		||||
	libvirt-domain-snapshot \
 | 
			
		||||
	libvirt-event \
 | 
			
		||||
	libvirt-host \
 | 
			
		||||
	libvirt-interface \
 | 
			
		||||
	libvirt-network \
 | 
			
		||||
	libvirt-nodedev \
 | 
			
		||||
	libvirt-nwfilter \
 | 
			
		||||
	libvirt-secret \
 | 
			
		||||
	libvirt-storage \
 | 
			
		||||
	libvirt-stream \
 | 
			
		||||
	virterror \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
PERL = perl
 | 
			
		||||
 | 
			
		||||
modules_admin = libvirt-admin
 | 
			
		||||
modules_qemu = libvirt-qemu
 | 
			
		||||
modules_lxc = libvirt-lxc
 | 
			
		||||
# The directory containing the source code (if it contains documentation).
 | 
			
		||||
DOC_SOURCE_DIR=../src
 | 
			
		||||
 | 
			
		||||
all: vpathhack
 | 
			
		||||
DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
 | 
			
		||||
 | 
			
		||||
# This hack enables us to view the web pages
 | 
			
		||||
# from within the uninstalled build tree
 | 
			
		||||
vpathhack:
 | 
			
		||||
	@for dir in fonts js logos; \
 | 
			
		||||
	do \
 | 
			
		||||
	  test -e $$dir || ln -s $(srcdir)/$$dir $$dir ; \
 | 
			
		||||
	done
 | 
			
		||||
	@for file in $(css); \
 | 
			
		||||
	do \
 | 
			
		||||
	  test -e $$file || ln -s $(srcdir)/$$file $$file ; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
	for dir in fonts js logos; \
 | 
			
		||||
	do \
 | 
			
		||||
	  rm -f $$dir ; \
 | 
			
		||||
	done
 | 
			
		||||
	for file in $(css); \
 | 
			
		||||
	do \
 | 
			
		||||
	  rm -f $$file ; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
apihtml = \
 | 
			
		||||
  html/index.html \
 | 
			
		||||
apihtml =					\
 | 
			
		||||
  html/index.html				\
 | 
			
		||||
  $(apihtml_generated)
 | 
			
		||||
 | 
			
		||||
apihtml_generated = \
 | 
			
		||||
	$(addprefix html/libvirt-,$(addsuffix .html,$(modules))) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
  html/libvirt-libvirt-domain.html		\
 | 
			
		||||
  html/libvirt-libvirt-domain-snapshot.html	\
 | 
			
		||||
  html/libvirt-libvirt-event.html		\
 | 
			
		||||
  html/libvirt-libvirt-host.html		\
 | 
			
		||||
  html/libvirt-libvirt-interface.html		\
 | 
			
		||||
  html/libvirt-libvirt-network.html		\
 | 
			
		||||
  html/libvirt-libvirt-nodedev.html		\
 | 
			
		||||
  html/libvirt-libvirt-nwfilter.html		\
 | 
			
		||||
  html/libvirt-libvirt-secret.html		\
 | 
			
		||||
  html/libvirt-libvirt-storage.html		\
 | 
			
		||||
  html/libvirt-libvirt-stream.html		\
 | 
			
		||||
  html/libvirt-virterror.html
 | 
			
		||||
 | 
			
		||||
apiadminhtml = \
 | 
			
		||||
  html/index-admin.html \
 | 
			
		||||
  $(apiadminhtml_generated)
 | 
			
		||||
 | 
			
		||||
apiadminhtml_generated = \
 | 
			
		||||
	$(addprefix html/libvirt-,$(addsuffix .html,$(modules_admin))) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
apiqemuhtml = \
 | 
			
		||||
  html/index-qemu.html \
 | 
			
		||||
  $(apiqemuhtml_generated)
 | 
			
		||||
 | 
			
		||||
apiqemuhtml_generated = \
 | 
			
		||||
	$(addprefix html/libvirt-,$(addsuffix .html,$(modules_qemu))) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
apilxchtml = \
 | 
			
		||||
  html/index-lxc.html \
 | 
			
		||||
  $(apilxchtml_generated)
 | 
			
		||||
 | 
			
		||||
apilxchtml_generated = \
 | 
			
		||||
	$(addprefix html/libvirt-,$(addsuffix .html,$(modules_lxc))) \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
apipng = \
 | 
			
		||||
  html/left.png \
 | 
			
		||||
  html/up.png \
 | 
			
		||||
  html/home.png \
 | 
			
		||||
apipng =	\
 | 
			
		||||
  html/left.png	\
 | 
			
		||||
  html/up.png	\
 | 
			
		||||
  html/home.png	\
 | 
			
		||||
  html/right.png
 | 
			
		||||
 | 
			
		||||
apirefdir = $(HTML_DIR)/html
 | 
			
		||||
apiref_DATA = $(apihtml) $(apiadminhtml) $(apiqemuhtml) $(apilxchtml) $(apipng)
 | 
			
		||||
devhelphtml =			\
 | 
			
		||||
  devhelp/libvirt.devhelp	\
 | 
			
		||||
  devhelp/index.html		\
 | 
			
		||||
  devhelp/general.html		\
 | 
			
		||||
  devhelp/libvirt-virterror.html
 | 
			
		||||
 | 
			
		||||
css = \
 | 
			
		||||
css =         \
 | 
			
		||||
  generic.css \
 | 
			
		||||
  libvirt.css \
 | 
			
		||||
  mobile.css \
 | 
			
		||||
  main.css
 | 
			
		||||
 | 
			
		||||
javascript = \
 | 
			
		||||
  js/main.js \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
devhelppng =		\
 | 
			
		||||
  devhelp/home.png	\
 | 
			
		||||
  devhelp/left.png	\
 | 
			
		||||
  devhelp/right.png	\
 | 
			
		||||
  devhelp/up.png
 | 
			
		||||
 | 
			
		||||
javascriptdir = $(HTML_DIR)/js
 | 
			
		||||
javascript_DATA = $(javascript)
 | 
			
		||||
devhelpcss = devhelp/style.css
 | 
			
		||||
 | 
			
		||||
fonts = \
 | 
			
		||||
  fonts/LICENSE.md \
 | 
			
		||||
  fonts/stylesheet.css \
 | 
			
		||||
  fonts/overpass-bold-italic.woff \
 | 
			
		||||
  fonts/overpass-bold.woff \
 | 
			
		||||
  fonts/overpass-italic.woff \
 | 
			
		||||
  fonts/overpass-light-italic.woff \
 | 
			
		||||
  fonts/overpass-light.woff \
 | 
			
		||||
  fonts/overpass-mono-bold.woff \
 | 
			
		||||
  fonts/overpass-mono-light.woff \
 | 
			
		||||
  fonts/overpass-mono-regular.woff \
 | 
			
		||||
  fonts/overpass-mono-semibold.woff \
 | 
			
		||||
  fonts/overpass-regular.woff
 | 
			
		||||
 | 
			
		||||
fontsdir = $(HTML_DIR)/fonts
 | 
			
		||||
fonts_DATA = $(fonts)
 | 
			
		||||
 | 
			
		||||
logofiles = \
 | 
			
		||||
  logos/logo-base.svg \
 | 
			
		||||
  logos/logo-square.svg \
 | 
			
		||||
  logos/logo-square-powered.svg \
 | 
			
		||||
  logos/logo-banner-dark.svg \
 | 
			
		||||
  logos/logo-banner-light.svg \
 | 
			
		||||
  logos/logo-square-96.png \
 | 
			
		||||
  logos/logo-square-128.png \
 | 
			
		||||
  logos/logo-square-192.png \
 | 
			
		||||
  logos/logo-square-256.png \
 | 
			
		||||
  logos/logo-square-powered-96.png \
 | 
			
		||||
  logos/logo-square-powered-128.png \
 | 
			
		||||
  logos/logo-square-powered-192.png \
 | 
			
		||||
  logos/logo-square-powered-256.png \
 | 
			
		||||
  logos/logo-banner-dark-256.png \
 | 
			
		||||
  logos/logo-banner-dark-800.png \
 | 
			
		||||
  logos/logo-banner-light-256.png \
 | 
			
		||||
  logos/logo-banner-light-800.png
 | 
			
		||||
 | 
			
		||||
logofilesdir = $(HTML_DIR)/logos
 | 
			
		||||
logofiles_DATA = $(logofiles)
 | 
			
		||||
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 \
 | 
			
		||||
  migration-managed-direct.png \
 | 
			
		||||
  migration-managed-p2p.png \
 | 
			
		||||
  migration-native.png \
 | 
			
		||||
@@ -171,171 +94,53 @@ gif = \
 | 
			
		||||
  architecture.gif \
 | 
			
		||||
  node.gif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
internals_html_in = \
 | 
			
		||||
  $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
 | 
			
		||||
internals_rst = \
 | 
			
		||||
  $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.rst))
 | 
			
		||||
internals_rst_html_in = \
 | 
			
		||||
  $(internals_rst:%.rst=%.html.in)
 | 
			
		||||
internals_html = \
 | 
			
		||||
  $(internals_html_in:%.html.in=%.html) \
 | 
			
		||||
  $(internals_rst_html_in:%.html.in=%.html)
 | 
			
		||||
internals_html = $(internals_html_in:%.html.in=%.html)
 | 
			
		||||
 | 
			
		||||
internalsdir = $(HTML_DIR)/internals
 | 
			
		||||
internals_DATA = $(internals_html)
 | 
			
		||||
# todo.html is special - it is shipped in the tarball, but we
 | 
			
		||||
# have a dedicated 'todo' target to rebuild it from a proper
 | 
			
		||||
# config file, all other users are able to build it locally.
 | 
			
		||||
# For all other files, since we ship pre-built html in the
 | 
			
		||||
# tarball, we must also ship the sources, even when those
 | 
			
		||||
# sources are themselves generated.
 | 
			
		||||
dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) \
 | 
			
		||||
  todo.html.in \
 | 
			
		||||
  hvsupport.html.in
 | 
			
		||||
dot_html = $(dot_html_in:%.html.in=%.html)
 | 
			
		||||
 | 
			
		||||
kbase_html_in = \
 | 
			
		||||
  $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/kbase/*.html.in))
 | 
			
		||||
kbase_rst = \
 | 
			
		||||
  $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/kbase/*.rst))
 | 
			
		||||
kbase_rst_html_in = \
 | 
			
		||||
  $(kbase_rst:%.rst=%.html.in)
 | 
			
		||||
kbase_html = \
 | 
			
		||||
  $(kbase_html_in:%.html.in=%.html) \
 | 
			
		||||
  $(kbase_rst_html_in:%.html.in=%.html)
 | 
			
		||||
dot_php_in = $(notdir $(wildcard $(srcdir)/*.php.in))
 | 
			
		||||
dot_php_code_in = $(dot_php_in:%.php.in=%.php.code.in)
 | 
			
		||||
dot_php = $(dot_php_in:%.php.in=%.php)
 | 
			
		||||
 | 
			
		||||
kbasedir = $(HTML_DIR)/kbase
 | 
			
		||||
kbase_DATA = $(kbase_html)
 | 
			
		||||
patches = $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/api_extension/*.patch))
 | 
			
		||||
 | 
			
		||||
# Sync with src/util/
 | 
			
		||||
KEYCODES = linux osx atset1 atset2 atset3 xtkbd usb win32 qnum
 | 
			
		||||
KEYNAMES = linux osx win32
 | 
			
		||||
xml = \
 | 
			
		||||
  libvirt-api.xml \
 | 
			
		||||
  libvirt-refs.xml
 | 
			
		||||
 | 
			
		||||
manpages_rst = \
 | 
			
		||||
  manpages/index.rst \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
manpages1_rst = \
 | 
			
		||||
  manpages/virt-pki-validate.rst \
 | 
			
		||||
  manpages/virt-xml-validate.rst \
 | 
			
		||||
  manpages/virt-admin.rst \
 | 
			
		||||
  manpages/virsh.rst \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
manpages7_rst = \
 | 
			
		||||
  $(KEYCODES:%=manpages/virkeycode-%.rst) \
 | 
			
		||||
  $(KEYNAMES:%=manpages/virkeyname-%.rst) \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
manpages8_rst = $(NULL)
 | 
			
		||||
manpages_rst += \
 | 
			
		||||
  $(manpages1_rst) \
 | 
			
		||||
  $(manpages7_rst) \
 | 
			
		||||
  $(manpages8_rst) \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
if WITH_LIBVIRTD
 | 
			
		||||
manpages8_rst += \
 | 
			
		||||
  manpages/libvirtd.rst \
 | 
			
		||||
  manpages/virtlockd.rst \
 | 
			
		||||
  manpages/virtlogd.rst \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
else ! WITH_LIBVIRTD
 | 
			
		||||
manpages_rst += \
 | 
			
		||||
  manpages/libvirtd.rst \
 | 
			
		||||
  manpages/virtlockd.rst \
 | 
			
		||||
  manpages/virtlogd.rst \
 | 
			
		||||
  $(NULL)
 | 
			
		||||
endif ! WITH_LIBVIRTD
 | 
			
		||||
if WITH_HOST_VALIDATE
 | 
			
		||||
  manpages1_rst += manpages/virt-host-validate.rst
 | 
			
		||||
else ! WITH_HOST_VALIDATE
 | 
			
		||||
  manpages_rst += manpages/virt-host-validate.rst
 | 
			
		||||
endif ! WITH_HOST_VALIDATE
 | 
			
		||||
if WITH_LOGIN_SHELL
 | 
			
		||||
  manpages1_rst += manpages/virt-login-shell.rst
 | 
			
		||||
else ! WITH_LOGIN_SHELL
 | 
			
		||||
  manpages_rst += manpages/virt-login-shell.rst
 | 
			
		||||
endif ! WITH_LOGIN_SHELL
 | 
			
		||||
if WITH_SANLOCK
 | 
			
		||||
  manpages8_rst += manpages/virt-sanlock-cleanup.rst
 | 
			
		||||
else ! WITH_SANLOCK
 | 
			
		||||
  manpages_rst += manpages/virt-sanlock-cleanup.rst
 | 
			
		||||
endif ! WITH_SANLOCK
 | 
			
		||||
if WITH_QEMU
 | 
			
		||||
  manpages1_rst += manpages/virt-qemu-run.rst
 | 
			
		||||
else ! WITH_QEMU
 | 
			
		||||
  manpages_rst += manpages/virt-qemu-run.rst
 | 
			
		||||
endif ! WITH_QEMU
 | 
			
		||||
manpages_rst_html_in = \
 | 
			
		||||
  $(manpages_rst:%.rst=%.html.in)
 | 
			
		||||
manpages_html = \
 | 
			
		||||
  $(manpages_rst_html_in:%.html.in=%.html)
 | 
			
		||||
qemu_xml = \
 | 
			
		||||
  libvirt-qemu-api.xml \
 | 
			
		||||
  libvirt-qemu-refs.xml
 | 
			
		||||
 | 
			
		||||
man1_MANS = $(manpages1_rst:%.rst=%.1)
 | 
			
		||||
man7_MANS = $(manpages7_rst:%.rst=%.7)
 | 
			
		||||
man8_MANS = $(manpages8_rst:%.rst=%.8)
 | 
			
		||||
lxc_xml = \
 | 
			
		||||
  libvirt-lxc-api.xml \
 | 
			
		||||
  libvirt-lxc-refs.xml
 | 
			
		||||
 | 
			
		||||
%.1: %.rst
 | 
			
		||||
	$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
 | 
			
		||||
	   grep -v '^\.\. contents::' < $< | \
 | 
			
		||||
	   sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \
 | 
			
		||||
	       -e 's|RUNSTATEDIR|$(runstatedir)|g' | \
 | 
			
		||||
	   $(RST2MAN) --strict > $@ || { rm $@ && exit 1; }
 | 
			
		||||
 | 
			
		||||
%.7: %.rst
 | 
			
		||||
	$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
 | 
			
		||||
	   grep -v '^\.\. contents::' < $< | \
 | 
			
		||||
	   sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \
 | 
			
		||||
	       -e 's|RUNSTATEDIR|$(runstatedir)|g' | \
 | 
			
		||||
	   $(RST2MAN) --strict > $@ || { rm $@ && exit 1; }
 | 
			
		||||
 | 
			
		||||
%.8: %.rst
 | 
			
		||||
	$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
 | 
			
		||||
	   grep -v '^\.\. contents::' < $< | \
 | 
			
		||||
	   sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \
 | 
			
		||||
	       -e 's|RUNSTATEDIR|$(runstatedir)|g' | \
 | 
			
		||||
	   $(RST2MAN) --strict > $@ || { rm $@ && exit 1; }
 | 
			
		||||
 | 
			
		||||
manpages/virkeycode-%.rst: $(top_srcdir)/src/keycodemapdb/data/keymaps.csv \
 | 
			
		||||
		$(top_srcdir)/src/keycodemapdb/tools/keymap-gen Makefile.am
 | 
			
		||||
	$(AM_V_GEN)export NAME=`echo $@ | \
 | 
			
		||||
		sed -e 's,manpages/virkeycode-,,' -e 's,\.rst,,'` && \
 | 
			
		||||
		$(MKDIR_P) manpages/ && \
 | 
			
		||||
		$(RUNUTF8) $(PYTHON) $(top_srcdir)/src/keycodemapdb/tools/keymap-gen \
 | 
			
		||||
		code-docs \
 | 
			
		||||
		--lang rst \
 | 
			
		||||
		--title "virkeycode-$$NAME" \
 | 
			
		||||
		--subtitle "Key code values for $$NAME" \
 | 
			
		||||
		$(top_srcdir)/src/keycodemapdb/data/keymaps.csv $$NAME > $@
 | 
			
		||||
 | 
			
		||||
manpages/virkeyname-%.rst: $(top_srcdir)/src/keycodemapdb/data/keymaps.csv \
 | 
			
		||||
		$(top_srcdir)/src/keycodemapdb/tools/keymap-gen Makefile.am
 | 
			
		||||
	$(AM_V_GEN)export NAME=`echo $@ | \
 | 
			
		||||
		sed -e 's,manpages/virkeyname-,,' -e 's,\.rst,,'` && \
 | 
			
		||||
		$(MKDIR_P) manpages/ && \
 | 
			
		||||
		$(RUNUTF8) $(PYTHON) $(top_srcdir)/src/keycodemapdb/tools/keymap-gen \
 | 
			
		||||
		name-docs \
 | 
			
		||||
		--lang rst \
 | 
			
		||||
		--title "virkeyname-$$NAME" \
 | 
			
		||||
		--subtitle "Key name values for $$NAME" \
 | 
			
		||||
		$(top_srcdir)/src/keycodemapdb/data/keymaps.csv $$NAME > $@
 | 
			
		||||
 | 
			
		||||
manpagesdir = $(HTML_DIR)/manpages
 | 
			
		||||
manpages_DATA = $(manpages_html)
 | 
			
		||||
 | 
			
		||||
# Generate hvsupport.html and news.html first, since they take one extra step.
 | 
			
		||||
dot_html_generated_in = \
 | 
			
		||||
  hvsupport.html.in \
 | 
			
		||||
  news.html.in
 | 
			
		||||
dot_html_in = \
 | 
			
		||||
  $(notdir $(wildcard $(srcdir)/*.html.in))
 | 
			
		||||
dot_rst = \
 | 
			
		||||
  $(notdir $(wildcard $(srcdir)/*.rst))
 | 
			
		||||
dot_rst_html_in = \
 | 
			
		||||
  $(dot_rst:%.rst=%.html)
 | 
			
		||||
dot_html = \
 | 
			
		||||
  $(dot_html_generated_in:%.html.in=%.html) \
 | 
			
		||||
  $(dot_html_in:%.html.in=%.html) \
 | 
			
		||||
  $(dot_rst_html_in:%.html.in=%.html)
 | 
			
		||||
 | 
			
		||||
htmldir = $(HTML_DIR)
 | 
			
		||||
html_DATA = $(css) $(png) $(gif) $(dot_html)
 | 
			
		||||
admin_xml = \
 | 
			
		||||
  libvirt-admin-api.xml \
 | 
			
		||||
  libvirt-admin-refs.xml
 | 
			
		||||
 | 
			
		||||
apidir = $(pkgdatadir)/api
 | 
			
		||||
api_DATA = \
 | 
			
		||||
       libvirt-api.xml \
 | 
			
		||||
       libvirt-qemu-api.xml \
 | 
			
		||||
       libvirt-lxc-api.xml \
 | 
			
		||||
       libvirt-admin-api.xml
 | 
			
		||||
       libvirt-lxc-api.xml
 | 
			
		||||
 | 
			
		||||
fig = \
 | 
			
		||||
  libvirt-net-logical.fig \
 | 
			
		||||
  libvirt-net-physical.fig \
 | 
			
		||||
  libvirt-daemon-arch.fig \
 | 
			
		||||
  libvirt-driver-arch.fig \
 | 
			
		||||
  libvirt-object-model.fig \
 | 
			
		||||
@@ -345,149 +150,158 @@ fig = \
 | 
			
		||||
  migration-tunnel.fig \
 | 
			
		||||
  migration-unmanaged-direct.fig
 | 
			
		||||
 | 
			
		||||
schemadir = $(pkgdatadir)/schemas
 | 
			
		||||
schema_DATA = $(wildcard $(srcdir)/schemas/*.rng)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST= \
 | 
			
		||||
  site.xsl subsite.xsl newapi.xsl page.xsl \
 | 
			
		||||
  wrapstring.xsl \
 | 
			
		||||
  $(dot_html_in) $(dot_rst) $(gif) $(apipng) \
 | 
			
		||||
  $(fig) $(png) $(css) \
 | 
			
		||||
  $(javascript) $(logofiles) \
 | 
			
		||||
  $(internals_html_in) $(internals_rst) $(fonts) \
 | 
			
		||||
  $(kbase_html_in) $(kbase_rst) \
 | 
			
		||||
  $(manpages_rst) \
 | 
			
		||||
  aclperms.htmlinc \
 | 
			
		||||
  $(schema_DATA)
 | 
			
		||||
EXTRA_DIST=					\
 | 
			
		||||
  apibuild.py genaclperms.pl \
 | 
			
		||||
  site.xsl newapi.xsl news.xsl page.xsl \
 | 
			
		||||
  hacking1.xsl hacking2.xsl wrapstring.xsl \
 | 
			
		||||
  $(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
 | 
			
		||||
  $(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
 | 
			
		||||
  $(xml) $(qemu_xml) $(lxc_xml) $(fig) $(png) $(css) \
 | 
			
		||||
  $(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
 | 
			
		||||
  $(internals_html_in) $(internals_html) \
 | 
			
		||||
  sitemap.html.in aclperms.htmlinc \
 | 
			
		||||
  todo.pl hvsupport.pl todo.cfg-example
 | 
			
		||||
 | 
			
		||||
acl_generated = aclperms.htmlinc
 | 
			
		||||
 | 
			
		||||
aclperms.htmlinc: $(top_srcdir)/src/access/viraccessperm.h \
 | 
			
		||||
        $(top_srcdir)/scripts/genaclperms.py Makefile.am
 | 
			
		||||
	$(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/genaclperms.py $< > $@
 | 
			
		||||
$(srcdir)/aclperms.htmlinc: $(top_srcdir)/src/access/viraccessperm.h \
 | 
			
		||||
        $(srcdir)/genaclperms.pl Makefile.am
 | 
			
		||||
	$(AM_V_GEN)$(PERL) $(srcdir)/genaclperms.pl $< > $@
 | 
			
		||||
 | 
			
		||||
CLEANFILES = \
 | 
			
		||||
  $(dot_html) \
 | 
			
		||||
  $(apihtml) \
 | 
			
		||||
  $(apiadminhtml) \
 | 
			
		||||
  $(apiqemuhtml) \
 | 
			
		||||
  $(apilxchtml) \
 | 
			
		||||
  $(internals_html) \
 | 
			
		||||
  $(kbase_html) \
 | 
			
		||||
  $(manpages_html) \
 | 
			
		||||
  $(man1_MANS) \
 | 
			
		||||
  $(man7_MANS) \
 | 
			
		||||
  $(manpages7_rst) \
 | 
			
		||||
  $(man8_MANS) \
 | 
			
		||||
  $(api_DATA) \
 | 
			
		||||
  $(dot_html_generated_in) \
 | 
			
		||||
  aclperms.htmlinc
 | 
			
		||||
MAINTAINERCLEANFILES = \
 | 
			
		||||
  $(addprefix $(srcdir)/,$(dot_html)) \
 | 
			
		||||
  $(addprefix $(srcdir)/,$(apihtml)) \
 | 
			
		||||
  $(addprefix $(srcdir)/,$(devhelphtml)) \
 | 
			
		||||
  $(addprefix $(srcdir)/,$(internals_html)) \
 | 
			
		||||
  $(addprefix $(srcdir)/,$(dot_php)) \
 | 
			
		||||
  $(srcdir)/hvsupport.html.in $(srcdir)/aclperms.htmlinc
 | 
			
		||||
 | 
			
		||||
timestamp="$(shell if test -n "$$SOURCE_DATE_EPOCH"; \
 | 
			
		||||
		   then \
 | 
			
		||||
		     date -u --date="@$$SOURCE_DATE_EPOCH"; \
 | 
			
		||||
		   else \
 | 
			
		||||
		     date -u; \
 | 
			
		||||
		   fi)"
 | 
			
		||||
all-am: web
 | 
			
		||||
 | 
			
		||||
hvsupport.html: hvsupport.html.in
 | 
			
		||||
api: $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
 | 
			
		||||
qemu_api: $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
 | 
			
		||||
lxc_api: $(srcdir)/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-refs.xml
 | 
			
		||||
admin_api: $(srcdir)/libvirt-admin-api.xml $(srcdir)/libvirt-admin-refs.xml
 | 
			
		||||
 | 
			
		||||
hvsupport.html.in: $(top_srcdir)/scripts/hvsupport.py $(api_DATA) \
 | 
			
		||||
web: $(dot_html) $(internals_html) html/index.html devhelp/index.html \
 | 
			
		||||
  $(dot_php)
 | 
			
		||||
 | 
			
		||||
todo.html.in: todo.pl
 | 
			
		||||
	if [ -f  todo.cfg ]; then \
 | 
			
		||||
		echo "Generating $@"; \
 | 
			
		||||
		$(PERL) $< > $@ \
 | 
			
		||||
		|| { rm $@ && exit 1; }; \
 | 
			
		||||
	else \
 | 
			
		||||
		echo "Stubbing $@"; \
 | 
			
		||||
		printf "%s\n" \
 | 
			
		||||
		  "<html xmlns=\"http://www.w3.org/1999/xhtml\">" \
 | 
			
		||||
		  "<body>" \
 | 
			
		||||
		  "<h1>Todo list unavailable: no config file</h1>" \
 | 
			
		||||
		  "</body></html>" > $@ ; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
todo:
 | 
			
		||||
	rm -f todo.html.in
 | 
			
		||||
	$(MAKE) todo.html
 | 
			
		||||
 | 
			
		||||
hvsupport.html:: $(srcdir)/hvsupport.html.in
 | 
			
		||||
 | 
			
		||||
$(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
 | 
			
		||||
		$(top_srcdir)/src/libvirt_public.syms \
 | 
			
		||||
	$(top_srcdir)/src/libvirt_qemu.syms $(top_srcdir)/src/libvirt_lxc.syms \
 | 
			
		||||
	$(top_srcdir)/src/driver.h
 | 
			
		||||
	$(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/hvsupport.py \
 | 
			
		||||
		$(top_srcdir) $(top_builddir) > $@ || { rm $@ && exit 1; }
 | 
			
		||||
	$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(top_srcdir)/src > $@ \
 | 
			
		||||
		|| { rm $@ && exit 1; }
 | 
			
		||||
 | 
			
		||||
news.html.in: \
 | 
			
		||||
	  $(srcdir)/news.xml \
 | 
			
		||||
	  $(srcdir)/news-html.xsl
 | 
			
		||||
	$(AM_V_GEN)$(XSLTPROC) --nonet \
 | 
			
		||||
	    $(srcdir)/news-html.xsl \
 | 
			
		||||
	    $(srcdir)/news.xml \
 | 
			
		||||
	  >$@ \
 | 
			
		||||
	    || { rm -f $@; exit 1; };
 | 
			
		||||
EXTRA_DIST += \
 | 
			
		||||
	$(srcdir)/news.xml \
 | 
			
		||||
	$(srcdir)/news.rng \
 | 
			
		||||
	$(srcdir)/news-html.xsl
 | 
			
		||||
.PHONY: todo
 | 
			
		||||
 | 
			
		||||
%.png: %.fig
 | 
			
		||||
	convert -rotate 90 $< $@
 | 
			
		||||
 | 
			
		||||
manpages/%.html.in: manpages/%.rst
 | 
			
		||||
	$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
 | 
			
		||||
	 grep -v '^:Manual ' < $< | \
 | 
			
		||||
	  sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \
 | 
			
		||||
	     -e 's|RUNSTATEDIR|$(runstatedir)|g' | \
 | 
			
		||||
	  $(RST2HTML) --strict > $@ || { rm $@ && exit 1; }
 | 
			
		||||
internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
 | 
			
		||||
	@if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	  echo "Generating $@"; \
 | 
			
		||||
	  $(MKDIR_P) internals; \
 | 
			
		||||
	  name=`echo $@ | sed -e 's/.tmp//'`; \
 | 
			
		||||
	  $(XSLTPROC) --stringparam pagename $$name --nonet \
 | 
			
		||||
	    $(top_srcdir)/docs/subsite.xsl $< > $@ \
 | 
			
		||||
	    || { rm $@ && exit 1; }; fi
 | 
			
		||||
 | 
			
		||||
%.html.in: %.rst
 | 
			
		||||
	$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
 | 
			
		||||
	  $(RST2HTML) --strict $< > $@ || { rm $@ && exit 1; }
 | 
			
		||||
 | 
			
		||||
%.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \
 | 
			
		||||
		$(acl_generated)
 | 
			
		||||
	$(AM_V_GEN)name=`echo $@ | sed -e 's/.tmp//'`; \
 | 
			
		||||
	  dir=`dirname $@` ; \
 | 
			
		||||
	  if test "$$dir" = "."; \
 | 
			
		||||
	  then \
 | 
			
		||||
	    style=site.xsl; \
 | 
			
		||||
	  else \
 | 
			
		||||
	    $(MKDIR_P) $$dir; \
 | 
			
		||||
	    style=subsite.xsl; \
 | 
			
		||||
	  fi; \
 | 
			
		||||
	  $(XSLTPROC) --stringparam pagename $$name \
 | 
			
		||||
	    --stringparam builddir '$(abs_top_builddir)' \
 | 
			
		||||
	    --stringparam timestamp $(timestamp) --nonet \
 | 
			
		||||
	    $(top_srcdir)/docs/$$style $< > $@ \
 | 
			
		||||
	    || { rm $@ && exit 1; }
 | 
			
		||||
%.html.tmp: %.html.in site.xsl page.xsl sitemap.html.in $(acl_generated)
 | 
			
		||||
	@if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	  echo "Generating $@"; \
 | 
			
		||||
	  name=`echo $@ | sed -e 's/.tmp//'`; \
 | 
			
		||||
	  $(XSLTPROC) --stringparam pagename $$name --nonet \
 | 
			
		||||
	    $(top_srcdir)/docs/site.xsl $< > $@ \
 | 
			
		||||
	    || { rm $@ && exit 1; }; fi
 | 
			
		||||
 | 
			
		||||
%.html: %.html.tmp
 | 
			
		||||
	$(AM_V_GEN)$(XMLLINT) --nonet --format $< > $@ \
 | 
			
		||||
	  || { rm $@ && exit 1; }
 | 
			
		||||
	@if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
 | 
			
		||||
	  if $(XMLCATALOG) '$(XML_CATALOG_FILE)' \
 | 
			
		||||
	    "-//W3C//DTD XHTML 1.0 Strict//EN" > /dev/null ; then \
 | 
			
		||||
	  echo "Validating $@" ; \
 | 
			
		||||
	  SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
 | 
			
		||||
	  $(XMLLINT) --catalogs --nonet --format --valid $< > $(srcdir)/$@ \
 | 
			
		||||
	  || { rm $(srcdir)/$@ && exit 1; }; \
 | 
			
		||||
	  else echo "missing XHTML1 DTD"; cat $< > $(srcdir)/$@ ; fi ; fi
 | 
			
		||||
 | 
			
		||||
%.php.tmp: %.php.in site.xsl page.xsl sitemap.html.in
 | 
			
		||||
	@if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	  echo "Generating $@"; \
 | 
			
		||||
	  $(XSLTPROC) --stringparam pagename $(@:.tmp=) --nonet \
 | 
			
		||||
	    $(top_srcdir)/docs/site.xsl $< > $@ \
 | 
			
		||||
	    || { rm $@ && exit 1; }; fi
 | 
			
		||||
 | 
			
		||||
%.php: %.php.tmp %.php.code.in
 | 
			
		||||
	@if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	  echo "Scripting $@"; \
 | 
			
		||||
	    sed -e '/<span id="php_placeholder"><\/span>/r '"$(srcdir)/$@.code.in" \
 | 
			
		||||
	    -e /php_placeholder/d < $@.tmp > $(srcdir)/$@ \
 | 
			
		||||
	    || { rm $(srcdir)/$@ && exit 1; }; fi
 | 
			
		||||
 | 
			
		||||
$(apihtml_generated): html/index.html
 | 
			
		||||
$(apiadminhtml_generated): html/index-admin.html
 | 
			
		||||
$(apiqemuhtml_generated): html/index-qemu.html
 | 
			
		||||
$(apilxchtml_generated): html/index-lxc.html
 | 
			
		||||
 | 
			
		||||
html/index.html: libvirt-api.xml newapi.xsl page.xsl $(APIBUILD_STAMP)
 | 
			
		||||
	$(AM_V_GEN)$(XSLTPROC) --nonet -o ./ \
 | 
			
		||||
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
 | 
			
		||||
	$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	  $(XSLTPROC) --nonet -o $(srcdir)/ \
 | 
			
		||||
	  --stringparam builddir '$(abs_top_builddir)' \
 | 
			
		||||
	  --stringparam timestamp $(timestamp) \
 | 
			
		||||
	  $(srcdir)/newapi.xsl libvirt-api.xml
 | 
			
		||||
	  $(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi && \
 | 
			
		||||
	if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
 | 
			
		||||
	  if $(XMLCATALOG) '$(XML_CATALOG_FILE)' "-//W3C//DTD XHTML 1.0 Strict//EN" \
 | 
			
		||||
	    > /dev/null ; then \
 | 
			
		||||
	  SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
 | 
			
		||||
	  $(XMLLINT) --catalogs --nonet --valid --noout $(srcdir)/html/*.html ; \
 | 
			
		||||
	  else echo "missing XHTML1 DTD"; cat $< > $(srcdir)/$@ ; fi ; fi
 | 
			
		||||
 | 
			
		||||
html/index-%.html: libvirt-%-api.xml newapi.xsl page.xsl $(APIBUILD_STAMP)
 | 
			
		||||
	$(AM_V_GEN)$(XSLTPROC) --nonet -o ./ \
 | 
			
		||||
	  --stringparam builddir '$(abs_top_builddir)' \
 | 
			
		||||
	  --stringparam timestamp $(timestamp) \
 | 
			
		||||
	  --stringparam indexfile $(@:html/%=%) \
 | 
			
		||||
	  $(srcdir)/newapi.xsl $<
 | 
			
		||||
$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
 | 
			
		||||
	$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
 | 
			
		||||
	  $(XSLTPROC) --nonet -o $(srcdir)/devhelp/ \
 | 
			
		||||
	  $(top_srcdir)/docs/devhelp/devhelp.xsl $(srcdir)/libvirt-api.xml ; fi
 | 
			
		||||
 | 
			
		||||
check-html:
 | 
			
		||||
	$(XMLLINT) --nonet --noout html/*.html
 | 
			
		||||
 | 
			
		||||
check-local: check-html
 | 
			
		||||
 | 
			
		||||
python_generated_files = \
 | 
			
		||||
		html/libvirt-libvirt-lxc.html \
 | 
			
		||||
		html/libvirt-libvirt-qemu.html \
 | 
			
		||||
		html/libvirt-libvirt-admin.html \
 | 
			
		||||
		html/libvirt-virterror.html \
 | 
			
		||||
		$(api_DATA) \
 | 
			
		||||
		$(srcdir)/html/libvirt-libvirt-lxc.html \
 | 
			
		||||
		$(srcdir)/html/libvirt-libvirt-qemu.html \
 | 
			
		||||
		$(srcdir)/html/libvirt-libvirt-admin.html \
 | 
			
		||||
		$(srcdir)/html/libvirt-virterror.html \
 | 
			
		||||
		$(srcdir)/libvirt-api.xml \
 | 
			
		||||
		$(srcdir)/libvirt-refs.xml \
 | 
			
		||||
		$(srcdir)/libvirt-lxc-api.xml \
 | 
			
		||||
		$(srcdir)/libvirt-lxc-refs.xml \
 | 
			
		||||
		$(srcdir)/libvirt-qemu-api.xml \
 | 
			
		||||
		$(srcdir)/libvirt-qemu-refs.xml \
 | 
			
		||||
		$(srcdir)/libvirt-admin-api.xml \
 | 
			
		||||
		$(srcdir)/libvirt-admin-refs.xml \
 | 
			
		||||
		$(NULL)
 | 
			
		||||
 | 
			
		||||
APIBUILD=$(top_srcdir)/scripts/apibuild.py
 | 
			
		||||
APIBUILD_STAMP=apibuild.py.stamp
 | 
			
		||||
CLEANFILES += $(APIBUILD_STAMP)
 | 
			
		||||
APIBUILD=$(srcdir)/apibuild.py
 | 
			
		||||
APIBUILD_STAMP=$(APIBUILD).stamp
 | 
			
		||||
EXTRA_DIST += $(APIBUILD_STAMP)
 | 
			
		||||
 | 
			
		||||
$(python_generated_files): $(APIBUILD_STAMP)
 | 
			
		||||
 | 
			
		||||
$(APIBUILD_STAMP): $(top_srcdir)/scripts/apibuild.py \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt.h \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt-common.h.in \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt-domain-checkpoint.h \
 | 
			
		||||
$(APIBUILD_STAMP): $(srcdir)/apibuild.py \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt.h.in \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt-domain-snapshot.h \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt-domain.h \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt-event.h \
 | 
			
		||||
@@ -504,23 +318,53 @@ $(APIBUILD_STAMP): $(top_srcdir)/scripts/apibuild.py \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/libvirt-admin.h \
 | 
			
		||||
		$(top_srcdir)/include/libvirt/virterror.h \
 | 
			
		||||
		$(top_srcdir)/src/libvirt.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-domain-checkpoint.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-domain-snapshot.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-domain.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-host.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-interface.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-network.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-nodedev.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-nwfilter.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-secret.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-storage.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-stream.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-lxc.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-qemu.c \
 | 
			
		||||
		$(top_srcdir)/src/admin/libvirt-admin.c \
 | 
			
		||||
		$(top_srcdir)/src/libvirt-admin.c \
 | 
			
		||||
		$(top_srcdir)/src/util/virerror.c \
 | 
			
		||||
		$(top_srcdir)/src/util/virevent.c \
 | 
			
		||||
		$(top_srcdir)/src/util/virtypedparam-public.c
 | 
			
		||||
	$(AM_V_GEN)srcdir=$(srcdir) builddir=$(builddir) \
 | 
			
		||||
		$(RUNUTF8) $(PYTHON) $(APIBUILD)
 | 
			
		||||
		$(top_srcdir)/src/util/virtypedparam.c
 | 
			
		||||
	$(AM_V_GEN)srcdir=$(srcdir) $(PYTHON) $(APIBUILD)
 | 
			
		||||
	touch $@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
check-local: all
 | 
			
		||||
dist-local: all
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
	rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local: clean-local
 | 
			
		||||
	rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml \
 | 
			
		||||
		todo.html.in
 | 
			
		||||
	rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
 | 
			
		||||
	rm -rf $(srcdir)/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-refs.xml
 | 
			
		||||
	rm -rf $(srcdir)/libvirt-admin-api.xml $(srcdir)/libvirt-admin-refs.xml
 | 
			
		||||
	rm -rf $(APIBUILD_STAMP)
 | 
			
		||||
 | 
			
		||||
rebuild: api qemu_api lxc_api admin_api all
 | 
			
		||||
 | 
			
		||||
install-data-local:
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
 | 
			
		||||
	for f in $(css) $(dot_html) $(gif) $(png); do \
 | 
			
		||||
	  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR); done
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/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)$(HTML_DIR)/internals
 | 
			
		||||
	for f in $(internals_html); do \
 | 
			
		||||
	  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR)/internals; done
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(DEVHELP_DIR)
 | 
			
		||||
	for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
 | 
			
		||||
	    $(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
 | 
			
		||||
	done
 | 
			
		||||
	$(INSTALL_DATA) $(srcdir)/libvirtLogo.png $(DESTDIR)$(pkgdatadir)
 | 
			
		||||
 | 
			
		||||
uninstall-local:
 | 
			
		||||
	for 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)/$$(basename $$f); \
 | 
			
		||||
	done
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>Client access control</h1>
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
    <ul id="toc"></ul>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="intro">Access control introduction</a></h2>
 | 
			
		||||
    <h2><a name="intro">Access control introduction</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      In a default configuration, the libvirtd daemon has three levels
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
      <code>getattr</code> permission.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="drivers">Access control drivers</a></h2>
 | 
			
		||||
    <h2><a name="drivers">Access control drivers</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      The access control framework is designed as a pluggable
 | 
			
		||||
@@ -83,7 +83,7 @@
 | 
			
		||||
      the libvirtd daemon be restarted.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="perms">Objects and permissions</a></h2>
 | 
			
		||||
    <h2><a name="perms">Objects and permissions</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Libvirt applies access control to all the main object
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>Polkit access control</h1>
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
    <ul id="toc"></ul>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="intro">Introduction</a></h2>
 | 
			
		||||
    <h2><a name="intro">Introduction</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      A default install of libvirt will typically use
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
      object.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="perms">Permission names</a></h2>
 | 
			
		||||
    <h2><a name="perms">Permission names</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      The libvirt <a href="acl.html#perms">object names and permission names</a>
 | 
			
		||||
@@ -53,7 +53,7 @@
 | 
			
		||||
      permissions default to deny access.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="attrs">Object identity attributes</a></h2>
 | 
			
		||||
    <h2><a name="attrs">Object identity attributes</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      To allow polkit authorization rules to be written to match
 | 
			
		||||
@@ -63,8 +63,8 @@
 | 
			
		||||
      of object being checked
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_connect">virConnectPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_connect">virConnectPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -79,8 +79,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_domain">virDomainPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_domain">virDomainPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -103,8 +103,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_interface">virInterfacePtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_interface">virInterfacePtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -127,8 +127,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_network">virNetworkPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_network">virNetworkPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -151,8 +151,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_node_device">virNodeDevicePtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_node_device">virNodeDevicePtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -171,8 +171,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_nwfilter">virNWFilterPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_nwfilter">virNWFilterPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -195,8 +195,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_secret">virSecretPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_secret">virSecretPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -224,15 +224,11 @@
 | 
			
		||||
          <td>secret_usage_target</td>
 | 
			
		||||
          <td>Name of the associated iSCSI target, if any</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>secret_usage_name</td>
 | 
			
		||||
          <td>Name of the associated TLS secret, if any</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_storage_pool">virStoragePoolPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_storage_pool">virStoragePoolPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -255,8 +251,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_storage_vol">virStorageVolPtr</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
    <h3><a name="object_storage_vol">virStorageVolPtr</a></h3>
 | 
			
		||||
    <table class="acl">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Attribute</th>
 | 
			
		||||
@@ -287,113 +283,8 @@
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="connect_driver">Hypervisor Driver connect_driver</a></h2>
 | 
			
		||||
    <p>
 | 
			
		||||
      The <code>connect_driver</code> parameter describes the
 | 
			
		||||
      client's <a href="remote.html">remote Connection Driver</a>
 | 
			
		||||
      name based on the <a href="uri.html">URI</a> used for the
 | 
			
		||||
      connection.
 | 
			
		||||
    </p>
 | 
			
		||||
    <p>
 | 
			
		||||
      <span class="since">Since 4.1.0</span>, when calling an API
 | 
			
		||||
      outside the scope of the primary connection driver, the
 | 
			
		||||
      primary driver will attempt to open a secondary connection
 | 
			
		||||
      to the specific API driver in order to process the API. For
 | 
			
		||||
      example, when hypervisor domain processing needs to make an
 | 
			
		||||
      API call within the storage driver or the network filter driver
 | 
			
		||||
      an attempt to open a connection to the "storage" or "nwfilter"
 | 
			
		||||
      driver will be made. Similarly, a "storage" primary connection
 | 
			
		||||
      may need to create a connection to the "secret" driver in order
 | 
			
		||||
      to process secrets for the API. If successful, then calls to
 | 
			
		||||
      those API's will occur in the <code>connect_driver</code> context
 | 
			
		||||
      of the secondary connection driver rather than in the context of
 | 
			
		||||
      the primary driver. This affects the <code>connect_driver</code>
 | 
			
		||||
      returned from rule generation from the <code>action.loookup</code>
 | 
			
		||||
      function. The following table provides a list of the various
 | 
			
		||||
      connection drivers and the <code>connect_driver</code> name
 | 
			
		||||
      used by each regardless of primary or secondary connection.
 | 
			
		||||
      The access denied error message from libvirt will list the
 | 
			
		||||
      connection driver by name that denied the access.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="object_connect_driver">Connection Driver Name</a></h3>
 | 
			
		||||
    <table>
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <th>Connection Driver</th>
 | 
			
		||||
          <th><code>connect_driver</code> name</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
      <tbody>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>bhyve</td>
 | 
			
		||||
          <td>bhyve</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>esx</td>
 | 
			
		||||
          <td>ESX</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>hyperv</td>
 | 
			
		||||
          <td>Hyper-V</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>interface</td>
 | 
			
		||||
          <td>interface</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>libxl</td>
 | 
			
		||||
          <td>xenlight</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>lxc</td>
 | 
			
		||||
          <td>LXC</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>network</td>
 | 
			
		||||
          <td>network</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>nodedev</td>
 | 
			
		||||
          <td>nodedev</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>nwfilter</td>
 | 
			
		||||
          <td>NWFilter</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>openvz</td>
 | 
			
		||||
          <td>OPENVZ</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>qemu</td>
 | 
			
		||||
          <td>QEMU</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>secret</td>
 | 
			
		||||
          <td>secret</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>storage</td>
 | 
			
		||||
          <td>storage</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>vbox</td>
 | 
			
		||||
          <td>VBOX</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>vmware</td>
 | 
			
		||||
          <td>VMWARE</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td>vz</td>
 | 
			
		||||
          <td>vz</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <h2><a id="user">User identity attributes</a></h2>
 | 
			
		||||
    <h2><a name="user">User identity attributes</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      At this point in time, the only attribute provided by
 | 
			
		||||
@@ -412,7 +303,7 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <h2><a id="checks">Writing access control policies</a></h2>
 | 
			
		||||
    <h2><a name="checks">Writing access control policies</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      If using versions of polkit prior to 0.106 then it is only
 | 
			
		||||
@@ -439,9 +330,9 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <pre>
 | 
			
		||||
polkit.addRule(function(action, subject) {
 | 
			
		||||
  ....logic to check 'action' and 'subject'...
 | 
			
		||||
});
 | 
			
		||||
      polkit.addRule(function(action, subject) {
 | 
			
		||||
        ....logic to check 'action' and 'subject'...
 | 
			
		||||
      });
 | 
			
		||||
    </pre>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
@@ -457,13 +348,7 @@ polkit.addRule(function(action, subject) {
 | 
			
		||||
      <code>lookup</code> method.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
    See
 | 
			
		||||
    <a href="https://libvirt.org/git/?p=libvirt.git;a=tree;f=examples/polkit;hb=HEAD">source code</a>
 | 
			
		||||
    for a more complex example.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="exconnect">Example: restricting ability to connect to drivers</a></h3>
 | 
			
		||||
    <h3><a name="exconnect">Example: restricting ability to connect to drivers</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Consider a local user <code>berrange</code>
 | 
			
		||||
@@ -491,7 +376,7 @@ polkit.addRule(function(action, subject) {
 | 
			
		||||
});
 | 
			
		||||
    </pre>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="exdomain">Example: restricting access to a single domain</a></h3>
 | 
			
		||||
    <h3><a name="exdomain">Example: restricting access to a single domain</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Consider a local user <code>berrange</code>
 | 
			
		||||
@@ -501,7 +386,7 @@ polkit.addRule(function(action, subject) {
 | 
			
		||||
      To achieve this we need to write a rule which checks
 | 
			
		||||
      whether the <code>connect_driver</code> attribute
 | 
			
		||||
      is <code>LXC</code> and the <code>domain_name</code>
 | 
			
		||||
      attribute is <code>demo</code>, and match on an action
 | 
			
		||||
      attribute is <code>demo</code>, and match on a action
 | 
			
		||||
      name of <code>org.libvirt.api.domain.getattr</code>. Using
 | 
			
		||||
      the javascript rules format, this ends up written as
 | 
			
		||||
    </p>
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 13 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 16 KiB  | 
@@ -1,5 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>The libvirt API concepts</h1>
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 | 
			
		||||
    <ul id="toc"></ul>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="Objects">Objects Exposed</a></h2>
 | 
			
		||||
    <h2><a name="Objects">Objects Exposed</a></h2>
 | 
			
		||||
    <p> As defined in the <a href="goals.html">goals section</a>, the libvirt
 | 
			
		||||
    API is designed to expose all the resources needed to manage the
 | 
			
		||||
    virtualization support of recent operating systems. The first object
 | 
			
		||||
@@ -121,7 +121,7 @@
 | 
			
		||||
      set of nodes.</p></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="Functions">Functions and Naming Conventions</a></h2>
 | 
			
		||||
    <h2><a name="Functions">Functions and Naming Conventions</a></h2>
 | 
			
		||||
    <p> The naming of the functions present in the library is usually
 | 
			
		||||
      composed by a prefix describing the object associated to the function
 | 
			
		||||
      and a verb describing the action on that object.</p>
 | 
			
		||||
@@ -155,7 +155,7 @@
 | 
			
		||||
          </ul>
 | 
			
		||||
      </li>
 | 
			
		||||
      <li><b>Enumeration</b> [virConnectList..., virConnectNumOf...]
 | 
			
		||||
      <p>Used to enumerate a set of object available to a given
 | 
			
		||||
      <p>Used to enumerate a set of object available to an given
 | 
			
		||||
      hypervisor connection such as:</p>
 | 
			
		||||
          <ul>
 | 
			
		||||
            <li>
 | 
			
		||||
@@ -297,7 +297,7 @@
 | 
			
		||||
    <p> For more in-depth details of the storage related APIs see
 | 
			
		||||
      <a href="storage.html">the storage management page</a>.
 | 
			
		||||
    </p>
 | 
			
		||||
    <h2><a id="Drivers">The libvirt Drivers</a></h2>
 | 
			
		||||
    <h2><a name="Drivers">The libvirt Drivers</a></h2>
 | 
			
		||||
    <p>Drivers are the basic building block for libvirt functionality
 | 
			
		||||
    to support the capability to handle specific hypervisor driver calls.
 | 
			
		||||
    Drivers are discovered and registered during connection processing as
 | 
			
		||||
@@ -325,12 +325,12 @@
 | 
			
		||||
    the various functions and support found in each driver by the version
 | 
			
		||||
    support was added into libvirt.
 | 
			
		||||
    </p>
 | 
			
		||||
    <h2><a id="Remote">Daemon and Remote Access</a></h2>
 | 
			
		||||
    <h2><a name="Remote">Daemon and Remote Access</a></h2>
 | 
			
		||||
    <p>Access to libvirt drivers is primarily handled by the libvirtd
 | 
			
		||||
    daemon through the <a href="remote.html">remote</a> driver via an
 | 
			
		||||
    <a href="internals/rpc.html">RPC</a>. Some hypervisors do support
 | 
			
		||||
    client-side connections and responses, such as Test, OpenVZ, VMware,
 | 
			
		||||
    VirtualBox (vbox), ESX, Hyper-V, Xen, and Virtuozzo.
 | 
			
		||||
    Power VM (phyp), VirtualBox (vbox), ESX, Hyper-V, Xen, and Parallels.
 | 
			
		||||
    The libvirtd daemon service is started on the host at system boot
 | 
			
		||||
    time and can also be restarted at any time by a properly privileged
 | 
			
		||||
    user, such as root. The libvirtd daemon uses the same libvirt API
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>Implementing a new API in Libvirt</h1>
 | 
			
		||||
@@ -8,9 +8,14 @@
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      This document walks you through the process of implementing a new
 | 
			
		||||
      API in libvirt.  Remember that new API consists of any new public
 | 
			
		||||
      functions, as well as the addition of flags or extensions of XML used by
 | 
			
		||||
      existing functions.
 | 
			
		||||
      API in libvirt.  It uses as an example the addition of an API for
 | 
			
		||||
      separating maximum from current vcpu usage of a domain, over
 | 
			
		||||
      the course of a fifteen-patch series.
 | 
			
		||||
      Remember that new API consists of any new public functions, as
 | 
			
		||||
      well as the addition of flags or extensions of XML used by
 | 
			
		||||
      existing functions.  The example in this document adds both new
 | 
			
		||||
      functions and an XML extension.  Not all libvirt API additions
 | 
			
		||||
      require quite as many patches.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
@@ -22,7 +27,12 @@
 | 
			
		||||
      added to libvirt.  Someone may already be working on the feature you
 | 
			
		||||
      want.  Also, recognize that everything you write is likely to undergo
 | 
			
		||||
      significant rework as you discuss it with the other developers, so
 | 
			
		||||
      don't wait too long before getting feedback.
 | 
			
		||||
      don't wait too long before getting feedback.  In the vcpu example
 | 
			
		||||
      below, list feedback was first requested
 | 
			
		||||
      <a href="https://www.redhat.com/archives/libvir-list/2010-September/msg00423.html">here</a>
 | 
			
		||||
      and resulted in several rounds of improvements before coding
 | 
			
		||||
      began.  In turn, this example is slightly rearranged from the actual
 | 
			
		||||
      order of the commits.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
@@ -34,7 +44,7 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      <a href="https://libvirt.org/downloads.html">https://libvirt.org/downloads.html</a>
 | 
			
		||||
      <a href="http://libvirt.org/downloads.html">http://libvirt.org/downloads.html</a>
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
@@ -71,12 +81,14 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Submit new code in the form of one patch per step.  That's not to say
 | 
			
		||||
      submit patches before you have working functionality--get the whole thing
 | 
			
		||||
      working and make sure you're happy with it.  Then use git to break the
 | 
			
		||||
      changes into pieces so you don't drop a big blob of code on the
 | 
			
		||||
      mailing list in one go.  Also, you should follow the upstream tree, and
 | 
			
		||||
      rebase your series to adapt your patches to work with any other changes
 | 
			
		||||
      Submit new code in the form shown in the example code: one patch
 | 
			
		||||
      per step.  That's not to say submit patches before you have working
 | 
			
		||||
      functionality--get the whole thing working and make sure you're happy
 | 
			
		||||
      with it.  Then use git or some other version control system that lets
 | 
			
		||||
      you rewrite your commit history and break patches into pieces so you
 | 
			
		||||
      don't drop a big blob of code on the mailing list in one go.
 | 
			
		||||
      Also, you should follow the upstream tree, and rebase your
 | 
			
		||||
      series to adapt your patches to work with any other changes
 | 
			
		||||
      that were accepted upstream during your development.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
@@ -89,14 +101,16 @@
 | 
			
		||||
      separately.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id='publicapi'>Defining the public API</a></h2>
 | 
			
		||||
    <p>With that said, let's begin.</p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name='publicapi'>Defining the public API</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>The first task is to define the public API.  If the new API
 | 
			
		||||
      involves an XML extension, you have to enhance the RelaxNG
 | 
			
		||||
      schema and document the new elements or attributes:</p>
 | 
			
		||||
 | 
			
		||||
    <p><code>
 | 
			
		||||
        docs/schemas/domaincommon.rng<br/>
 | 
			
		||||
        docs/schemas/domain.rng<br/>
 | 
			
		||||
        docs/formatdomain.html.in
 | 
			
		||||
    </code></p>
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +120,7 @@
 | 
			
		||||
      libvirt library and call the new function:</p>
 | 
			
		||||
 | 
			
		||||
    <p><code>
 | 
			
		||||
        include/libvirt/libvirt-$MODULE.h.in
 | 
			
		||||
        include/libvirt/libvirt.h.in
 | 
			
		||||
        src/libvirt_public.syms
 | 
			
		||||
    </code></p>
 | 
			
		||||
 | 
			
		||||
@@ -119,7 +133,11 @@
 | 
			
		||||
      rework it as you go through the process of implementing it.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id='internalapi'>Defining the internal API</a></h2>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0001-add-to-xml.patch">0001-add-to-xml.patch</a>
 | 
			
		||||
    and <a href="api_extension/0002-add-new-public-API.patch">0002-add-new-public-API.patch</a>
 | 
			
		||||
    for example code.</p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name='internalapi'>Defining the internal API</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Each public API call is associated with a driver, such as a host
 | 
			
		||||
@@ -137,7 +155,7 @@
 | 
			
		||||
 | 
			
		||||
    <p>The driver structs are defined in:</p>
 | 
			
		||||
 | 
			
		||||
    <p><code>src/driver-$MODULE.h</code></p>
 | 
			
		||||
    <p><code>src/driver.h</code></p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      To define the internal API, first typedef the driver function
 | 
			
		||||
@@ -146,7 +164,9 @@
 | 
			
		||||
      provide a <code>NULL</code> stub for the new function.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id='implpublic'>Implementing the public API</a></h2>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0003-define-internal-driver-API.patch">0003-define-internal-driver-API.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name='implpublic'>Implementing the public API</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Implementing the public API is largely a formality in which we wire up
 | 
			
		||||
@@ -177,17 +197,23 @@
 | 
			
		||||
 | 
			
		||||
    <p>The public API calls are implemented in:</p>
 | 
			
		||||
 | 
			
		||||
    <p><code>src/libvirt-$MODULE.c</code></p>
 | 
			
		||||
    <p><code>src/libvirt.c</code></p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id='remoteproto'>Implementing the remote protocol</a></h2>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0004-implement-the-public-APIs.patch">0004-implement-the-public-APIs.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name='remoteproto'>Implementing the remote protocol</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Implementing the remote protocol is essentially a
 | 
			
		||||
      straightforward exercise which is probably most easily
 | 
			
		||||
      understood by referring to the existing code.
 | 
			
		||||
      understood by referring to the existing code and the example
 | 
			
		||||
      patch.  It involves several related changes, including the
 | 
			
		||||
      regeneration of derived files, with further details below.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id='wireproto'>Defining the wire protocol format</a></h3>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch">0005-implement-the-remote-protocol.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <h3><a name='wireproto'>Defining the wire protocol format</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Defining the wire protocol involves making additions to:
 | 
			
		||||
@@ -219,21 +245,21 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><code>
 | 
			
		||||
        src/remote/remote_daemon_dispatch_stubs.h
 | 
			
		||||
        src/remote/remote_daemon_dispatch.h
 | 
			
		||||
        src/remote/remote_daemon_dispatch.c
 | 
			
		||||
        daemon/remote_dispatch_args.h
 | 
			
		||||
        daemon/remote_dispatch_prototypes.h
 | 
			
		||||
        daemon/remote_dispatch_table.h
 | 
			
		||||
        src/remote/remote_protocol.c
 | 
			
		||||
        src/remote/remote_protocol.h
 | 
			
		||||
    </code></p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id='rpcclient'>Implement the RPC client</a></h3>
 | 
			
		||||
    <h3><a name='rpcclient'>Implement the RPC client</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Implementing the RPC client uses the rpcgen generated .h files.
 | 
			
		||||
      The remote method calls go in:
 | 
			
		||||
      Implementing the uses the rpcgen generated .h files.  The remote
 | 
			
		||||
      method calls go in:
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><code>src/remote/remote_driver.c</code></p>
 | 
			
		||||
    <p><code>src/remote/remote_internal.c</code></p>
 | 
			
		||||
 | 
			
		||||
    <p>Each remote method invocation does the following:</p>
 | 
			
		||||
 | 
			
		||||
@@ -247,7 +273,7 @@
 | 
			
		||||
      <li>unlocks the remote driver.</li>
 | 
			
		||||
    </ol>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="serverdispatch">Implement the server side dispatcher</a></h3>
 | 
			
		||||
    <h3><a name="serverdispatch">Implement the server side dispatcher</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Implementing the server side of the remote function call is simply a
 | 
			
		||||
@@ -256,7 +282,7 @@
 | 
			
		||||
      The server side dispatchers are implemented in:
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><code>src/remote/remote_daemon_dispatch.c</code></p>
 | 
			
		||||
    <p><code>daemon/remote.c</code></p>
 | 
			
		||||
 | 
			
		||||
    <p>Again, this step uses the .h files generated by make rpcgen.</p>
 | 
			
		||||
 | 
			
		||||
@@ -272,7 +298,9 @@
 | 
			
		||||
      existing lines probably imply a backwards-incompatible API change.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="internaluseapi">Use the new API internally</a></h2>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0005-implement-the-remote-protocol.patch">0005-implement-the-remote-protocol.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="internaluseapi">Use the new API internally</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Sometimes, a new API serves as a superset of existing API, by
 | 
			
		||||
@@ -284,7 +312,9 @@
 | 
			
		||||
      not necessary if the new API has no relation to existing API.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="virshuseapi">Expose the new API in virsh</a></h2>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0006-make-old-API-trivially-wrap-to-new-API.patch">0006-make-old-API-trivially-wrap-to-new-API.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="virshuseapi">Expose the new API in virsh</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      All new API should be manageable from the virsh command line
 | 
			
		||||
@@ -309,11 +339,13 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p><code>
 | 
			
		||||
        tools/virsh-$MODULE.c<br/>
 | 
			
		||||
        tools/virsh.c<br/>
 | 
			
		||||
        tools/virsh.pod
 | 
			
		||||
    </code></p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="driverimpl">Implement the driver methods</a></h2>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0007-add-virsh-support.patch">0007-add-virsh-support.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
 | 
			
		||||
@@ -324,7 +356,7 @@
 | 
			
		||||
      adding.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="commonimpl">Implement common handling</a></h3>
 | 
			
		||||
    <h3><a name="commonimpl">Implement common handling</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      If the new API is applicable to more than one driver, it may
 | 
			
		||||
@@ -339,7 +371,9 @@
 | 
			
		||||
      the same way as the older API wrappers.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h3><a id="drivercode">Implement driver handling</a></h3>
 | 
			
		||||
    <p class="example">See <a href="api_extension/0008-support-new-xml.patch">0008-support-new-xml.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="drivercode">Implement driver handling</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      The remaining patches should only touch one driver at a time.
 | 
			
		||||
@@ -350,14 +384,41 @@
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      It is always a good idea to patch the test driver in addition to the
 | 
			
		||||
      target driver, to prove that the API can be used for more than one
 | 
			
		||||
      driver.
 | 
			
		||||
      In the example patches, three separate drivers are supported:
 | 
			
		||||
      test, qemu, and xen.  It is always a good idea to patch the test
 | 
			
		||||
      driver in addition to the target driver, to prove that the API
 | 
			
		||||
      can be used for more than one driver.  The example updates the
 | 
			
		||||
      test driver in one patch:
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p class="example">See <a href="api_extension/0009-support-all-flags-in-test-driver.patch">0009-support-all-flags-in-test-driver.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Any cleanups resulting from the changes should be added as separate
 | 
			
		||||
      patches at the end of the series.
 | 
			
		||||
      The qemu changes were easier to split into two phases, one for
 | 
			
		||||
      updating the mapping between the new XML and the hypervisor
 | 
			
		||||
      command line arguments, and one for supporting all possible
 | 
			
		||||
      flags of the new API:
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p class="example">See <a href="api_extension/0010-improve-vcpu-support-in-qemu-command-line.patch">0010-improve-vcpu-support-in-qemu-command-line.patch</a>
 | 
			
		||||
      and <a href="api_extension/0011-complete-vcpu-support-in-qemu-driver.patch">0011-complete-vcpu-support-in-qemu-driver.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      Finally, the example breaks the xen driver changes across four
 | 
			
		||||
      patches.  One maps the XML changes to the hypervisor command,
 | 
			
		||||
      the next two are independently implementing the getter and
 | 
			
		||||
      setter APIs, and the last one provides cleanup of code that was
 | 
			
		||||
      rendered dead by the new API.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p class="example">See <a href="api_extension/0012-improve-vcpu-support-in-xen-command-line.patch">0012-improve-vcpu-support-in-xen-command-line.patch</a>,
 | 
			
		||||
      <a href="api_extension/0013-improve-getting-xen-vcpu-counts.patch">0013-improve-getting-xen-vcpu-counts.patch</a>,
 | 
			
		||||
      <a href="api_extension/0014-improve-setting-xen-vcpu-counts.patch">0014-improve-setting-xen-vcpu-counts.patch</a>,
 | 
			
		||||
      and <a href="api_extension/0015-remove-dead-xen-code.patch">0015-remove-dead-xen-code.patch</a></p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      The exact details of the example code are probably uninteresting
 | 
			
		||||
      unless you're concerned with virtual cpu management.
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										145
									
								
								docs/api_extension/0001-add-to-xml.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								docs/api_extension/0001-add-to-xml.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
From a74f4e44649906dcd82151f7ef837f66d7fa2ab1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Mon, 27 Sep 2010 17:36:06 -0600
 | 
			
		||||
Subject: [PATCH 01/15] vcpu: add current attribute to <vcpu> element
 | 
			
		||||
 | 
			
		||||
Syntax agreed on in
 | 
			
		||||
https://www.redhat.com/archives/libvir-list/2010-September/msg00476.html
 | 
			
		||||
 | 
			
		||||
<domain ...>
 | 
			
		||||
  <vcpu current='x'>y</vcpu>
 | 
			
		||||
...
 | 
			
		||||
 | 
			
		||||
can now be used to specify 1 <= x <= y current vcpus, in relation
 | 
			
		||||
to the boot-time max of y vcpus.  If current is omitted, then
 | 
			
		||||
current and max are assumed to be the same value.
 | 
			
		||||
 | 
			
		||||
* docs/schemas/domain.rng: Add new attribute.
 | 
			
		||||
* docs/formatdomain.html.in: Document it.
 | 
			
		||||
* tests/qemuxml2argvdata/qemuxml2argv-smp.xml: Add to
 | 
			
		||||
domainschematest.
 | 
			
		||||
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml: Likewise.
 | 
			
		||||
---
 | 
			
		||||
 docs/formatdomain.html.in                   |    9 +++++--
 | 
			
		||||
 docs/schemas/domain.rng                     |    5 ++++
 | 
			
		||||
 tests/qemuxml2argvdata/qemuxml2argv-smp.xml |   28 +++++++++++++++++++++++++++
 | 
			
		||||
 tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml  |   22 +++++++++++++++++++++
 | 
			
		||||
 4 files changed, 61 insertions(+), 3 deletions(-)
 | 
			
		||||
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.xml
 | 
			
		||||
 create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
 | 
			
		||||
 | 
			
		||||
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
 | 
			
		||||
index a8a1fac..96de121 100644
 | 
			
		||||
--- a/docs/formatdomain.html.in
 | 
			
		||||
+++ b/docs/formatdomain.html.in
 | 
			
		||||
@@ -200,7 +200,7 @@
 | 
			
		||||
     <swap_hard_limit>2097152</swap_hard_limit>
 | 
			
		||||
     <min_guarantee>65536</min_guarantee>
 | 
			
		||||
   </memtune>
 | 
			
		||||
-  <vcpu cpuset="1-4,^3,6">2</vcpu>
 | 
			
		||||
+  <vcpu cpuset="1-4,^3,6" current="1">2</vcpu>
 | 
			
		||||
   ...</pre>
 | 
			
		||||
 | 
			
		||||
     <dl>
 | 
			
		||||
@@ -238,7 +238,7 @@
 | 
			
		||||
 	minimum memory allocation for the guest. The units for this value are
 | 
			
		||||
 	kilobytes (i.e. blocks of 1024 bytes)</dd>
 | 
			
		||||
       <dt><code>vcpu</code></dt>
 | 
			
		||||
-      <dd>The content of this element defines the number of virtual
 | 
			
		||||
+      <dd>The content of this element defines the maximum number of virtual
 | 
			
		||||
         CPUs allocated for the guest OS, which must be between 1 and
 | 
			
		||||
         the maximum supported by the hypervisor.  <span class="since">Since
 | 
			
		||||
         0.4.4</span>, this element can contain an optional
 | 
			
		||||
@@ -246,7 +246,10 @@
 | 
			
		||||
         list of physical CPU numbers that virtual CPUs can be pinned
 | 
			
		||||
         to.  Each element in that list is either a single CPU number,
 | 
			
		||||
         a range of CPU numbers, or a caret followed by a CPU number to
 | 
			
		||||
-        be excluded from a previous range.
 | 
			
		||||
+        be excluded from a previous range.  <span class="since">Since
 | 
			
		||||
+        0.8.5</span>, the optional attribute <code>current</code> can
 | 
			
		||||
+        be used to specify whether fewer than the maximum number of
 | 
			
		||||
+        virtual CPUs should be enabled.
 | 
			
		||||
       </dd>
 | 
			
		||||
     </dl>
 | 
			
		||||
 | 
			
		||||
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
 | 
			
		||||
index f230263..a934a77 100644
 | 
			
		||||
--- a/docs/schemas/domain.rng
 | 
			
		||||
+++ b/docs/schemas/domain.rng
 | 
			
		||||
@@ -337,6 +337,11 @@
 | 
			
		||||
               <ref name="cpuset"/>
 | 
			
		||||
             </attribute>
 | 
			
		||||
           </optional>
 | 
			
		||||
+          <optional>
 | 
			
		||||
+            <attribute name="current">
 | 
			
		||||
+              <ref name="countCPU"/>
 | 
			
		||||
+            </attribute>
 | 
			
		||||
+          </optional>
 | 
			
		||||
           <ref name="countCPU"/>
 | 
			
		||||
         </element>
 | 
			
		||||
       </optional>
 | 
			
		||||
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.xml b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..975f873
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.xml
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
+<domain type='qemu'>
 | 
			
		||||
+  <name>QEMUGuest1</name>
 | 
			
		||||
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
 | 
			
		||||
+  <memory>219200</memory>
 | 
			
		||||
+  <currentMemory>219200</currentMemory>
 | 
			
		||||
+  <vcpu current='1'>2</vcpu>
 | 
			
		||||
+  <os>
 | 
			
		||||
+    <type arch='i686' machine='pc'>hvm</type>
 | 
			
		||||
+    <boot dev='hd'/>
 | 
			
		||||
+  </os>
 | 
			
		||||
+  <cpu>
 | 
			
		||||
+    <topology sockets='2' cores='1' threads='1'/>
 | 
			
		||||
+  </cpu>
 | 
			
		||||
+  <clock offset='utc'/>
 | 
			
		||||
+  <on_poweroff>destroy</on_poweroff>
 | 
			
		||||
+  <on_reboot>restart</on_reboot>
 | 
			
		||||
+  <on_crash>destroy</on_crash>
 | 
			
		||||
+  <devices>
 | 
			
		||||
+    <emulator>/usr/bin/qemu</emulator>
 | 
			
		||||
+    <disk type='block' device='disk'>
 | 
			
		||||
+      <source dev='/dev/HostVG/QEMUGuest1'/>
 | 
			
		||||
+      <target dev='hda' bus='ide'/>
 | 
			
		||||
+      <address type='drive' controller='0' bus='0' unit='0'/>
 | 
			
		||||
+    </disk>
 | 
			
		||||
+    <controller type='ide' index='0'/>
 | 
			
		||||
+    <memballoon model='virtio'/>
 | 
			
		||||
+  </devices>
 | 
			
		||||
+</domain>
 | 
			
		||||
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..d061e11
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.xml
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
+<domain type='xen' id='15'>
 | 
			
		||||
+  <name>pvtest</name>
 | 
			
		||||
+  <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid>
 | 
			
		||||
+  <os>
 | 
			
		||||
+    <type>linux</type>
 | 
			
		||||
+    <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
 | 
			
		||||
+    <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
 | 
			
		||||
+    <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os  </cmdline>
 | 
			
		||||
+  </os>
 | 
			
		||||
+  <memory>430080</memory>
 | 
			
		||||
+  <vcpu current='2'>4</vcpu>
 | 
			
		||||
+  <on_poweroff>destroy</on_poweroff>
 | 
			
		||||
+  <on_reboot>destroy</on_reboot>
 | 
			
		||||
+  <on_crash>destroy</on_crash>
 | 
			
		||||
+  <devices>
 | 
			
		||||
+    <disk type='file' device='disk'>
 | 
			
		||||
+      <source file='/root/some.img'/>
 | 
			
		||||
+      <target dev='xvda'/>
 | 
			
		||||
+    </disk>
 | 
			
		||||
+    <console tty='/dev/pts/4'/>
 | 
			
		||||
+  </devices>
 | 
			
		||||
+</domain>
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								docs/api_extension/0002-add-new-public-API.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								docs/api_extension/0002-add-new-public-API.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
From ea3f5c68093429c6ad507b45689cdf209c2c257b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Fri, 24 Sep 2010 16:48:45 -0600
 | 
			
		||||
Subject: [PATCH 02/15] vcpu: add new public API
 | 
			
		||||
 | 
			
		||||
API agreed on in
 | 
			
		||||
https://www.redhat.com/archives/libvir-list/2010-September/msg00456.html,
 | 
			
		||||
but modified for enum names to be consistent with virDomainDeviceModifyFlags.
 | 
			
		||||
 | 
			
		||||
* include/libvirt/libvirt.h.in (virDomainVcpuFlags)
 | 
			
		||||
(virDomainSetVcpusFlags, virDomainGetVcpusFlags): New
 | 
			
		||||
declarations.
 | 
			
		||||
* src/libvirt_public.syms: Export new symbols.
 | 
			
		||||
---
 | 
			
		||||
 include/libvirt/libvirt.h.in |   15 +++++++++++++++
 | 
			
		||||
 src/libvirt_public.syms      |    2 ++
 | 
			
		||||
 2 files changed, 17 insertions(+), 0 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
 | 
			
		||||
index 2eba61e..d0cc4c0 100644
 | 
			
		||||
--- a/include/libvirt/libvirt.h.in
 | 
			
		||||
+++ b/include/libvirt/libvirt.h.in
 | 
			
		||||
@@ -915,8 +915,23 @@ struct _virVcpuInfo {
 | 
			
		||||
 };
 | 
			
		||||
 typedef virVcpuInfo *virVcpuInfoPtr;
 | 
			
		||||
 | 
			
		||||
+/* Flags for controlling virtual CPU hot-plugging.  */
 | 
			
		||||
+typedef enum {
 | 
			
		||||
+    /* Must choose at least one of these two bits; SetVcpus can choose both */
 | 
			
		||||
+    VIR_DOMAIN_VCPU_LIVE    = (1 << 0), /* Affect active domain */
 | 
			
		||||
+    VIR_DOMAIN_VCPU_CONFIG  = (1 << 1), /* Affect next boot */
 | 
			
		||||
+
 | 
			
		||||
+    /* Additional flags to be bit-wise OR'd in */
 | 
			
		||||
+    VIR_DOMAIN_VCPU_MAXIMUM = (1 << 2), /* Max rather than current count */
 | 
			
		||||
+} virDomainVcpuFlags;
 | 
			
		||||
+
 | 
			
		||||
 int                     virDomainSetVcpus       (virDomainPtr domain,
 | 
			
		||||
                                                  unsigned int nvcpus);
 | 
			
		||||
+int                     virDomainSetVcpusFlags  (virDomainPtr domain,
 | 
			
		||||
+                                                 unsigned int nvcpus,
 | 
			
		||||
+                                                 unsigned int flags);
 | 
			
		||||
+int                     virDomainGetVcpusFlags  (virDomainPtr domain,
 | 
			
		||||
+                                                 unsigned int flags);
 | 
			
		||||
 | 
			
		||||
 int                     virDomainPinVcpu        (virDomainPtr domain,
 | 
			
		||||
                                                  unsigned int vcpu,
 | 
			
		||||
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
 | 
			
		||||
index fceb516..a8091b1 100644
 | 
			
		||||
--- a/src/libvirt_public.syms
 | 
			
		||||
+++ b/src/libvirt_public.syms
 | 
			
		||||
@@ -409,6 +409,8 @@ LIBVIRT_0.8.5 {
 | 
			
		||||
     global:
 | 
			
		||||
         virDomainSetMemoryParameters;
 | 
			
		||||
         virDomainGetMemoryParameters;
 | 
			
		||||
+        virDomainGetVcpusFlags;
 | 
			
		||||
+        virDomainSetVcpusFlags;
 | 
			
		||||
 } LIBVIRT_0.8.2;
 | 
			
		||||
 | 
			
		||||
 # .... define new API here using predicted next version number ....
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										222
									
								
								docs/api_extension/0003-define-internal-driver-API.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								docs/api_extension/0003-define-internal-driver-API.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,222 @@
 | 
			
		||||
From dd255d64053e9960cd375994ce8f056522e12acc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Mon, 27 Sep 2010 09:18:22 -0600
 | 
			
		||||
Subject: [PATCH 03/15] vcpu: define internal driver API
 | 
			
		||||
 | 
			
		||||
* src/driver.h (virDrvDomainSetVcpusFlags)
 | 
			
		||||
(virDrvDomainGetVcpusFlags): New typedefs.
 | 
			
		||||
(_virDriver): New callback members.
 | 
			
		||||
* src/esx/esx_driver.c (esxDriver): Add stub for driver.
 | 
			
		||||
* src/lxc/lxc_driver.c (lxcDriver): Likewise.
 | 
			
		||||
* src/opennebula/one_driver.c (oneDriver): Likewise.
 | 
			
		||||
* src/openvz/openvz_driver.c (openvzDriver): Likewise.
 | 
			
		||||
* src/phyp/phyp_driver.c (phypDriver): Likewise.
 | 
			
		||||
* src/qemu/qemu_driver.c (qemuDriver): Likewise.
 | 
			
		||||
* src/remote/remote_driver.c (remote_driver): Likewise.
 | 
			
		||||
* src/test/test_driver.c (testDriver): Likewise.
 | 
			
		||||
* src/uml/uml_driver.c (umlDriver): Likewise.
 | 
			
		||||
* src/vbox/vbox_tmpl.c (Driver): Likewise.
 | 
			
		||||
* src/xen/xen_driver.c (xenUnifiedDriver): Likewise.
 | 
			
		||||
* src/xenapi/xenapi_driver.c (xenapiDriver): Likewise.
 | 
			
		||||
---
 | 
			
		||||
 src/driver.h                |    9 +++++++++
 | 
			
		||||
 src/esx/esx_driver.c        |    2 ++
 | 
			
		||||
 src/lxc/lxc_driver.c        |    2 ++
 | 
			
		||||
 src/opennebula/one_driver.c |    2 ++
 | 
			
		||||
 src/openvz/openvz_driver.c  |    2 ++
 | 
			
		||||
 src/phyp/phyp_driver.c      |    2 ++
 | 
			
		||||
 src/qemu/qemu_driver.c      |    2 ++
 | 
			
		||||
 src/remote/remote_driver.c  |    2 ++
 | 
			
		||||
 src/test/test_driver.c      |    2 ++
 | 
			
		||||
 src/uml/uml_driver.c        |    2 ++
 | 
			
		||||
 src/vbox/vbox_tmpl.c        |    2 ++
 | 
			
		||||
 src/xen/xen_driver.c        |    2 ++
 | 
			
		||||
 src/xenapi/xenapi_driver.c  |    2 ++
 | 
			
		||||
 13 files changed, 33 insertions(+), 0 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/driver.h b/src/driver.h
 | 
			
		||||
index 32aeb04..79a96c1 100644
 | 
			
		||||
--- a/src/driver.h
 | 
			
		||||
+++ b/src/driver.h
 | 
			
		||||
@@ -185,6 +185,13 @@ typedef int
 | 
			
		||||
         (*virDrvDomainSetVcpus)		(virDomainPtr domain,
 | 
			
		||||
                                          unsigned int nvcpus);
 | 
			
		||||
 typedef int
 | 
			
		||||
+        (*virDrvDomainSetVcpusFlags)	(virDomainPtr domain,
 | 
			
		||||
+                                         unsigned int nvcpus,
 | 
			
		||||
+                                         unsigned int flags);
 | 
			
		||||
+typedef int
 | 
			
		||||
+        (*virDrvDomainGetVcpusFlags)	(virDomainPtr domain,
 | 
			
		||||
+                                         unsigned int flags);
 | 
			
		||||
+typedef int
 | 
			
		||||
         (*virDrvDomainPinVcpu)		(virDomainPtr domain,
 | 
			
		||||
                                          unsigned int vcpu,
 | 
			
		||||
                                          unsigned char *cpumap,
 | 
			
		||||
@@ -520,6 +527,8 @@ struct _virDriver {
 | 
			
		||||
     virDrvDomainRestore		domainRestore;
 | 
			
		||||
     virDrvDomainCoreDump		domainCoreDump;
 | 
			
		||||
     virDrvDomainSetVcpus		domainSetVcpus;
 | 
			
		||||
+    virDrvDomainSetVcpusFlags		domainSetVcpusFlags;
 | 
			
		||||
+    virDrvDomainGetVcpusFlags		domainGetVcpusFlags;
 | 
			
		||||
     virDrvDomainPinVcpu		domainPinVcpu;
 | 
			
		||||
     virDrvDomainGetVcpus		domainGetVcpus;
 | 
			
		||||
     virDrvDomainGetMaxVcpus		domainGetMaxVcpus;
 | 
			
		||||
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
 | 
			
		||||
index 1b4ee29..2a32374 100644
 | 
			
		||||
--- a/src/esx/esx_driver.c
 | 
			
		||||
+++ b/src/esx/esx_driver.c
 | 
			
		||||
@@ -4160,6 +4160,8 @@ static virDriver esxDriver = {
 | 
			
		||||
     NULL,                            /* domainRestore */
 | 
			
		||||
     NULL,                            /* domainCoreDump */
 | 
			
		||||
     esxDomainSetVcpus,               /* domainSetVcpus */
 | 
			
		||||
+    NULL,                            /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL,                            /* domainGetVcpusFlags */
 | 
			
		||||
     NULL,                            /* domainPinVcpu */
 | 
			
		||||
     NULL,                            /* domainGetVcpus */
 | 
			
		||||
     esxDomainGetMaxVcpus,            /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
 | 
			
		||||
index df814da..7563a8c 100644
 | 
			
		||||
--- a/src/lxc/lxc_driver.c
 | 
			
		||||
+++ b/src/lxc/lxc_driver.c
 | 
			
		||||
@@ -2768,6 +2768,8 @@ static virDriver lxcDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     NULL, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     NULL, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
 | 
			
		||||
index ced9a38..199fca3 100644
 | 
			
		||||
--- a/src/opennebula/one_driver.c
 | 
			
		||||
+++ b/src/opennebula/one_driver.c
 | 
			
		||||
@@ -751,6 +751,8 @@ static virDriver oneDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     NULL, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     NULL, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
 | 
			
		||||
index 92cf4a1..9d19aeb 100644
 | 
			
		||||
--- a/src/openvz/openvz_driver.c
 | 
			
		||||
+++ b/src/openvz/openvz_driver.c
 | 
			
		||||
@@ -1590,6 +1590,8 @@ static virDriver openvzDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     openvzDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
 | 
			
		||||
index e63d8d9..6e0a5e9 100644
 | 
			
		||||
--- a/src/phyp/phyp_driver.c
 | 
			
		||||
+++ b/src/phyp/phyp_driver.c
 | 
			
		||||
@@ -3941,6 +3941,8 @@ static virDriver phypDriver = {
 | 
			
		||||
     NULL,                       /* domainRestore */
 | 
			
		||||
     NULL,                       /* domainCoreDump */
 | 
			
		||||
     phypDomainSetCPU,           /* domainSetVcpus */
 | 
			
		||||
+    NULL,                       /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL,                       /* domainGetVcpusFlags */
 | 
			
		||||
     NULL,                       /* domainPinVcpu */
 | 
			
		||||
     NULL,                       /* domainGetVcpus */
 | 
			
		||||
     phypGetLparCPUMAX,          /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 | 
			
		||||
index abd8e9d..3d17e04 100644
 | 
			
		||||
--- a/src/qemu/qemu_driver.c
 | 
			
		||||
+++ b/src/qemu/qemu_driver.c
 | 
			
		||||
@@ -12938,6 +12938,8 @@ static virDriver qemuDriver = {
 | 
			
		||||
     qemudDomainRestore, /* domainRestore */
 | 
			
		||||
     qemudDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     qemudDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     qemudDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     qemudDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
 | 
			
		||||
index 0b10406..1a687ad 100644
 | 
			
		||||
--- a/src/remote/remote_driver.c
 | 
			
		||||
+++ b/src/remote/remote_driver.c
 | 
			
		||||
@@ -10468,6 +10468,8 @@ static virDriver remote_driver = {
 | 
			
		||||
     remoteDomainRestore, /* domainRestore */
 | 
			
		||||
     remoteDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     remoteDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     remoteDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     remoteDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
 | 
			
		||||
index 7d4d119..6a00558 100644
 | 
			
		||||
--- a/src/test/test_driver.c
 | 
			
		||||
+++ b/src/test/test_driver.c
 | 
			
		||||
@@ -5260,6 +5260,8 @@ static virDriver testDriver = {
 | 
			
		||||
     testDomainRestore, /* domainRestore */
 | 
			
		||||
     testDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     testSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     testDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     testDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     testDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
 | 
			
		||||
index 3dcd321..5161012 100644
 | 
			
		||||
--- a/src/uml/uml_driver.c
 | 
			
		||||
+++ b/src/uml/uml_driver.c
 | 
			
		||||
@@ -2129,6 +2129,8 @@ static virDriver umlDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     NULL, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     NULL, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
 | 
			
		||||
index 7e7d8e4..cb9193a 100644
 | 
			
		||||
--- a/src/vbox/vbox_tmpl.c
 | 
			
		||||
+++ b/src/vbox/vbox_tmpl.c
 | 
			
		||||
@@ -8267,6 +8267,8 @@ virDriver NAME(Driver) = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     vboxDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
 | 
			
		||||
index c2a4de3..7d67ced 100644
 | 
			
		||||
--- a/src/xen/xen_driver.c
 | 
			
		||||
+++ b/src/xen/xen_driver.c
 | 
			
		||||
@@ -1951,6 +1951,8 @@ static virDriver xenUnifiedDriver = {
 | 
			
		||||
     xenUnifiedDomainRestore, /* domainRestore */
 | 
			
		||||
     xenUnifiedDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     xenUnifiedDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     xenUnifiedDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     xenUnifiedDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
 | 
			
		||||
index e62a139..753169c 100644
 | 
			
		||||
--- a/src/xenapi/xenapi_driver.c
 | 
			
		||||
+++ b/src/xenapi/xenapi_driver.c
 | 
			
		||||
@@ -1754,6 +1754,8 @@ static virDriver xenapiDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     xenapiDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
+    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
+    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
     xenapiDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     xenapiDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										188
									
								
								docs/api_extension/0004-implement-the-public-APIs.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								docs/api_extension/0004-implement-the-public-APIs.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
From 9d2c60799271d605f82dfd4bfa6ed7d14ad87e26 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Mon, 27 Sep 2010 09:37:22 -0600
 | 
			
		||||
Subject: [PATCH 04/15] vcpu: implement the public APIs
 | 
			
		||||
 | 
			
		||||
Factors common checks (such as nonzero vcpu count) up front, but
 | 
			
		||||
drivers will still need to do additional flag checks.
 | 
			
		||||
 | 
			
		||||
* src/libvirt.c (virDomainSetVcpusFlags, virDomainGetVcpusFlags):
 | 
			
		||||
New functions.
 | 
			
		||||
(virDomainSetVcpus, virDomainGetMaxVcpus): Refer to new API.
 | 
			
		||||
---
 | 
			
		||||
 src/libvirt.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 | 
			
		||||
 1 files changed, 134 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/libvirt.c b/src/libvirt.c
 | 
			
		||||
index 629d97b..1b39210 100644
 | 
			
		||||
--- a/src/libvirt.c
 | 
			
		||||
+++ b/src/libvirt.c
 | 
			
		||||
@@ -5192,7 +5192,9 @@ error:
 | 
			
		||||
  * This function requires privileged access to the hypervisor.
 | 
			
		||||
  *
 | 
			
		||||
  * This command only changes the runtime configuration of the domain,
 | 
			
		||||
- * so can only be called on an active domain.
 | 
			
		||||
+ * so can only be called on an active domain.  It is hypervisor-dependent
 | 
			
		||||
+ * whether it also affects persistent configuration; for more control,
 | 
			
		||||
+ * use virDomainSetVcpusFlags().
 | 
			
		||||
  *
 | 
			
		||||
  * Returns 0 in case of success, -1 in case of failure.
 | 
			
		||||
  */
 | 
			
		||||
@@ -5237,13 +5239,139 @@ error:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
+ * virDomainSetVcpusFlags:
 | 
			
		||||
+ * @domain: pointer to domain object, or NULL for Domain0
 | 
			
		||||
+ * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1
 | 
			
		||||
+ * @flags: an OR'ed set of virDomainVcpuFlags
 | 
			
		||||
+ *
 | 
			
		||||
+ * Dynamically change the number of virtual CPUs used by the domain.
 | 
			
		||||
+ * Note that this call may fail if the underlying virtualization hypervisor
 | 
			
		||||
+ * does not support it or if growing the number is arbitrary limited.
 | 
			
		||||
+ * This function requires privileged access to the hypervisor.
 | 
			
		||||
+ *
 | 
			
		||||
+ * @flags must include VIR_DOMAIN_VCPU_LIVE to affect a running
 | 
			
		||||
+ * domain (which may fail if domain is not active), or
 | 
			
		||||
+ * VIR_DOMAIN_VCPU_CONFIG to affect the next boot via the XML
 | 
			
		||||
+ * description of the domain.  Both flags may be set.
 | 
			
		||||
+ *
 | 
			
		||||
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then
 | 
			
		||||
+ * VIR_DOMAIN_VCPU_LIVE must be clear, and only the maximum virtual
 | 
			
		||||
+ * CPU limit is altered; generally, this value must be less than or
 | 
			
		||||
+ * equal to virConnectGetMaxVcpus().  Otherwise, this call affects the
 | 
			
		||||
+ * current virtual CPU limit, which must be less than or equal to the
 | 
			
		||||
+ * maximum limit.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns 0 in case of success, -1 in case of failure.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+int
 | 
			
		||||
+virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
 | 
			
		||||
+                       unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    virConnectPtr conn;
 | 
			
		||||
+    VIR_DEBUG("domain=%p, nvcpus=%u, flags=%u", domain, nvcpus, flags);
 | 
			
		||||
+
 | 
			
		||||
+    virResetLastError();
 | 
			
		||||
+
 | 
			
		||||
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
 | 
			
		||||
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
 | 
			
		||||
+        virDispatchError(NULL);
 | 
			
		||||
+        return (-1);
 | 
			
		||||
+    }
 | 
			
		||||
+    if (domain->conn->flags & VIR_CONNECT_RO) {
 | 
			
		||||
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
 | 
			
		||||
+        goto error;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /* Perform some argument validation common to all implementations.  */
 | 
			
		||||
+    if (nvcpus < 1 || (unsigned short) nvcpus != nvcpus ||
 | 
			
		||||
+        (flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
 | 
			
		||||
+        virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
+        goto error;
 | 
			
		||||
+    }
 | 
			
		||||
+    conn = domain->conn;
 | 
			
		||||
+
 | 
			
		||||
+    if (conn->driver->domainSetVcpusFlags) {
 | 
			
		||||
+        int ret;
 | 
			
		||||
+        ret = conn->driver->domainSetVcpusFlags (domain, nvcpus, flags);
 | 
			
		||||
+        if (ret < 0)
 | 
			
		||||
+            goto error;
 | 
			
		||||
+        return ret;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 | 
			
		||||
+
 | 
			
		||||
+error:
 | 
			
		||||
+    virDispatchError(domain->conn);
 | 
			
		||||
+    return -1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * virDomainGetVcpusFlags:
 | 
			
		||||
+ * @domain: pointer to domain object, or NULL for Domain0
 | 
			
		||||
+ * @flags: an OR'ed set of virDomainVcpuFlags
 | 
			
		||||
+ *
 | 
			
		||||
+ * Query the number of virtual CPUs used by the domain.  Note that
 | 
			
		||||
+ * this call may fail if the underlying virtualization hypervisor does
 | 
			
		||||
+ * not support it.  This function requires privileged access to the
 | 
			
		||||
+ * hypervisor.
 | 
			
		||||
+ *
 | 
			
		||||
+ * @flags must include either VIR_DOMAIN_VCPU_ACTIVE to query a
 | 
			
		||||
+ * running domain (which will fail if domain is not active), or
 | 
			
		||||
+ * VIR_DOMAIN_VCPU_PERSISTENT to query the XML description of the
 | 
			
		||||
+ * domain.  It is an error to set both flags.
 | 
			
		||||
+ *
 | 
			
		||||
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum
 | 
			
		||||
+ * virtual CPU limit is queried.  Otherwise, this call queries the
 | 
			
		||||
+ * current virtual CPU limit.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns 0 in case of success, -1 in case of failure.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+int
 | 
			
		||||
+virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    virConnectPtr conn;
 | 
			
		||||
+    VIR_DEBUG("domain=%p, flags=%u", domain, flags);
 | 
			
		||||
+
 | 
			
		||||
+    virResetLastError();
 | 
			
		||||
+
 | 
			
		||||
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
 | 
			
		||||
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
 | 
			
		||||
+        virDispatchError(NULL);
 | 
			
		||||
+        return (-1);
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /* Exactly one of these two flags should be set.  */
 | 
			
		||||
+    if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
 | 
			
		||||
+        virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
+        goto error;
 | 
			
		||||
+    }
 | 
			
		||||
+    conn = domain->conn;
 | 
			
		||||
+
 | 
			
		||||
+    if (conn->driver->domainGetVcpusFlags) {
 | 
			
		||||
+        int ret;
 | 
			
		||||
+        ret = conn->driver->domainGetVcpusFlags (domain, flags);
 | 
			
		||||
+        if (ret < 0)
 | 
			
		||||
+            goto error;
 | 
			
		||||
+        return ret;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 | 
			
		||||
+
 | 
			
		||||
+error:
 | 
			
		||||
+    virDispatchError(domain->conn);
 | 
			
		||||
+    return -1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
  * virDomainPinVcpu:
 | 
			
		||||
  * @domain: pointer to domain object, or NULL for Domain0
 | 
			
		||||
  * @vcpu: virtual CPU number
 | 
			
		||||
  * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
 | 
			
		||||
- * 	Each bit set to 1 means that corresponding CPU is usable.
 | 
			
		||||
- * 	Bytes are stored in little-endian order: CPU0-7, 8-15...
 | 
			
		||||
- * 	In each byte, lowest CPU number is least significant bit.
 | 
			
		||||
+ *      Each bit set to 1 means that corresponding CPU is usable.
 | 
			
		||||
+ *      Bytes are stored in little-endian order: CPU0-7, 8-15...
 | 
			
		||||
+ *      In each byte, lowest CPU number is least significant bit.
 | 
			
		||||
  * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
 | 
			
		||||
  *	underlying virtualization system (Xen...).
 | 
			
		||||
  *	If maplen < size, missing bytes are set to zero.
 | 
			
		||||
@@ -5371,9 +5499,9 @@ error:
 | 
			
		||||
  *
 | 
			
		||||
  * Provides the maximum number of virtual CPUs supported for
 | 
			
		||||
  * the guest VM. If the guest is inactive, this is basically
 | 
			
		||||
- * the same as virConnectGetMaxVcpus. If the guest is running
 | 
			
		||||
+ * the same as virConnectGetMaxVcpus(). If the guest is running
 | 
			
		||||
  * this will reflect the maximum number of virtual CPUs the
 | 
			
		||||
- * guest was booted with.
 | 
			
		||||
+ * guest was booted with.  For more details, see virDomainGetVcpusFlags().
 | 
			
		||||
  *
 | 
			
		||||
  * Returns the maximum of virtual CPU or -1 in case of error.
 | 
			
		||||
  */
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										421
									
								
								docs/api_extension/0005-implement-the-remote-protocol.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										421
									
								
								docs/api_extension/0005-implement-the-remote-protocol.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,421 @@
 | 
			
		||||
From eb826444f90c2563dadf148630b0cd6a9b41ba1e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Mon, 27 Sep 2010 10:10:06 -0600
 | 
			
		||||
Subject: [PATCH 05/15] vcpu: implement the remote protocol
 | 
			
		||||
 | 
			
		||||
Done by editing the first three files, then running
 | 
			
		||||
'make -C src rpcgen', then editing src/remote_protocol-structs
 | 
			
		||||
to match.
 | 
			
		||||
 | 
			
		||||
* daemon/remote.c (remoteDispatchDomainSetVcpusFlags)
 | 
			
		||||
(remoteDispatchDomainGetVcpusFlags): New functions.
 | 
			
		||||
* src/remote/remote_driver.c (remoteDomainSetVcpusFlags)
 | 
			
		||||
(remoteDomainGetVcpusFlags, remote_driver): Client side
 | 
			
		||||
serialization.
 | 
			
		||||
* src/remote/remote_protocol.x
 | 
			
		||||
(remote_domain_set_vcpus_flags_args)
 | 
			
		||||
(remote_domain_get_vcpus_flags_args)
 | 
			
		||||
(remote_domain_get_vcpus_flags_ret)
 | 
			
		||||
(REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS)
 | 
			
		||||
(REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS): Define wire format.
 | 
			
		||||
* daemon/remote_dispatch_args.h: Regenerate.
 | 
			
		||||
* daemon/remote_dispatch_prototypes.h: Likewise.
 | 
			
		||||
* daemon/remote_dispatch_table.h: Likewise.
 | 
			
		||||
* src/remote/remote_protocol.c: Likewise.
 | 
			
		||||
* src/remote/remote_protocol.h: Likewise.
 | 
			
		||||
* src/remote_protocol-structs: Likewise.
 | 
			
		||||
---
 | 
			
		||||
 daemon/remote.c                     |   53 ++++++++++++++++++++++++++++++++
 | 
			
		||||
 daemon/remote_dispatch_args.h       |    2 +
 | 
			
		||||
 daemon/remote_dispatch_prototypes.h |   16 ++++++++++
 | 
			
		||||
 daemon/remote_dispatch_ret.h        |    1 +
 | 
			
		||||
 daemon/remote_dispatch_table.h      |   10 ++++++
 | 
			
		||||
 src/remote/remote_driver.c          |   57 +++++++++++++++++++++++++++++++++-
 | 
			
		||||
 src/remote/remote_protocol.c        |   33 ++++++++++++++++++++
 | 
			
		||||
 src/remote/remote_protocol.h        |   26 ++++++++++++++++
 | 
			
		||||
 src/remote/remote_protocol.x        |   19 +++++++++++-
 | 
			
		||||
 src/remote_protocol-structs         |   12 +++++++
 | 
			
		||||
 10 files changed, 226 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemon/remote.c b/daemon/remote.c
 | 
			
		||||
index 7a96e29..323f00c 100644
 | 
			
		||||
--- a/daemon/remote.c
 | 
			
		||||
+++ b/daemon/remote.c
 | 
			
		||||
@@ -1751,6 +1751,33 @@ oom:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
+remoteDispatchDomainGetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
 | 
			
		||||
+                                   struct qemud_client *client ATTRIBUTE_UNUSED,
 | 
			
		||||
+                                   virConnectPtr conn,
 | 
			
		||||
+                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
 | 
			
		||||
+                                   remote_error *rerr,
 | 
			
		||||
+                                   remote_domain_get_vcpus_flags_args *args,
 | 
			
		||||
+                                   remote_domain_get_vcpus_flags_ret *ret)
 | 
			
		||||
+{
 | 
			
		||||
+    virDomainPtr dom;
 | 
			
		||||
+
 | 
			
		||||
+    dom = get_nonnull_domain (conn, args->dom);
 | 
			
		||||
+    if (dom == NULL) {
 | 
			
		||||
+        remoteDispatchConnError(rerr, conn);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    ret->num = virDomainGetVcpusFlags (dom, args->flags);
 | 
			
		||||
+    if (ret->num == -1) {
 | 
			
		||||
+        virDomainFree(dom);
 | 
			
		||||
+        remoteDispatchConnError(rerr, conn);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    virDomainFree(dom);
 | 
			
		||||
+    return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
 remoteDispatchDomainMigratePrepare (struct qemud_server *server ATTRIBUTE_UNUSED,
 | 
			
		||||
                                     struct qemud_client *client ATTRIBUTE_UNUSED,
 | 
			
		||||
                                     virConnectPtr conn,
 | 
			
		||||
@@ -2568,6 +2595,32 @@ remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
+remoteDispatchDomainSetVcpusFlags (struct qemud_server *server ATTRIBUTE_UNUSED,
 | 
			
		||||
+                                   struct qemud_client *client ATTRIBUTE_UNUSED,
 | 
			
		||||
+                                   virConnectPtr conn,
 | 
			
		||||
+                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
 | 
			
		||||
+                                   remote_error *rerr,
 | 
			
		||||
+                                   remote_domain_set_vcpus_flags_args *args,
 | 
			
		||||
+                                   void *ret ATTRIBUTE_UNUSED)
 | 
			
		||||
+{
 | 
			
		||||
+    virDomainPtr dom;
 | 
			
		||||
+
 | 
			
		||||
+    dom = get_nonnull_domain (conn, args->dom);
 | 
			
		||||
+    if (dom == NULL) {
 | 
			
		||||
+        remoteDispatchConnError(rerr, conn);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (virDomainSetVcpusFlags (dom, args->nvcpus, args->flags) == -1) {
 | 
			
		||||
+        virDomainFree(dom);
 | 
			
		||||
+        remoteDispatchConnError(rerr, conn);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    virDomainFree(dom);
 | 
			
		||||
+    return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
 remoteDispatchDomainShutdown (struct qemud_server *server ATTRIBUTE_UNUSED,
 | 
			
		||||
                               struct qemud_client *client ATTRIBUTE_UNUSED,
 | 
			
		||||
                               virConnectPtr conn,
 | 
			
		||||
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
 | 
			
		||||
index d8528b6..9583e9c 100644
 | 
			
		||||
--- a/daemon/remote_dispatch_args.h
 | 
			
		||||
+++ b/daemon/remote_dispatch_args.h
 | 
			
		||||
@@ -167,3 +167,5 @@
 | 
			
		||||
     remote_domain_create_with_flags_args val_remote_domain_create_with_flags_args;
 | 
			
		||||
     remote_domain_set_memory_parameters_args val_remote_domain_set_memory_parameters_args;
 | 
			
		||||
     remote_domain_get_memory_parameters_args val_remote_domain_get_memory_parameters_args;
 | 
			
		||||
+    remote_domain_set_vcpus_flags_args val_remote_domain_set_vcpus_flags_args;
 | 
			
		||||
+    remote_domain_get_vcpus_flags_args val_remote_domain_get_vcpus_flags_args;
 | 
			
		||||
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
 | 
			
		||||
index b674bb4..6b35851 100644
 | 
			
		||||
--- a/daemon/remote_dispatch_prototypes.h
 | 
			
		||||
+++ b/daemon/remote_dispatch_prototypes.h
 | 
			
		||||
@@ -306,6 +306,14 @@ static int remoteDispatchDomainGetVcpus(
 | 
			
		||||
     remote_error *err,
 | 
			
		||||
     remote_domain_get_vcpus_args *args,
 | 
			
		||||
     remote_domain_get_vcpus_ret *ret);
 | 
			
		||||
+static int remoteDispatchDomainGetVcpusFlags(
 | 
			
		||||
+    struct qemud_server *server,
 | 
			
		||||
+    struct qemud_client *client,
 | 
			
		||||
+    virConnectPtr conn,
 | 
			
		||||
+    remote_message_header *hdr,
 | 
			
		||||
+    remote_error *err,
 | 
			
		||||
+    remote_domain_get_vcpus_flags_args *args,
 | 
			
		||||
+    remote_domain_get_vcpus_flags_ret *ret);
 | 
			
		||||
 static int remoteDispatchDomainHasCurrentSnapshot(
 | 
			
		||||
     struct qemud_server *server,
 | 
			
		||||
     struct qemud_client *client,
 | 
			
		||||
@@ -554,6 +562,14 @@ static int remoteDispatchDomainSetVcpus(
 | 
			
		||||
     remote_error *err,
 | 
			
		||||
     remote_domain_set_vcpus_args *args,
 | 
			
		||||
     void *ret);
 | 
			
		||||
+static int remoteDispatchDomainSetVcpusFlags(
 | 
			
		||||
+    struct qemud_server *server,
 | 
			
		||||
+    struct qemud_client *client,
 | 
			
		||||
+    virConnectPtr conn,
 | 
			
		||||
+    remote_message_header *hdr,
 | 
			
		||||
+    remote_error *err,
 | 
			
		||||
+    remote_domain_set_vcpus_flags_args *args,
 | 
			
		||||
+    void *ret);
 | 
			
		||||
 static int remoteDispatchDomainShutdown(
 | 
			
		||||
     struct qemud_server *server,
 | 
			
		||||
     struct qemud_client *client,
 | 
			
		||||
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
 | 
			
		||||
index 17c9bca..3723b00 100644
 | 
			
		||||
--- a/daemon/remote_dispatch_ret.h
 | 
			
		||||
+++ b/daemon/remote_dispatch_ret.h
 | 
			
		||||
@@ -136,3 +136,4 @@
 | 
			
		||||
     remote_domain_get_block_info_ret val_remote_domain_get_block_info_ret;
 | 
			
		||||
     remote_domain_create_with_flags_ret val_remote_domain_create_with_flags_ret;
 | 
			
		||||
     remote_domain_get_memory_parameters_ret val_remote_domain_get_memory_parameters_ret;
 | 
			
		||||
+    remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret;
 | 
			
		||||
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
 | 
			
		||||
index 47d95eb..dd2adc7 100644
 | 
			
		||||
--- a/daemon/remote_dispatch_table.h
 | 
			
		||||
+++ b/daemon/remote_dispatch_table.h
 | 
			
		||||
@@ -997,3 +997,13 @@
 | 
			
		||||
     .args_filter = (xdrproc_t) xdr_remote_domain_get_memory_parameters_args,
 | 
			
		||||
     .ret_filter = (xdrproc_t) xdr_remote_domain_get_memory_parameters_ret,
 | 
			
		||||
 },
 | 
			
		||||
+{   /* DomainSetVcpusFlags => 199 */
 | 
			
		||||
+    .fn = (dispatch_fn) remoteDispatchDomainSetVcpusFlags,
 | 
			
		||||
+    .args_filter = (xdrproc_t) xdr_remote_domain_set_vcpus_flags_args,
 | 
			
		||||
+    .ret_filter = (xdrproc_t) xdr_void,
 | 
			
		||||
+},
 | 
			
		||||
+{   /* DomainGetVcpusFlags => 200 */
 | 
			
		||||
+    .fn = (dispatch_fn) remoteDispatchDomainGetVcpusFlags,
 | 
			
		||||
+    .args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args,
 | 
			
		||||
+    .ret_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret,
 | 
			
		||||
+},
 | 
			
		||||
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
 | 
			
		||||
index 1a687ad..37c37ef 100644
 | 
			
		||||
--- a/src/remote/remote_driver.c
 | 
			
		||||
+++ b/src/remote/remote_driver.c
 | 
			
		||||
@@ -2580,6 +2580,59 @@ done:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
+remoteDomainSetVcpusFlags (virDomainPtr domain, unsigned int nvcpus,
 | 
			
		||||
+                           unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    int rv = -1;
 | 
			
		||||
+    remote_domain_set_vcpus_flags_args args;
 | 
			
		||||
+    struct private_data *priv = domain->conn->privateData;
 | 
			
		||||
+
 | 
			
		||||
+    remoteDriverLock(priv);
 | 
			
		||||
+
 | 
			
		||||
+    make_nonnull_domain (&args.dom, domain);
 | 
			
		||||
+    args.nvcpus = nvcpus;
 | 
			
		||||
+    args.flags = flags;
 | 
			
		||||
+
 | 
			
		||||
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS,
 | 
			
		||||
+              (xdrproc_t) xdr_remote_domain_set_vcpus_flags_args,
 | 
			
		||||
+              (char *) &args,
 | 
			
		||||
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
 | 
			
		||||
+        goto done;
 | 
			
		||||
+
 | 
			
		||||
+    rv = 0;
 | 
			
		||||
+
 | 
			
		||||
+done:
 | 
			
		||||
+    remoteDriverUnlock(priv);
 | 
			
		||||
+    return rv;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
+remoteDomainGetVcpusFlags (virDomainPtr domain, unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    int rv = -1;
 | 
			
		||||
+    remote_domain_get_vcpus_flags_args args;
 | 
			
		||||
+    remote_domain_get_vcpus_flags_ret ret;
 | 
			
		||||
+    struct private_data *priv = domain->conn->privateData;
 | 
			
		||||
+
 | 
			
		||||
+    remoteDriverLock(priv);
 | 
			
		||||
+
 | 
			
		||||
+    make_nonnull_domain (&args.dom, domain);
 | 
			
		||||
+    args.flags = flags;
 | 
			
		||||
+
 | 
			
		||||
+    memset (&ret, 0, sizeof ret);
 | 
			
		||||
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS,
 | 
			
		||||
+              (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args, (char *) &args,
 | 
			
		||||
+              (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret, (char *) &ret) == -1)
 | 
			
		||||
+        goto done;
 | 
			
		||||
+
 | 
			
		||||
+    rv = ret.num;
 | 
			
		||||
+
 | 
			
		||||
+done:
 | 
			
		||||
+    remoteDriverUnlock(priv);
 | 
			
		||||
+    return rv;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
 remoteDomainPinVcpu (virDomainPtr domain,
 | 
			
		||||
                      unsigned int vcpu,
 | 
			
		||||
                      unsigned char *cpumap,
 | 
			
		||||
@@ -10468,8 +10521,8 @@ static virDriver remote_driver = {
 | 
			
		||||
     remoteDomainRestore, /* domainRestore */
 | 
			
		||||
     remoteDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     remoteDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    remoteDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    remoteDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     remoteDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     remoteDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
 | 
			
		||||
index 5c55713..38ea050 100644
 | 
			
		||||
--- a/src/remote/remote_protocol.c
 | 
			
		||||
+++ b/src/remote/remote_protocol.c
 | 
			
		||||
@@ -1355,6 +1355,39 @@ xdr_remote_domain_set_vcpus_args (XDR *xdrs, remote_domain_set_vcpus_args *objp)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 bool_t
 | 
			
		||||
+xdr_remote_domain_set_vcpus_flags_args (XDR *xdrs, remote_domain_set_vcpus_flags_args *objp)
 | 
			
		||||
+{
 | 
			
		||||
+
 | 
			
		||||
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
 | 
			
		||||
+                 return FALSE;
 | 
			
		||||
+         if (!xdr_u_int (xdrs, &objp->nvcpus))
 | 
			
		||||
+                 return FALSE;
 | 
			
		||||
+         if (!xdr_u_int (xdrs, &objp->flags))
 | 
			
		||||
+                 return FALSE;
 | 
			
		||||
+        return TRUE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool_t
 | 
			
		||||
+xdr_remote_domain_get_vcpus_flags_args (XDR *xdrs, remote_domain_get_vcpus_flags_args *objp)
 | 
			
		||||
+{
 | 
			
		||||
+
 | 
			
		||||
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
 | 
			
		||||
+                 return FALSE;
 | 
			
		||||
+         if (!xdr_u_int (xdrs, &objp->flags))
 | 
			
		||||
+                 return FALSE;
 | 
			
		||||
+        return TRUE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool_t
 | 
			
		||||
+xdr_remote_domain_get_vcpus_flags_ret (XDR *xdrs, remote_domain_get_vcpus_flags_ret *objp)
 | 
			
		||||
+{
 | 
			
		||||
+
 | 
			
		||||
+         if (!xdr_int (xdrs, &objp->num))
 | 
			
		||||
+                 return FALSE;
 | 
			
		||||
+        return TRUE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool_t
 | 
			
		||||
 xdr_remote_domain_pin_vcpu_args (XDR *xdrs, remote_domain_pin_vcpu_args *objp)
 | 
			
		||||
 {
 | 
			
		||||
         char **objp_cpp0 = (char **) (void *) &objp->cpumap.cpumap_val;
 | 
			
		||||
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
 | 
			
		||||
index 756da11..d75e76c 100644
 | 
			
		||||
--- a/src/remote/remote_protocol.h
 | 
			
		||||
+++ b/src/remote/remote_protocol.h
 | 
			
		||||
@@ -750,6 +750,24 @@ struct remote_domain_set_vcpus_args {
 | 
			
		||||
 };
 | 
			
		||||
 typedef struct remote_domain_set_vcpus_args remote_domain_set_vcpus_args;
 | 
			
		||||
 | 
			
		||||
+struct remote_domain_set_vcpus_flags_args {
 | 
			
		||||
+        remote_nonnull_domain dom;
 | 
			
		||||
+        u_int nvcpus;
 | 
			
		||||
+        u_int flags;
 | 
			
		||||
+};
 | 
			
		||||
+typedef struct remote_domain_set_vcpus_flags_args remote_domain_set_vcpus_flags_args;
 | 
			
		||||
+
 | 
			
		||||
+struct remote_domain_get_vcpus_flags_args {
 | 
			
		||||
+        remote_nonnull_domain dom;
 | 
			
		||||
+        u_int flags;
 | 
			
		||||
+};
 | 
			
		||||
+typedef struct remote_domain_get_vcpus_flags_args remote_domain_get_vcpus_flags_args;
 | 
			
		||||
+
 | 
			
		||||
+struct remote_domain_get_vcpus_flags_ret {
 | 
			
		||||
+        int num;
 | 
			
		||||
+};
 | 
			
		||||
+typedef struct remote_domain_get_vcpus_flags_ret remote_domain_get_vcpus_flags_ret;
 | 
			
		||||
+
 | 
			
		||||
 struct remote_domain_pin_vcpu_args {
 | 
			
		||||
         remote_nonnull_domain dom;
 | 
			
		||||
         int vcpu;
 | 
			
		||||
@@ -2281,6 +2299,8 @@ enum remote_procedure {
 | 
			
		||||
         REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS = 196,
 | 
			
		||||
         REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
 | 
			
		||||
         REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
 | 
			
		||||
+        REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
 | 
			
		||||
+        REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200,
 | 
			
		||||
 };
 | 
			
		||||
 typedef enum remote_procedure remote_procedure;
 | 
			
		||||
 | 
			
		||||
@@ -2422,6 +2442,9 @@ extern  bool_t xdr_remote_domain_define_xml_args (XDR *, remote_domain_define_xm
 | 
			
		||||
 extern  bool_t xdr_remote_domain_define_xml_ret (XDR *, remote_domain_define_xml_ret*);
 | 
			
		||||
 extern  bool_t xdr_remote_domain_undefine_args (XDR *, remote_domain_undefine_args*);
 | 
			
		||||
 extern  bool_t xdr_remote_domain_set_vcpus_args (XDR *, remote_domain_set_vcpus_args*);
 | 
			
		||||
+extern  bool_t xdr_remote_domain_set_vcpus_flags_args (XDR *, remote_domain_set_vcpus_flags_args*);
 | 
			
		||||
+extern  bool_t xdr_remote_domain_get_vcpus_flags_args (XDR *, remote_domain_get_vcpus_flags_args*);
 | 
			
		||||
+extern  bool_t xdr_remote_domain_get_vcpus_flags_ret (XDR *, remote_domain_get_vcpus_flags_ret*);
 | 
			
		||||
 extern  bool_t xdr_remote_domain_pin_vcpu_args (XDR *, remote_domain_pin_vcpu_args*);
 | 
			
		||||
 extern  bool_t xdr_remote_domain_get_vcpus_args (XDR *, remote_domain_get_vcpus_args*);
 | 
			
		||||
 extern  bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*);
 | 
			
		||||
@@ -2762,6 +2785,9 @@ extern bool_t xdr_remote_domain_define_xml_args ();
 | 
			
		||||
 extern bool_t xdr_remote_domain_define_xml_ret ();
 | 
			
		||||
 extern bool_t xdr_remote_domain_undefine_args ();
 | 
			
		||||
 extern bool_t xdr_remote_domain_set_vcpus_args ();
 | 
			
		||||
+extern bool_t xdr_remote_domain_set_vcpus_flags_args ();
 | 
			
		||||
+extern bool_t xdr_remote_domain_get_vcpus_flags_args ();
 | 
			
		||||
+extern bool_t xdr_remote_domain_get_vcpus_flags_ret ();
 | 
			
		||||
 extern bool_t xdr_remote_domain_pin_vcpu_args ();
 | 
			
		||||
 extern bool_t xdr_remote_domain_get_vcpus_args ();
 | 
			
		||||
 extern bool_t xdr_remote_domain_get_vcpus_ret ();
 | 
			
		||||
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
 | 
			
		||||
index e80fb5f..d57e6d0 100644
 | 
			
		||||
--- a/src/remote/remote_protocol.x
 | 
			
		||||
+++ b/src/remote/remote_protocol.x
 | 
			
		||||
@@ -768,6 +768,21 @@ struct remote_domain_set_vcpus_args {
 | 
			
		||||
     int nvcpus;
 | 
			
		||||
 };
 | 
			
		||||
 | 
			
		||||
+struct remote_domain_set_vcpus_flags_args {
 | 
			
		||||
+    remote_nonnull_domain dom;
 | 
			
		||||
+    unsigned int nvcpus;
 | 
			
		||||
+    unsigned int flags;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct remote_domain_get_vcpus_flags_args {
 | 
			
		||||
+    remote_nonnull_domain dom;
 | 
			
		||||
+    unsigned int flags;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct remote_domain_get_vcpus_flags_ret {
 | 
			
		||||
+    int num;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 struct remote_domain_pin_vcpu_args {
 | 
			
		||||
     remote_nonnull_domain dom;
 | 
			
		||||
     int vcpu;
 | 
			
		||||
@@ -2062,7 +2077,9 @@ enum remote_procedure {
 | 
			
		||||
     REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON = 195,
 | 
			
		||||
     REMOTE_PROC_DOMAIN_CREATE_WITH_FLAGS = 196,
 | 
			
		||||
     REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
 | 
			
		||||
-    REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198
 | 
			
		||||
+    REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
 | 
			
		||||
+    REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
 | 
			
		||||
+    REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200
 | 
			
		||||
 | 
			
		||||
     /*
 | 
			
		||||
      * Notice how the entries are grouped in sets of 10 ?
 | 
			
		||||
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
 | 
			
		||||
index 838423e..d505886 100644
 | 
			
		||||
--- a/src/remote_protocol-structs
 | 
			
		||||
+++ b/src/remote_protocol-structs
 | 
			
		||||
@@ -461,6 +461,18 @@ struct remote_domain_set_vcpus_args {
 | 
			
		||||
 	remote_nonnull_domain      dom;
 | 
			
		||||
 	int                        nvcpus;
 | 
			
		||||
 };
 | 
			
		||||
+struct remote_domain_set_vcpus_flags_args {
 | 
			
		||||
+	remote_nonnull_domain      dom;
 | 
			
		||||
+	u_int                      nvcpus;
 | 
			
		||||
+	u_int                      flags;
 | 
			
		||||
+};
 | 
			
		||||
+struct remote_domain_get_vcpus_flags_args {
 | 
			
		||||
+	remote_nonnull_domain      dom;
 | 
			
		||||
+	u_int                      flags;
 | 
			
		||||
+};
 | 
			
		||||
+struct remote_domain_get_vcpus_flags_ret {
 | 
			
		||||
+	int                        num;
 | 
			
		||||
+};
 | 
			
		||||
 struct remote_domain_pin_vcpu_args {
 | 
			
		||||
 	remote_nonnull_domain      dom;
 | 
			
		||||
 	int                        vcpu;
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,735 @@
 | 
			
		||||
From 50c51f13e2af04afac46e181c4ed62581545a488 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Mon, 27 Sep 2010 16:37:53 -0600
 | 
			
		||||
Subject: [PATCH 06/15] vcpu: make old API trivially wrap to new API
 | 
			
		||||
 | 
			
		||||
Note - this wrapping is completely mechanical; the old API will
 | 
			
		||||
function identically, since the new API validates that the exact
 | 
			
		||||
same flags are provided by the old API.  On a per-driver basis,
 | 
			
		||||
it may make sense to have the old API pass a different set of flags,
 | 
			
		||||
but that should be done in the per-driver patch that implements
 | 
			
		||||
the full range of flag support in the new API.
 | 
			
		||||
 | 
			
		||||
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
 | 
			
		||||
Move guts...
 | 
			
		||||
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
 | 
			
		||||
functions.
 | 
			
		||||
(esxDriver): Trivially support the new API.
 | 
			
		||||
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
 | 
			
		||||
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
 | 
			
		||||
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
 | 
			
		||||
* src/phyp/phyp_driver.c (phypDomainSetCPU)
 | 
			
		||||
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
 | 
			
		||||
(phypDomainGetVcpusFlags, phypDriver): Likewise.
 | 
			
		||||
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
 | 
			
		||||
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
 | 
			
		||||
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
 | 
			
		||||
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
 | 
			
		||||
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
 | 
			
		||||
Likewise.
 | 
			
		||||
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
 | 
			
		||||
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
 | 
			
		||||
(virDomainGetVcpusFlags, virDriver): Likewise.
 | 
			
		||||
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
 | 
			
		||||
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
 | 
			
		||||
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
 | 
			
		||||
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
 | 
			
		||||
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
 | 
			
		||||
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
 | 
			
		||||
(xenapiError): New helper macro.
 | 
			
		||||
---
 | 
			
		||||
 src/esx/esx_driver.c       |   32 +++++++++++++++++++---
 | 
			
		||||
 src/openvz/openvz_driver.c |   34 +++++++++++++++++++++---
 | 
			
		||||
 src/phyp/phyp_driver.c     |   32 ++++++++++++++++++++---
 | 
			
		||||
 src/qemu/qemu_driver.c     |   38 +++++++++++++++++++++++++---
 | 
			
		||||
 src/test/test_driver.c     |   36 ++++++++++++++++++++++---
 | 
			
		||||
 src/vbox/vbox_tmpl.c       |   36 +++++++++++++++++++++++---
 | 
			
		||||
 src/xen/xen_driver.c       |   34 ++++++++++++++++++++++---
 | 
			
		||||
 src/xenapi/xenapi_driver.c |   60 ++++++++++++++++++++++++++++++++++++++------
 | 
			
		||||
 8 files changed, 263 insertions(+), 39 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
 | 
			
		||||
index 2a32374..b3e1284 100644
 | 
			
		||||
--- a/src/esx/esx_driver.c
 | 
			
		||||
+++ b/src/esx/esx_driver.c
 | 
			
		||||
@@ -2384,7 +2384,8 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
-esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 | 
			
		||||
+esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
 | 
			
		||||
+                       unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     int result = -1;
 | 
			
		||||
     esxPrivate *priv = domain->conn->privateData;
 | 
			
		||||
@@ -2394,6 +2395,11 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 | 
			
		||||
     esxVI_ManagedObjectReference *task = NULL;
 | 
			
		||||
     esxVI_TaskInfoState taskInfoState;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if (nvcpus < 1) {
 | 
			
		||||
         ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
 | 
			
		||||
                   _("Requested number of virtual CPUs must at least be 1"));
 | 
			
		||||
@@ -2453,15 +2459,26 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return esxDomainSetVcpusFlags(domain, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
-esxDomainGetMaxVcpus(virDomainPtr domain)
 | 
			
		||||
+esxDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     esxPrivate *priv = domain->conn->privateData;
 | 
			
		||||
     esxVI_String *propertyNameList = NULL;
 | 
			
		||||
     esxVI_ObjectContent *hostSystem = NULL;
 | 
			
		||||
     esxVI_DynamicProperty *dynamicProperty = NULL;
 | 
			
		||||
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if (priv->maxVcpus > 0) {
 | 
			
		||||
         return priv->maxVcpus;
 | 
			
		||||
     }
 | 
			
		||||
@@ -2507,7 +2524,12 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
 | 
			
		||||
     return priv->maxVcpus;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-
 | 
			
		||||
+static int
 | 
			
		||||
+esxDomainGetMaxVcpus(virDomainPtr domain)
 | 
			
		||||
+{
 | 
			
		||||
+    return esxDomainGetVcpusFlags(domain, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                           VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
 | 
			
		||||
 static char *
 | 
			
		||||
 esxDomainDumpXML(virDomainPtr domain, int flags)
 | 
			
		||||
@@ -4160,8 +4182,8 @@ static virDriver esxDriver = {
 | 
			
		||||
     NULL,                            /* domainRestore */
 | 
			
		||||
     NULL,                            /* domainCoreDump */
 | 
			
		||||
     esxDomainSetVcpus,               /* domainSetVcpus */
 | 
			
		||||
-    NULL,                            /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL,                            /* domainGetVcpusFlags */
 | 
			
		||||
+    esxDomainSetVcpusFlags,          /* domainSetVcpusFlags */
 | 
			
		||||
+    esxDomainGetVcpusFlags,          /* domainGetVcpusFlags */
 | 
			
		||||
     NULL,                            /* domainPinVcpu */
 | 
			
		||||
     NULL,                            /* domainGetVcpus */
 | 
			
		||||
     esxDomainGetMaxVcpus,            /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
 | 
			
		||||
index 9d19aeb..0f3cfdf 100644
 | 
			
		||||
--- a/src/openvz/openvz_driver.c
 | 
			
		||||
+++ b/src/openvz/openvz_driver.c
 | 
			
		||||
@@ -67,7 +67,6 @@
 | 
			
		||||
 static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid);
 | 
			
		||||
 static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
 | 
			
		||||
 static int openvzDomainGetMaxVcpus(virDomainPtr dom);
 | 
			
		||||
-static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus);
 | 
			
		||||
 static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
 | 
			
		||||
                                         unsigned int nvcpus);
 | 
			
		||||
 static int openvzDomainSetMemoryInternal(virDomainObjPtr vm,
 | 
			
		||||
@@ -1211,11 +1210,24 @@ static int openvzGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
 | 
			
		||||
     return -1;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+openvzDomainGetVcpusFlags(virDomainPtr dom ATTRIBUTE_UNUSED,
 | 
			
		||||
+                          unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        openvzError(VIR_ERR_INVALID_ARG, _("unsupported flags (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
 | 
			
		||||
-static int openvzDomainGetMaxVcpus(virDomainPtr dom ATTRIBUTE_UNUSED) {
 | 
			
		||||
     return openvzGetMaxVCPUs(NULL, "openvz");
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int openvzDomainGetMaxVcpus(virDomainPtr dom)
 | 
			
		||||
+{
 | 
			
		||||
+    return openvzDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                           VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
 | 
			
		||||
                                         unsigned int nvcpus)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1241,12 +1253,18 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
 | 
			
		||||
     return 0;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+static int openvzDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
+                                     unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     virDomainObjPtr         vm;
 | 
			
		||||
     struct openvz_driver   *driver = dom->conn->privateData;
 | 
			
		||||
     int                     ret = -1;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        openvzError(VIR_ERR_INVALID_ARG, _("unsupported flags (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     openvzDriverLock(driver);
 | 
			
		||||
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
 | 
			
		||||
     openvzDriverUnlock(driver);
 | 
			
		||||
@@ -1272,6 +1290,12 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return openvzDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static virDrvOpenStatus openvzOpen(virConnectPtr conn,
 | 
			
		||||
                                    virConnectAuthPtr auth ATTRIBUTE_UNUSED,
 | 
			
		||||
                                    int flags ATTRIBUTE_UNUSED)
 | 
			
		||||
@@ -1590,8 +1614,8 @@ static virDriver openvzDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     openvzDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    openvzDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    openvzDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
 | 
			
		||||
index 6e0a5e9..e284ae0 100644
 | 
			
		||||
--- a/src/phyp/phyp_driver.c
 | 
			
		||||
+++ b/src/phyp/phyp_driver.c
 | 
			
		||||
@@ -1497,15 +1497,27 @@ phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
-phypGetLparCPUMAX(virDomainPtr dom)
 | 
			
		||||
+phypDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     phyp_driverPtr phyp_driver = dom->conn->privateData;
 | 
			
		||||
     char *managed_system = phyp_driver->managed_system;
 | 
			
		||||
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        PHYP_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1);
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
+phypGetLparCPUMAX(virDomainPtr dom)
 | 
			
		||||
+{
 | 
			
		||||
+    return phypDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                         VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
 phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
 | 
			
		||||
                   const char *lpar_name)
 | 
			
		||||
 {
 | 
			
		||||
@@ -3831,7 +3843,8 @@ phypConnectGetCapabilities(virConnectPtr conn)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
-phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+phypDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
+                        unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     ConnectionData *connection_data = dom->conn->networkPrivateData;
 | 
			
		||||
     phyp_driverPtr phyp_driver = dom->conn->privateData;
 | 
			
		||||
@@ -3846,6 +3859,11 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
     unsigned int amount = 0;
 | 
			
		||||
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        PHYP_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
 | 
			
		||||
         return 0;
 | 
			
		||||
 | 
			
		||||
@@ -3891,6 +3909,12 @@ phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return phypDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static virDrvOpenStatus
 | 
			
		||||
 phypVIOSDriverOpen(virConnectPtr conn,
 | 
			
		||||
                    virConnectAuthPtr auth ATTRIBUTE_UNUSED,
 | 
			
		||||
@@ -3941,8 +3965,8 @@ static virDriver phypDriver = {
 | 
			
		||||
     NULL,                       /* domainRestore */
 | 
			
		||||
     NULL,                       /* domainCoreDump */
 | 
			
		||||
     phypDomainSetCPU,           /* domainSetVcpus */
 | 
			
		||||
-    NULL,                       /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL,                       /* domainGetVcpusFlags */
 | 
			
		||||
+    phypDomainSetVcpusFlags,    /* domainSetVcpusFlags */
 | 
			
		||||
+    phypDomainGetVcpusFlags,    /* domainGetVcpusFlags */
 | 
			
		||||
     NULL,                       /* domainPinVcpu */
 | 
			
		||||
     NULL,                       /* domainGetVcpus */
 | 
			
		||||
     phypGetLparCPUMAX,          /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 | 
			
		||||
index 3d17e04..7a2ea8f 100644
 | 
			
		||||
--- a/src/qemu/qemu_driver.c
 | 
			
		||||
+++ b/src/qemu/qemu_driver.c
 | 
			
		||||
@@ -5934,13 +5934,22 @@ unsupported:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
 | 
			
		||||
+static int
 | 
			
		||||
+qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
+                         unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
     struct qemud_driver *driver = dom->conn->privateData;
 | 
			
		||||
     virDomainObjPtr vm;
 | 
			
		||||
     const char * type;
 | 
			
		||||
     int max;
 | 
			
		||||
     int ret = -1;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
+                        flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     qemuDriverLock(driver);
 | 
			
		||||
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
 | 
			
		||||
     qemuDriverUnlock(driver);
 | 
			
		||||
@@ -5994,6 +6003,12 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return qemudDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
 qemudDomainPinVcpu(virDomainPtr dom,
 | 
			
		||||
@@ -6150,12 +6165,20 @@ cleanup:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-static int qemudDomainGetMaxVcpus(virDomainPtr dom) {
 | 
			
		||||
+static int
 | 
			
		||||
+qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
     struct qemud_driver *driver = dom->conn->privateData;
 | 
			
		||||
     virDomainObjPtr vm;
 | 
			
		||||
     const char *type;
 | 
			
		||||
     int ret = -1;
 | 
			
		||||
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
+                        flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     qemuDriverLock(driver);
 | 
			
		||||
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
 | 
			
		||||
     qemuDriverUnlock(driver);
 | 
			
		||||
@@ -6183,6 +6206,13 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+qemudDomainGetMaxVcpus(virDomainPtr dom)
 | 
			
		||||
+{
 | 
			
		||||
+    return qemudDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                          VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel)
 | 
			
		||||
 {
 | 
			
		||||
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
 | 
			
		||||
@@ -12938,8 +12968,8 @@ static virDriver qemuDriver = {
 | 
			
		||||
     qemudDomainRestore, /* domainRestore */
 | 
			
		||||
     qemudDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     qemudDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     qemudDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     qemudDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
 | 
			
		||||
index 6a00558..b70c80d 100644
 | 
			
		||||
--- a/src/test/test_driver.c
 | 
			
		||||
+++ b/src/test/test_driver.c
 | 
			
		||||
@@ -2029,17 +2029,37 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-static int testDomainGetMaxVcpus(virDomainPtr domain)
 | 
			
		||||
+static int
 | 
			
		||||
+testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     return testGetMaxVCPUs(domain->conn, "test");
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-static int testSetVcpus(virDomainPtr domain,
 | 
			
		||||
-                        unsigned int nrCpus) {
 | 
			
		||||
+static int
 | 
			
		||||
+testDomainGetMaxVcpus(virDomainPtr domain)
 | 
			
		||||
+{
 | 
			
		||||
+    return testDomainGetVcpusFlags(domain, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                            VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
+testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
 | 
			
		||||
+                        unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
     testConnPtr privconn = domain->conn->privateData;
 | 
			
		||||
     virDomainObjPtr privdom = NULL;
 | 
			
		||||
     int ret = -1, maxvcpus;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     /* Do this first before locking */
 | 
			
		||||
     maxvcpus = testDomainGetMaxVcpus(domain);
 | 
			
		||||
     if (maxvcpus < 0)
 | 
			
		||||
@@ -2082,6 +2102,12 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+testSetVcpus(virDomainPtr domain, unsigned int nrCpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return testDomainSetVcpusFlags(domain, nrCpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int testDomainGetVcpus(virDomainPtr domain,
 | 
			
		||||
                               virVcpuInfoPtr info,
 | 
			
		||||
                               int maxinfo,
 | 
			
		||||
@@ -5260,8 +5286,8 @@ static virDriver testDriver = {
 | 
			
		||||
     testDomainRestore, /* domainRestore */
 | 
			
		||||
     testDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     testSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    testDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    testDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     testDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     testDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     testDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
 | 
			
		||||
index cb9193a..0cbe8b3 100644
 | 
			
		||||
--- a/src/vbox/vbox_tmpl.c
 | 
			
		||||
+++ b/src/vbox/vbox_tmpl.c
 | 
			
		||||
@@ -1839,13 +1839,21 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-static int vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
 | 
			
		||||
+static int
 | 
			
		||||
+vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
+                        unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
     VBOX_OBJECT_CHECK(dom->conn, int, -1);
 | 
			
		||||
     IMachine *machine    = NULL;
 | 
			
		||||
     vboxIID  *iid        = NULL;
 | 
			
		||||
     PRUint32  CPUCount   = nvcpus;
 | 
			
		||||
     nsresult rc;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        vboxError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
 #if VBOX_API_VERSION == 2002
 | 
			
		||||
     if (VIR_ALLOC(iid) < 0) {
 | 
			
		||||
         virReportOOMError();
 | 
			
		||||
@@ -1887,11 +1895,24 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-static int vboxDomainGetMaxVcpus(virDomainPtr dom) {
 | 
			
		||||
+static int
 | 
			
		||||
+vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return vboxDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
+vboxDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
     VBOX_OBJECT_CHECK(dom->conn, int, -1);
 | 
			
		||||
     ISystemProperties *systemProperties = NULL;
 | 
			
		||||
     PRUint32 maxCPUCount = 0;
 | 
			
		||||
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        vboxError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     /* Currently every domain supports the same number of max cpus
 | 
			
		||||
      * as that supported by vbox and thus take it directly from
 | 
			
		||||
      * the systemproperties.
 | 
			
		||||
@@ -1909,6 +1930,13 @@ static int vboxDomainGetMaxVcpus(virDomainPtr dom) {
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+vboxDomainGetMaxVcpus(virDomainPtr dom)
 | 
			
		||||
+{
 | 
			
		||||
+    return vboxDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                         VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
 | 
			
		||||
     VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
 | 
			
		||||
     virDomainDefPtr def  = NULL;
 | 
			
		||||
@@ -8267,8 +8295,8 @@ virDriver NAME(Driver) = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     vboxDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    vboxDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    vboxDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
     vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
 | 
			
		||||
index 7d67ced..d6c9c57 100644
 | 
			
		||||
--- a/src/xen/xen_driver.c
 | 
			
		||||
+++ b/src/xen/xen_driver.c
 | 
			
		||||
@@ -1069,11 +1069,18 @@ xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
-xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
+                               unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     GET_PRIVATE(dom->conn);
 | 
			
		||||
     int i;
 | 
			
		||||
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
+                        flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     /* Try non-hypervisor methods first, then hypervisor direct method
 | 
			
		||||
      * as a last resort.
 | 
			
		||||
      */
 | 
			
		||||
@@ -1093,6 +1100,12 @@ xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
+xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
 xenUnifiedDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
 | 
			
		||||
                          unsigned char *cpumap, int maplen)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1126,11 +1139,17 @@ xenUnifiedDomainGetVcpus (virDomainPtr dom,
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
-xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
 | 
			
		||||
+xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     GET_PRIVATE(dom->conn);
 | 
			
		||||
     int i, ret;
 | 
			
		||||
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
+                        flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
 | 
			
		||||
         if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
 | 
			
		||||
             ret = drivers[i]->domainGetMaxVcpus (dom);
 | 
			
		||||
@@ -1140,6 +1159,13 @@ xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
 | 
			
		||||
     return -1;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+static int
 | 
			
		||||
+xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
 | 
			
		||||
+{
 | 
			
		||||
+    return xenUnifiedDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                               VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static char *
 | 
			
		||||
 xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1951,8 +1977,8 @@ static virDriver xenUnifiedDriver = {
 | 
			
		||||
     xenUnifiedDomainRestore, /* domainRestore */
 | 
			
		||||
     xenUnifiedDomainCoreDump, /* domainCoreDump */
 | 
			
		||||
     xenUnifiedDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    xenUnifiedDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    xenUnifiedDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     xenUnifiedDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     xenUnifiedDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
 | 
			
		||||
index 753169c..7d4ab8d 100644
 | 
			
		||||
--- a/src/xenapi/xenapi_driver.c
 | 
			
		||||
+++ b/src/xenapi/xenapi_driver.c
 | 
			
		||||
@@ -40,6 +40,11 @@
 | 
			
		||||
 #include "xenapi_driver_private.h"
 | 
			
		||||
 #include "xenapi_utils.h"
 | 
			
		||||
 | 
			
		||||
+#define VIR_FROM_THIS VIR_FROM_XENAPI
 | 
			
		||||
+
 | 
			
		||||
+#define xenapiError(code, ...)                                    \
 | 
			
		||||
+        virReportErrorHelper(NULL, VIR_FROM_THIS, code, __FILE__, \
 | 
			
		||||
+                             __FUNCTION__, __LINE__, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
  * getCapsObject
 | 
			
		||||
@@ -987,19 +992,26 @@ xenapiDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
- * xenapiDomainSetVcpus
 | 
			
		||||
+ * xenapiDomainSetVcpusFlags
 | 
			
		||||
  *
 | 
			
		||||
  * Sets the VCPUs on the domain
 | 
			
		||||
  * Return 0 on success or -1 in case of error
 | 
			
		||||
  */
 | 
			
		||||
 static int
 | 
			
		||||
-xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+xenapiDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
+                           unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
-
 | 
			
		||||
     /* vm.set_vcpus_max */
 | 
			
		||||
     xen_vm vm;
 | 
			
		||||
     xen_vm_set *vms;
 | 
			
		||||
     xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
 | 
			
		||||
+
 | 
			
		||||
+    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        xenapiError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
+                    flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
 | 
			
		||||
         if (vms->size != 1) {
 | 
			
		||||
             xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
@@ -1019,6 +1031,18 @@ xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
+ * xenapiDomainSetVcpus
 | 
			
		||||
+ *
 | 
			
		||||
+ * Sets the VCPUs on the domain
 | 
			
		||||
+ * Return 0 on success or -1 in case of error
 | 
			
		||||
+ */
 | 
			
		||||
+static int
 | 
			
		||||
+xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
+{
 | 
			
		||||
+    return xenapiDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
  * xenapiDomainPinVcpu
 | 
			
		||||
  *
 | 
			
		||||
  * Dynamically change the real CPUs which can be allocated to a virtual CPU
 | 
			
		||||
@@ -1140,19 +1164,26 @@ xenapiDomainGetVcpus (virDomainPtr dom,
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
- * xenapiDomainGetMaxVcpus
 | 
			
		||||
+ * xenapiDomainGetVcpusFlags
 | 
			
		||||
  *
 | 
			
		||||
  *
 | 
			
		||||
- * Returns maximum number of Vcpus on success or -1 in case of error
 | 
			
		||||
+ * Returns Vcpus count on success or -1 in case of error
 | 
			
		||||
  */
 | 
			
		||||
 static int
 | 
			
		||||
-xenapiDomainGetMaxVcpus (virDomainPtr dom)
 | 
			
		||||
+xenapiDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     xen_vm vm;
 | 
			
		||||
     xen_vm_set *vms;
 | 
			
		||||
     int64_t maxvcpu = 0;
 | 
			
		||||
     enum xen_vm_power_state state;
 | 
			
		||||
     xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
 | 
			
		||||
+
 | 
			
		||||
+    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        xenapiError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
+                    flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
 | 
			
		||||
         if (vms->size != 1) {
 | 
			
		||||
             xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
@@ -1176,6 +1207,19 @@ xenapiDomainGetMaxVcpus (virDomainPtr dom)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
+ * xenapiDomainGetMaxVcpus
 | 
			
		||||
+ *
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns maximum number of Vcpus on success or -1 in case of error
 | 
			
		||||
+ */
 | 
			
		||||
+static int
 | 
			
		||||
+xenapiDomainGetMaxVcpus (virDomainPtr dom)
 | 
			
		||||
+{
 | 
			
		||||
+    return xenapiDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                                           VIR_DOMAIN_VCPU_MAXIMUM));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
  * xenapiDomainDumpXML
 | 
			
		||||
  *
 | 
			
		||||
  *
 | 
			
		||||
@@ -1754,8 +1798,8 @@ static virDriver xenapiDriver = {
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
     xenapiDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
-    NULL, /* domainSetVcpusFlags */
 | 
			
		||||
-    NULL, /* domainGetVcpusFlags */
 | 
			
		||||
+    xenapiDomainSetVcpusFlags, /* domainSetVcpusFlags */
 | 
			
		||||
+    xenapiDomainGetVcpusFlags, /* domainGetVcpusFlags */
 | 
			
		||||
     xenapiDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     xenapiDomainGetVcpus, /* domainGetVcpus */
 | 
			
		||||
     xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										388
									
								
								docs/api_extension/0007-add-virsh-support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								docs/api_extension/0007-add-virsh-support.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,388 @@
 | 
			
		||||
From bf945ee97b72d3b0c4fc2da04530f5294f529d66 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Wed, 29 Sep 2010 15:20:23 -0600
 | 
			
		||||
Subject: [PATCH 08/15] vcpu: add virsh support
 | 
			
		||||
 | 
			
		||||
* tools/virsh.c (cmdSetvcpus): Add new flags.  Let invalid
 | 
			
		||||
commands through to driver, to ease testing of hypervisor argument
 | 
			
		||||
validation.
 | 
			
		||||
(cmdMaxvcpus, cmdVcpucount): New commands.
 | 
			
		||||
(commands): Add new commands.
 | 
			
		||||
* tools/virsh.pod (setvcpus, vcpucount, maxvcpus): Document new
 | 
			
		||||
behavior.
 | 
			
		||||
---
 | 
			
		||||
 tools/virsh.c   |  247 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 | 
			
		||||
 tools/virsh.pod |   38 ++++++++-
 | 
			
		||||
 2 files changed, 262 insertions(+), 23 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/tools/virsh.c b/tools/virsh.c
 | 
			
		||||
index 4f8c495..7fb7fbd 100644
 | 
			
		||||
--- a/tools/virsh.c
 | 
			
		||||
+++ b/tools/virsh.c
 | 
			
		||||
@@ -2281,10 +2281,216 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd)
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
+ * "maxvcpus" command
 | 
			
		||||
+ */
 | 
			
		||||
+static const vshCmdInfo info_maxvcpus[] = {
 | 
			
		||||
+    {"help", N_("connection vcpu maximum")},
 | 
			
		||||
+    {"desc", N_("Show maximum number of virtual CPUs for guests on this connection.")},
 | 
			
		||||
+    {NULL, NULL}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const vshCmdOptDef opts_maxvcpus[] = {
 | 
			
		||||
+    {"type", VSH_OT_STRING, 0, N_("domain type")},
 | 
			
		||||
+    {NULL, 0, 0, NULL}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
+cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd)
 | 
			
		||||
+{
 | 
			
		||||
+    char *type;
 | 
			
		||||
+    int vcpus;
 | 
			
		||||
+
 | 
			
		||||
+    type = vshCommandOptString(cmd, "type", NULL);
 | 
			
		||||
+
 | 
			
		||||
+    if (!vshConnectionUsability(ctl, ctl->conn))
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+
 | 
			
		||||
+    vcpus = virConnectGetMaxVcpus(ctl->conn, type);
 | 
			
		||||
+    if (vcpus < 0)
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+    vshPrint(ctl, "%d\n", vcpus);
 | 
			
		||||
+
 | 
			
		||||
+    return TRUE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * "vcpucount" command
 | 
			
		||||
+ */
 | 
			
		||||
+static const vshCmdInfo info_vcpucount[] = {
 | 
			
		||||
+    {"help", N_("domain vcpu counts")},
 | 
			
		||||
+    {"desc", N_("Returns the number of virtual CPUs used by the domain.")},
 | 
			
		||||
+    {NULL, NULL}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const vshCmdOptDef opts_vcpucount[] = {
 | 
			
		||||
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
 | 
			
		||||
+    {"maximum", VSH_OT_BOOL, 0, N_("get maximum cap on vcpus")},
 | 
			
		||||
+    {"current", VSH_OT_BOOL, 0, N_("get current vcpu usage")},
 | 
			
		||||
+    {"config", VSH_OT_BOOL, 0, N_("get value to be used on next boot")},
 | 
			
		||||
+    {"live", VSH_OT_BOOL, 0, N_("get value from running domain")},
 | 
			
		||||
+    {NULL, 0, 0, NULL}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static int
 | 
			
		||||
+cmdVcpucount(vshControl *ctl, const vshCmd *cmd)
 | 
			
		||||
+{
 | 
			
		||||
+    virDomainPtr dom;
 | 
			
		||||
+    int ret = TRUE;
 | 
			
		||||
+    int maximum = vshCommandOptBool(cmd, "maximum");
 | 
			
		||||
+    int current = vshCommandOptBool(cmd, "current");
 | 
			
		||||
+    int config = vshCommandOptBool(cmd, "config");
 | 
			
		||||
+    int live = vshCommandOptBool(cmd, "live");
 | 
			
		||||
+    bool all = maximum + current + config + live == 0;
 | 
			
		||||
+    int count;
 | 
			
		||||
+
 | 
			
		||||
+    if (maximum && current) {
 | 
			
		||||
+        vshError(ctl, "%s",
 | 
			
		||||
+                 _("--maximum and --current cannot both be specified"));
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (config && live) {
 | 
			
		||||
+        vshError(ctl, "%s",
 | 
			
		||||
+                 _("--config and --live cannot both be specified"));
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+    }
 | 
			
		||||
+    /* We want one of each pair of mutually exclusive options; that
 | 
			
		||||
+     * is, use of flags requires exactly two options.  */
 | 
			
		||||
+    if (maximum + current + config + live == 1) {
 | 
			
		||||
+        vshError(ctl,
 | 
			
		||||
+                 _("when using --%s, either --%s or --%s must be specified"),
 | 
			
		||||
+                 (maximum ? "maximum" : current ? "current"
 | 
			
		||||
+                  : config ? "config" : "live"),
 | 
			
		||||
+                 maximum + current ? "config" : "maximum",
 | 
			
		||||
+                 maximum + current ? "live" : "current");
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (!vshConnectionUsability(ctl, ctl->conn))
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+
 | 
			
		||||
+    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
 | 
			
		||||
+        return FALSE;
 | 
			
		||||
+
 | 
			
		||||
+    /* In all cases, try the new API first; if it fails because we are
 | 
			
		||||
+     * talking to an older client, try a fallback API before giving
 | 
			
		||||
+     * up.  */
 | 
			
		||||
+    if (all || (maximum && config)) {
 | 
			
		||||
+        count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
 | 
			
		||||
+                                             VIR_DOMAIN_VCPU_CONFIG));
 | 
			
		||||
+        if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
 | 
			
		||||
+                          || last_error->code == VIR_ERR_INVALID_ARG)) {
 | 
			
		||||
+            char *tmp;
 | 
			
		||||
+            char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
 | 
			
		||||
+            if (xml && (tmp = strstr(xml, "<vcpu"))) {
 | 
			
		||||
+                tmp = strchr(tmp, '>');
 | 
			
		||||
+                if (!tmp || virStrToLong_i(tmp + 1, &tmp, 10, &count) < 0)
 | 
			
		||||
+                    count = -1;
 | 
			
		||||
+            }
 | 
			
		||||
+            VIR_FREE(xml);
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+        if (count < 0) {
 | 
			
		||||
+            virshReportError(ctl);
 | 
			
		||||
+            ret = FALSE;
 | 
			
		||||
+        } else if (all) {
 | 
			
		||||
+            vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("config"),
 | 
			
		||||
+                     count);
 | 
			
		||||
+        } else {
 | 
			
		||||
+            vshPrint(ctl, "%d\n", count);
 | 
			
		||||
+        }
 | 
			
		||||
+        virFreeError(last_error);
 | 
			
		||||
+        last_error = NULL;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (all || (maximum && live)) {
 | 
			
		||||
+        count = virDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_MAXIMUM |
 | 
			
		||||
+                                             VIR_DOMAIN_VCPU_LIVE));
 | 
			
		||||
+        if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
 | 
			
		||||
+                          || last_error->code == VIR_ERR_INVALID_ARG)) {
 | 
			
		||||
+            count = virDomainGetMaxVcpus(dom);
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+        if (count < 0) {
 | 
			
		||||
+            virshReportError(ctl);
 | 
			
		||||
+            ret = FALSE;
 | 
			
		||||
+        } else if (all) {
 | 
			
		||||
+            vshPrint(ctl, "%-12s %-12s %3d\n", _("maximum"), _("live"),
 | 
			
		||||
+                     count);
 | 
			
		||||
+        } else {
 | 
			
		||||
+            vshPrint(ctl, "%d\n", count);
 | 
			
		||||
+        }
 | 
			
		||||
+        virFreeError(last_error);
 | 
			
		||||
+        last_error = NULL;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (all || (current && config)) {
 | 
			
		||||
+        count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_CONFIG);
 | 
			
		||||
+        if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
 | 
			
		||||
+                          || last_error->code == VIR_ERR_INVALID_ARG)) {
 | 
			
		||||
+            char *tmp, *end;
 | 
			
		||||
+            char *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
 | 
			
		||||
+            if (xml && (tmp = strstr(xml, "<vcpu"))) {
 | 
			
		||||
+                end = strchr(tmp, '>');
 | 
			
		||||
+                if (end) {
 | 
			
		||||
+                    *end = '\0';
 | 
			
		||||
+                    tmp = strstr(tmp, "current=");
 | 
			
		||||
+                    if (!tmp)
 | 
			
		||||
+                        tmp = end + 1;
 | 
			
		||||
+                    else {
 | 
			
		||||
+                        tmp += strlen("current=");
 | 
			
		||||
+                        tmp += *tmp == '\'' || *tmp == '"';
 | 
			
		||||
+                    }
 | 
			
		||||
+                }
 | 
			
		||||
+                if (!tmp || virStrToLong_i(tmp, &tmp, 10, &count) < 0)
 | 
			
		||||
+                    count = -1;
 | 
			
		||||
+            }
 | 
			
		||||
+            VIR_FREE(xml);
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+        if (count < 0) {
 | 
			
		||||
+            virshReportError(ctl);
 | 
			
		||||
+            ret = FALSE;
 | 
			
		||||
+        } else if (all) {
 | 
			
		||||
+            vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("config"),
 | 
			
		||||
+                     count);
 | 
			
		||||
+        } else {
 | 
			
		||||
+            vshPrint(ctl, "%d\n", count);
 | 
			
		||||
+        }
 | 
			
		||||
+        virFreeError(last_error);
 | 
			
		||||
+        last_error = NULL;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (all || (current && live)) {
 | 
			
		||||
+        count = virDomainGetVcpusFlags(dom, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+        if (count < 0 && (last_error->code == VIR_ERR_NO_SUPPORT
 | 
			
		||||
+                          || last_error->code == VIR_ERR_INVALID_ARG)) {
 | 
			
		||||
+            virDomainInfo info;
 | 
			
		||||
+            if (virDomainGetInfo(dom, &info) == 0)
 | 
			
		||||
+                count = info.nrVirtCpu;
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+        if (count < 0) {
 | 
			
		||||
+            virshReportError(ctl);
 | 
			
		||||
+            ret = FALSE;
 | 
			
		||||
+        } else if (all) {
 | 
			
		||||
+            vshPrint(ctl, "%-12s %-12s %3d\n", _("current"), _("live"),
 | 
			
		||||
+                     count);
 | 
			
		||||
+        } else {
 | 
			
		||||
+            vshPrint(ctl, "%d\n", count);
 | 
			
		||||
+        }
 | 
			
		||||
+        virFreeError(last_error);
 | 
			
		||||
+        last_error = NULL;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    virDomainFree(dom);
 | 
			
		||||
+    return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
  * "vcpuinfo" command
 | 
			
		||||
  */
 | 
			
		||||
 static const vshCmdInfo info_vcpuinfo[] = {
 | 
			
		||||
-    {"help", N_("domain vcpu information")},
 | 
			
		||||
+    {"help", N_("detailed domain vcpu information")},
 | 
			
		||||
     {"desc", N_("Returns basic information about the domain virtual CPUs.")},
 | 
			
		||||
     {NULL, NULL}
 | 
			
		||||
 };
 | 
			
		||||
@@ -2514,6 +2720,9 @@ static const vshCmdInfo info_setvcpus[] = {
 | 
			
		||||
 static const vshCmdOptDef opts_setvcpus[] = {
 | 
			
		||||
     {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
 | 
			
		||||
     {"count", VSH_OT_DATA, VSH_OFLAG_REQ, N_("number of virtual CPUs")},
 | 
			
		||||
+    {"maximum", VSH_OT_BOOL, 0, N_("set maximum limit on next boot")},
 | 
			
		||||
+    {"config", VSH_OT_BOOL, 0, N_("affect next boot")},
 | 
			
		||||
+    {"live", VSH_OT_BOOL, 0, N_("affect running domain")},
 | 
			
		||||
     {NULL, 0, 0, NULL}
 | 
			
		||||
 };
 | 
			
		||||
 | 
			
		||||
@@ -2522,8 +2731,13 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
 | 
			
		||||
 {
 | 
			
		||||
     virDomainPtr dom;
 | 
			
		||||
     int count;
 | 
			
		||||
-    int maxcpu;
 | 
			
		||||
     int ret = TRUE;
 | 
			
		||||
+    int maximum = vshCommandOptBool(cmd, "maximum");
 | 
			
		||||
+    int config = vshCommandOptBool(cmd, "config");
 | 
			
		||||
+    int live = vshCommandOptBool(cmd, "live");
 | 
			
		||||
+    int flags = ((maximum ? VIR_DOMAIN_VCPU_MAXIMUM : 0) |
 | 
			
		||||
+                 (config ? VIR_DOMAIN_VCPU_CONFIG : 0) |
 | 
			
		||||
+                 (live ? VIR_DOMAIN_VCPU_LIVE : 0));
 | 
			
		||||
 | 
			
		||||
     if (!vshConnectionUsability(ctl, ctl->conn))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
@@ -2532,26 +2746,15 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 | 
			
		||||
     count = vshCommandOptInt(cmd, "count", &count);
 | 
			
		||||
-    if (count <= 0) {
 | 
			
		||||
-        vshError(ctl, "%s", _("Invalid number of virtual CPUs."));
 | 
			
		||||
-        virDomainFree(dom);
 | 
			
		||||
-        return FALSE;
 | 
			
		||||
-    }
 | 
			
		||||
-
 | 
			
		||||
-    maxcpu = virDomainGetMaxVcpus(dom);
 | 
			
		||||
-    if (maxcpu <= 0) {
 | 
			
		||||
-        virDomainFree(dom);
 | 
			
		||||
-        return FALSE;
 | 
			
		||||
-    }
 | 
			
		||||
-
 | 
			
		||||
-    if (count > maxcpu) {
 | 
			
		||||
-        vshError(ctl, "%s", _("Too many virtual CPUs."));
 | 
			
		||||
-        virDomainFree(dom);
 | 
			
		||||
-        return FALSE;
 | 
			
		||||
-    }
 | 
			
		||||
 | 
			
		||||
-    if (virDomainSetVcpus(dom, count) != 0) {
 | 
			
		||||
-        ret = FALSE;
 | 
			
		||||
+    if (!flags) {
 | 
			
		||||
+        if (virDomainSetVcpus(dom, count) != 0) {
 | 
			
		||||
+            ret = FALSE;
 | 
			
		||||
+        }
 | 
			
		||||
+    } else {
 | 
			
		||||
+        if (virDomainSetVcpusFlags(dom, count, flags) < 0) {
 | 
			
		||||
+            ret = FALSE;
 | 
			
		||||
+        }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     virDomainFree(dom);
 | 
			
		||||
@@ -9642,6 +9845,7 @@ static const vshCmdDef commands[] = {
 | 
			
		||||
     {"freecell", cmdFreecell, opts_freecell, info_freecell},
 | 
			
		||||
     {"hostname", cmdHostname, NULL, info_hostname},
 | 
			
		||||
     {"list", cmdList, opts_list, info_list},
 | 
			
		||||
+    {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus},
 | 
			
		||||
     {"migrate", cmdMigrate, opts_migrate, info_migrate},
 | 
			
		||||
     {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime},
 | 
			
		||||
 | 
			
		||||
@@ -9748,6 +9952,7 @@ static const vshCmdDef commands[] = {
 | 
			
		||||
     {"vol-name", cmdVolName, opts_vol_name, info_vol_name},
 | 
			
		||||
     {"vol-key", cmdVolKey, opts_vol_key, info_vol_key},
 | 
			
		||||
 | 
			
		||||
+    {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount},
 | 
			
		||||
     {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
 | 
			
		||||
     {"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
 | 
			
		||||
     {"version", cmdVersion, NULL, info_version},
 | 
			
		||||
diff --git a/tools/virsh.pod b/tools/virsh.pod
 | 
			
		||||
index 943a563..dbcc680 100644
 | 
			
		||||
--- a/tools/virsh.pod
 | 
			
		||||
+++ b/tools/virsh.pod
 | 
			
		||||
@@ -443,7 +443,14 @@ Remove the managed save file for a domain if it exists.  The next time the
 | 
			
		||||
 domain is started it will not restore to its previous state but instead will
 | 
			
		||||
 do a full boot.
 | 
			
		||||
 | 
			
		||||
-=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi> I<migrateuri>
 | 
			
		||||
+=item B<maxvcpus> optional I<type>
 | 
			
		||||
+
 | 
			
		||||
+Provide the maximum number of virtual CPUs supported for a guest VM on
 | 
			
		||||
+this connection.  If provided, the I<type> parameter must be a valid
 | 
			
		||||
+type attribute for the <domain> element of XML.
 | 
			
		||||
+
 | 
			
		||||
+=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi>
 | 
			
		||||
+I<migrateuri>
 | 
			
		||||
 | 
			
		||||
 Migrate domain to another host.  Add --live for live migration; --suspend
 | 
			
		||||
 leaves the domain paused on the destination host. The I<desturi> is the
 | 
			
		||||
@@ -521,7 +528,8 @@ Displays the domain memory parameters.
 | 
			
		||||
 | 
			
		||||
 Allows you to set the domain memory parameters. LXC and QEMU/KVM supports these parameters.
 | 
			
		||||
 | 
			
		||||
-=item B<setvcpus> I<domain-id> I<count>
 | 
			
		||||
+=item B<setvcpus> I<domain-id> I<count> optional I<--maximum> I<--config>
 | 
			
		||||
+I<--live>
 | 
			
		||||
 | 
			
		||||
 Change the number of virtual CPUs active in the guest domain. Note that
 | 
			
		||||
 I<count> may be limited by host, hypervisor or limit coming from the
 | 
			
		||||
@@ -530,6 +538,17 @@ original description of domain.
 | 
			
		||||
 For Xen, you can only adjust the virtual CPUs of a running domain if
 | 
			
		||||
 the domain is paravirtualized.
 | 
			
		||||
 | 
			
		||||
+If I<--config> is specified, the change will only affect the next
 | 
			
		||||
+boot of a domain.  If I<--live> is specified, the domain must be
 | 
			
		||||
+running, and the change takes place immediately.  Both flags may be
 | 
			
		||||
+specified, if supported by the hypervisor.  If neither flag is given,
 | 
			
		||||
+then I<--live> is implied and it is up to the hypervisor whether
 | 
			
		||||
+I<--config> is also implied.
 | 
			
		||||
+
 | 
			
		||||
+If I<--maximum> is specified, then you must use I<--config> and
 | 
			
		||||
+avoid I<--live>; this flag controls the maximum limit of vcpus that
 | 
			
		||||
+can be hot-plugged the next time the domain is booted.
 | 
			
		||||
+
 | 
			
		||||
 =item B<shutdown> I<domain-id>
 | 
			
		||||
 | 
			
		||||
 Gracefully shuts down a domain.  This coordinates with the domain OS
 | 
			
		||||
@@ -568,6 +587,21 @@ is not available the processes will provide an exit code of 1.
 | 
			
		||||
 Undefine the configuration for an inactive domain. Since it's not running
 | 
			
		||||
 the domain name or UUID must be used as the I<domain-id>.
 | 
			
		||||
 | 
			
		||||
+=item B<vcpucount> I<domain-id>  optional I<--maximum> I<--current>
 | 
			
		||||
+I<--config> I<--live>
 | 
			
		||||
+
 | 
			
		||||
+Print information about the virtual cpu counts of the given
 | 
			
		||||
+I<domain-id>.  If no flags are specified, all possible counts are
 | 
			
		||||
+listed in a table; otherwise, the output is limited to just the
 | 
			
		||||
+numeric value requested.
 | 
			
		||||
+
 | 
			
		||||
+I<--maximum> requests information on the maximum cap of vcpus that a
 | 
			
		||||
+domain can add via B<setvcpus>, while I<--current> shows the current
 | 
			
		||||
+usage; these two flags cannot both be specified.  I<--config>
 | 
			
		||||
+requests information regarding the next time the domain will be
 | 
			
		||||
+booted, while I<--live> requires a running domain and lists current
 | 
			
		||||
+values; these two flags cannot both be specified.
 | 
			
		||||
+
 | 
			
		||||
 =item B<vcpuinfo> I<domain-id>
 | 
			
		||||
 | 
			
		||||
 Returns basic information about the domain virtual CPUs, like the number of
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										519
									
								
								docs/api_extension/0008-support-new-xml.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										519
									
								
								docs/api_extension/0008-support-new-xml.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,519 @@
 | 
			
		||||
From 4617eedfaeee2b187a1f14691d25746ba3ff31b6 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Wed, 29 Sep 2010 10:20:07 -0600
 | 
			
		||||
Subject: [PATCH 07/15] vcpu: support maxvcpu in domain_conf
 | 
			
		||||
 | 
			
		||||
Although this patch adds a distinction between maximum vcpus and
 | 
			
		||||
current vcpus in the XML, the values should be identical for all
 | 
			
		||||
drivers at this point.  Only in subsequent per-driver patches will
 | 
			
		||||
a distinction be made.
 | 
			
		||||
 | 
			
		||||
In general, virDomainGetInfo should prefer the current vcpus.
 | 
			
		||||
 | 
			
		||||
* src/conf/domain_conf.h (_virDomainDef): Adjust vcpus to unsigned
 | 
			
		||||
short, to match virDomainGetInfo limit.  Add maxvcpus member.
 | 
			
		||||
* src/conf/domain_conf.c (virDomainDefParseXML)
 | 
			
		||||
(virDomainDefFormat): parse and print out vcpu details.
 | 
			
		||||
* src/xen/xend_internal.c (xenDaemonParseSxpr)
 | 
			
		||||
(xenDaemonFormatSxpr): Manage both vcpu numbers, and require them
 | 
			
		||||
to be equal for now.
 | 
			
		||||
* src/xen/xm_internal.c (xenXMDomainConfigParse)
 | 
			
		||||
(xenXMDomainConfigFormat): Likewise.
 | 
			
		||||
* src/phyp/phyp_driver.c (phypDomainDumpXML): Likewise.
 | 
			
		||||
* src/openvz/openvz_conf.c (openvzLoadDomains): Likewise.
 | 
			
		||||
* src/openvz/openvz_driver.c (openvzDomainDefineXML)
 | 
			
		||||
(openvzDomainCreateXML, openvzDomainSetVcpusInternal): Likewise.
 | 
			
		||||
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxDomainDefineXML):
 | 
			
		||||
Likewise.
 | 
			
		||||
* src/xenapi/xenapi_driver.c (xenapiDomainDumpXML): Likewise.
 | 
			
		||||
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
 | 
			
		||||
* src/esx/esx_vmx.c (esxVMX_ParseConfig, esxVMX_FormatConfig):
 | 
			
		||||
Likewise.
 | 
			
		||||
* src/qemu/qemu_conf.c (qemuBuildSmpArgStr)
 | 
			
		||||
(qemuParseCommandLineSmp, qemuParseCommandLine): Likewise.
 | 
			
		||||
* src/qemu/qemu_driver.c (qemudDomainHotplugVcpus): Likewise.
 | 
			
		||||
* src/opennebula/one_conf.c (xmlOneTemplate): Likewise.
 | 
			
		||||
---
 | 
			
		||||
 src/conf/domain_conf.c     |   45 +++++++++++++++++++++++++++++++++++++------
 | 
			
		||||
 src/conf/domain_conf.h     |    3 +-
 | 
			
		||||
 src/esx/esx_vmx.c          |   24 ++++++++++++++--------
 | 
			
		||||
 src/opennebula/one_conf.c  |    9 +++++--
 | 
			
		||||
 src/openvz/openvz_conf.c   |    7 +++--
 | 
			
		||||
 src/openvz/openvz_driver.c |   15 +++++++++----
 | 
			
		||||
 src/phyp/phyp_driver.c     |    2 +-
 | 
			
		||||
 src/qemu/qemu_conf.c       |   14 +++++++++++-
 | 
			
		||||
 src/qemu/qemu_driver.c     |    5 ++-
 | 
			
		||||
 src/vbox/vbox_tmpl.c       |   12 +++++++---
 | 
			
		||||
 src/xen/xend_internal.c    |    9 ++++---
 | 
			
		||||
 src/xen/xm_internal.c      |   11 ++++++---
 | 
			
		||||
 src/xenapi/xenapi_driver.c |    2 +-
 | 
			
		||||
 src/xenapi/xenapi_utils.c  |    4 +-
 | 
			
		||||
 14 files changed, 114 insertions(+), 48 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
 | 
			
		||||
index 78d7a6a..a997e06 100644
 | 
			
		||||
--- a/src/conf/domain_conf.c
 | 
			
		||||
+++ b/src/conf/domain_conf.c
 | 
			
		||||
@@ -4203,6 +4203,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 | 
			
		||||
     int i, n;
 | 
			
		||||
     long id = -1;
 | 
			
		||||
     virDomainDefPtr def;
 | 
			
		||||
+    unsigned long count;
 | 
			
		||||
 | 
			
		||||
     if (VIR_ALLOC(def) < 0) {
 | 
			
		||||
         virReportOOMError();
 | 
			
		||||
@@ -4287,8 +4288,37 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 | 
			
		||||
                       &def->mem.swap_hard_limit) < 0)
 | 
			
		||||
         def->mem.swap_hard_limit = 0;
 | 
			
		||||
 | 
			
		||||
-    if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0)
 | 
			
		||||
-        def->vcpus = 1;
 | 
			
		||||
+    n = virXPathULong("string(./vcpu[1])", ctxt, &count);
 | 
			
		||||
+    if (n == -2) {
 | 
			
		||||
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
 | 
			
		||||
+                             _("maximum vcpus must be an integer"));
 | 
			
		||||
+        goto error;
 | 
			
		||||
+    } else if (n < 0) {
 | 
			
		||||
+        def->maxvcpus = 1;
 | 
			
		||||
+    } else {
 | 
			
		||||
+        def->maxvcpus = count;
 | 
			
		||||
+        if (def->maxvcpus != count || count == 0) {
 | 
			
		||||
+            virDomainReportError(VIR_ERR_XML_ERROR,
 | 
			
		||||
+                                 _("invalid maxvcpus %lu"), count);
 | 
			
		||||
+            goto error;
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    n = virXPathULong("string(./vcpu[1]/@current)", ctxt, &count);
 | 
			
		||||
+    if (n == -2) {
 | 
			
		||||
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
 | 
			
		||||
+                             _("current vcpus must be an integer"));
 | 
			
		||||
+        goto error;
 | 
			
		||||
+    } else if (n < 0) {
 | 
			
		||||
+        def->vcpus = def->maxvcpus;
 | 
			
		||||
+    } else {
 | 
			
		||||
+        def->vcpus = count;
 | 
			
		||||
+        if (def->vcpus != count || count == 0 || def->maxvcpus < count) {
 | 
			
		||||
+            virDomainReportError(VIR_ERR_XML_ERROR,
 | 
			
		||||
+                                 _("invalid current vcpus %lu"), count);
 | 
			
		||||
+            goto error;
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
 | 
			
		||||
     tmp = virXPathString("string(./vcpu[1]/@cpuset)", ctxt);
 | 
			
		||||
     if (tmp) {
 | 
			
		||||
@@ -6462,17 +6492,18 @@ char *virDomainDefFormat(virDomainDefPtr def,
 | 
			
		||||
         if (def->cpumask[n] != 1)
 | 
			
		||||
             allones = 0;
 | 
			
		||||
 | 
			
		||||
-    if (allones) {
 | 
			
		||||
-        virBufferAsprintf(&buf, "  <vcpu>%lu</vcpu>\n", def->vcpus);
 | 
			
		||||
-    } else {
 | 
			
		||||
+    virBufferAddLit(&buf, "  <vcpu");
 | 
			
		||||
+    if (!allones) {
 | 
			
		||||
         char *cpumask = NULL;
 | 
			
		||||
         if ((cpumask =
 | 
			
		||||
              virDomainCpuSetFormat(def->cpumask, def->cpumasklen)) == NULL)
 | 
			
		||||
             goto cleanup;
 | 
			
		||||
-        virBufferAsprintf(&buf, "  <vcpu cpuset='%s'>%lu</vcpu>\n",
 | 
			
		||||
-                          cpumask, def->vcpus);
 | 
			
		||||
+        virBufferAsprintf(&buf, " cpuset='%s'", cpumask);
 | 
			
		||||
         VIR_FREE(cpumask);
 | 
			
		||||
     }
 | 
			
		||||
+    if (def->vcpus != def->maxvcpus)
 | 
			
		||||
+        virBufferAsprintf(&buf, " current='%u'", def->vcpus);
 | 
			
		||||
+    virBufferAsprintf(&buf, ">%u</vcpu>\n", def->maxvcpus);
 | 
			
		||||
 | 
			
		||||
     if (def->os.bootloader) {
 | 
			
		||||
         virBufferEscapeString(&buf, "  <bootloader>%s</bootloader>\n",
 | 
			
		||||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
 | 
			
		||||
index db09c23..5499f28 100644
 | 
			
		||||
--- a/src/conf/domain_conf.h
 | 
			
		||||
+++ b/src/conf/domain_conf.h
 | 
			
		||||
@@ -885,7 +885,8 @@ struct _virDomainDef {
 | 
			
		||||
         unsigned long min_guarantee;
 | 
			
		||||
         unsigned long swap_hard_limit;
 | 
			
		||||
     } mem;
 | 
			
		||||
-    unsigned long vcpus;
 | 
			
		||||
+    unsigned short vcpus;
 | 
			
		||||
+    unsigned short maxvcpus;
 | 
			
		||||
     int cpumasklen;
 | 
			
		||||
     char *cpumask;
 | 
			
		||||
 | 
			
		||||
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
 | 
			
		||||
index 7ec8c0e..0a26614 100644
 | 
			
		||||
--- a/src/esx/esx_vmx.c
 | 
			
		||||
+++ b/src/esx/esx_vmx.c
 | 
			
		||||
@@ -50,7 +50,7 @@ def->uuid = <value>               <=>   uuid.bios = "<value>"
 | 
			
		||||
 def->name = <value>               <=>   displayName = "<value>"
 | 
			
		||||
 def->mem.max_balloon = <value kilobyte>    <=>   memsize = "<value megabyte>"            # must be a multiple of 4, defaults to 32
 | 
			
		||||
 def->mem.cur_balloon = <value kilobyte>    <=>   sched.mem.max = "<value megabyte>"      # defaults to "unlimited" -> def->mem.cur_balloon = def->mem.max_balloon
 | 
			
		||||
-def->vcpus = <value>              <=>   numvcpus = "<value>"                    # must be 1 or a multiple of 2, defaults to 1
 | 
			
		||||
+def->maxvcpus = <value>           <=>   numvcpus = "<value>"                    # must be 1 or a multiple of 2, defaults to 1
 | 
			
		||||
 def->cpumask = <uint list>        <=>   sched.cpu.affinity = "<uint list>"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1075,7 +1075,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    def->vcpus = numvcpus;
 | 
			
		||||
+    def->maxvcpus = def->vcpus = numvcpus;
 | 
			
		||||
 | 
			
		||||
     /* vmx:sched.cpu.affinity -> def:cpumask */
 | 
			
		||||
     // VirtualMachine:config.cpuAffinity.affinitySet
 | 
			
		||||
@@ -2609,16 +2609,22 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
 | 
			
		||||
                           (int)(def->mem.cur_balloon / 1024));
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    /* def:vcpus -> vmx:numvcpus */
 | 
			
		||||
-    if (def->vcpus <= 0 || (def->vcpus % 2 != 0 && def->vcpus != 1)) {
 | 
			
		||||
+    /* def:maxvcpus -> vmx:numvcpus */
 | 
			
		||||
+    if (def->vcpus != def->maxvcpus) {
 | 
			
		||||
+        ESX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
			
		||||
+                  _("No support for domain XML entry 'vcpu' attribute "
 | 
			
		||||
+                    "'current'"));
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (def->maxvcpus <= 0 || (def->maxvcpus % 2 != 0 && def->maxvcpus != 1)) {
 | 
			
		||||
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
                   _("Expecting domain XML entry 'vcpu' to be an unsigned "
 | 
			
		||||
                     "integer (1 or a multiple of 2) but found %d"),
 | 
			
		||||
-                  (int)def->vcpus);
 | 
			
		||||
+                  def->maxvcpus);
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", (int)def->vcpus);
 | 
			
		||||
+    virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", def->maxvcpus);
 | 
			
		||||
 | 
			
		||||
     /* def:cpumask -> vmx:sched.cpu.affinity */
 | 
			
		||||
     if (def->cpumasklen > 0) {
 | 
			
		||||
@@ -2632,11 +2638,11 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
-        if (sched_cpu_affinity_length < def->vcpus) {
 | 
			
		||||
+        if (sched_cpu_affinity_length < def->maxvcpus) {
 | 
			
		||||
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
                       _("Expecting domain XML attribute 'cpuset' of entry "
 | 
			
		||||
-                        "'vcpu' to contains at least %d CPU(s)"),
 | 
			
		||||
-                      (int)def->vcpus);
 | 
			
		||||
+                        "'vcpu' to contain at least %d CPU(s)"),
 | 
			
		||||
+                      def->maxvcpus);
 | 
			
		||||
             goto cleanup;
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
diff --git a/src/opennebula/one_conf.c b/src/opennebula/one_conf.c
 | 
			
		||||
index 44e28dc..2079c51 100644
 | 
			
		||||
--- a/src/opennebula/one_conf.c
 | 
			
		||||
+++ b/src/opennebula/one_conf.c
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
 /*----------------------------------------------------------------------------------*/
 | 
			
		||||
-/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright (C) 2010 Red Hat, Inc.
 | 
			
		||||
+ * Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
 | 
			
		||||
  * Complutense de Madrid (dsa-research.org)
 | 
			
		||||
  *
 | 
			
		||||
  * This library is free software; you can redistribute it and/or
 | 
			
		||||
@@ -169,9 +171,10 @@ char* xmlOneTemplate(virDomainDefPtr def)
 | 
			
		||||
 {
 | 
			
		||||
     int i;
 | 
			
		||||
     virBuffer buf= VIR_BUFFER_INITIALIZER;
 | 
			
		||||
-    virBufferAsprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
 | 
			
		||||
+    virBufferAsprintf(&buf,"#OpenNebula Template automatically generated "
 | 
			
		||||
+                      "by libvirt\nNAME = %s\nCPU = %d\nMEMORY = %ld\n",
 | 
			
		||||
                       def->name,
 | 
			
		||||
-                      def->vcpus,
 | 
			
		||||
+                      def->maxvcpus,
 | 
			
		||||
                       (def->mem.max_balloon)/1024);
 | 
			
		||||
 | 
			
		||||
     /*Optional Booting OpenNebula Information:*/
 | 
			
		||||
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
 | 
			
		||||
index ec11bbc..c84a6f3 100644
 | 
			
		||||
--- a/src/openvz/openvz_conf.c
 | 
			
		||||
+++ b/src/openvz/openvz_conf.c
 | 
			
		||||
@@ -507,11 +507,12 @@ int openvzLoadDomains(struct openvz_driver *driver) {
 | 
			
		||||
                         veid);
 | 
			
		||||
             goto cleanup;
 | 
			
		||||
         } else if (ret > 0) {
 | 
			
		||||
-            dom->def->vcpus = strtoI(temp);
 | 
			
		||||
+            dom->def->maxvcpus = strtoI(temp);
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
-        if (ret == 0 || dom->def->vcpus == 0)
 | 
			
		||||
-            dom->def->vcpus = openvzGetNodeCPUs();
 | 
			
		||||
+        if (ret == 0 || dom->def->maxvcpus == 0)
 | 
			
		||||
+            dom->def->maxvcpus = openvzGetNodeCPUs();
 | 
			
		||||
+        dom->def->vcpus = dom->def->maxvcpus;
 | 
			
		||||
 | 
			
		||||
         /* XXX load rest of VM config data .... */
 | 
			
		||||
 | 
			
		||||
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
 | 
			
		||||
index 0f3cfdf..b7c2754 100644
 | 
			
		||||
--- a/src/openvz/openvz_driver.c
 | 
			
		||||
+++ b/src/openvz/openvz_driver.c
 | 
			
		||||
@@ -925,8 +925,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
 | 
			
		||||
     if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
 | 
			
		||||
-    if (vm->def->vcpus > 0) {
 | 
			
		||||
-        if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
 | 
			
		||||
+    if (vm->def->vcpus != vm->def->maxvcpus) {
 | 
			
		||||
+        openvzError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 | 
			
		||||
+                    _("current vcpu count must equal maximum"));
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (vm->def->maxvcpus > 0) {
 | 
			
		||||
+        if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
 | 
			
		||||
             openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
 | 
			
		||||
                         _("Could not set number of virtual cpu"));
 | 
			
		||||
              goto cleanup;
 | 
			
		||||
@@ -1019,8 +1024,8 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
 | 
			
		||||
     vm->def->id = vm->pid;
 | 
			
		||||
     vm->state = VIR_DOMAIN_RUNNING;
 | 
			
		||||
 | 
			
		||||
-    if (vm->def->vcpus > 0) {
 | 
			
		||||
-        if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
 | 
			
		||||
+    if (vm->def->maxvcpus > 0) {
 | 
			
		||||
+        if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
 | 
			
		||||
             openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
 | 
			
		||||
                         _("Could not set number of virtual cpu"));
 | 
			
		||||
             goto cleanup;
 | 
			
		||||
@@ -1249,7 +1254,7 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    vm->def->vcpus = nvcpus;
 | 
			
		||||
+    vm->def->maxvcpus = vm->def->vcpus = nvcpus;
 | 
			
		||||
     return 0;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
 | 
			
		||||
index e284ae0..3d0ed11 100644
 | 
			
		||||
--- a/src/phyp/phyp_driver.c
 | 
			
		||||
+++ b/src/phyp/phyp_driver.c
 | 
			
		||||
@@ -3540,7 +3540,7 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
 | 
			
		||||
         goto err;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    if ((def.vcpus =
 | 
			
		||||
+    if ((def.maxvcpus = def.vcpus =
 | 
			
		||||
          phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
 | 
			
		||||
         VIR_ERROR0(_("Unable to determine domain's CPU."));
 | 
			
		||||
         goto err;
 | 
			
		||||
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
 | 
			
		||||
index 83c0f83..38c8351 100644
 | 
			
		||||
--- a/src/qemu/qemu_conf.c
 | 
			
		||||
+++ b/src/qemu/qemu_conf.c
 | 
			
		||||
@@ -3711,7 +3711,7 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
 | 
			
		||||
 {
 | 
			
		||||
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
-    virBufferAsprintf(&buf, "%lu", def->vcpus);
 | 
			
		||||
+    virBufferAsprintf(&buf, "%u", def->vcpus);
 | 
			
		||||
 | 
			
		||||
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
 | 
			
		||||
         /* sockets, cores, and threads are either all zero
 | 
			
		||||
@@ -3722,11 +3722,18 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
 | 
			
		||||
             virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
 | 
			
		||||
         }
 | 
			
		||||
         else {
 | 
			
		||||
-            virBufferAsprintf(&buf, ",sockets=%lu", def->vcpus);
 | 
			
		||||
+            virBufferAsprintf(&buf, ",sockets=%u", def->maxvcpus);
 | 
			
		||||
             virBufferAsprintf(&buf, ",cores=%u", 1);
 | 
			
		||||
             virBufferAsprintf(&buf, ",threads=%u", 1);
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
+    if (def->vcpus != def->maxvcpus) {
 | 
			
		||||
+        virBufferFreeAndReset(&buf);
 | 
			
		||||
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 | 
			
		||||
+                        _("setting current vcpu count less than maximum is "
 | 
			
		||||
+                          "not supported yet"));
 | 
			
		||||
+        return NULL;
 | 
			
		||||
+    }
 | 
			
		||||
 | 
			
		||||
     if (virBufferError(&buf)) {
 | 
			
		||||
         virBufferFreeAndReset(&buf);
 | 
			
		||||
@@ -6178,6 +6185,8 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
+    dom->maxvcpus = dom->vcpus;
 | 
			
		||||
+
 | 
			
		||||
     if (sockets && cores && threads) {
 | 
			
		||||
         virCPUDefPtr cpu;
 | 
			
		||||
 | 
			
		||||
@@ -6247,6 +6256,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
 | 
			
		||||
 | 
			
		||||
     def->id = -1;
 | 
			
		||||
     def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024;
 | 
			
		||||
+    def->maxvcpus = 1;
 | 
			
		||||
     def->vcpus = 1;
 | 
			
		||||
     def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
 | 
			
		||||
     def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
 | 
			
		||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 | 
			
		||||
index 7a2ea8f..c66dc04 100644
 | 
			
		||||
--- a/src/qemu/qemu_driver.c
 | 
			
		||||
+++ b/src/qemu/qemu_driver.c
 | 
			
		||||
@@ -2425,8 +2425,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver,
 | 
			
		||||
 | 
			
		||||
     if (ncpupids != vm->def->vcpus) {
 | 
			
		||||
         qemuReportError(VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
-                        _("got wrong number of vCPU pids from QEMU monitor. got %d, wanted %d"),
 | 
			
		||||
-                        ncpupids, (int)vm->def->vcpus);
 | 
			
		||||
+                        _("got wrong number of vCPU pids from QEMU monitor. "
 | 
			
		||||
+                          "got %d, wanted %d"),
 | 
			
		||||
+                        ncpupids, vm->def->vcpus);
 | 
			
		||||
         VIR_FREE(cpupids);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
 | 
			
		||||
index 0cbe8b3..5a859a4 100644
 | 
			
		||||
--- a/src/vbox/vbox_tmpl.c
 | 
			
		||||
+++ b/src/vbox/vbox_tmpl.c
 | 
			
		||||
@@ -2028,7 +2028,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
 | 
			
		||||
             def->mem.max_balloon = memorySize * 1024;
 | 
			
		||||
 | 
			
		||||
             machine->vtbl->GetCPUCount(machine, &CPUCount);
 | 
			
		||||
-            def->vcpus = CPUCount;
 | 
			
		||||
+            def->maxvcpus = def->vcpus = CPUCount;
 | 
			
		||||
 | 
			
		||||
             /* Skip cpumasklen, cpumask, onReboot, onPoweroff, onCrash */
 | 
			
		||||
 | 
			
		||||
@@ -4598,11 +4598,15 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
 | 
			
		||||
                   def->mem.cur_balloon, (unsigned)rc);
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    rc = machine->vtbl->SetCPUCount(machine, def->vcpus);
 | 
			
		||||
+    if (def->vcpus != def->maxvcpus) {
 | 
			
		||||
+        vboxError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 | 
			
		||||
+                    _("current vcpu count must equal maximum"));
 | 
			
		||||
+    }
 | 
			
		||||
+    rc = machine->vtbl->SetCPUCount(machine, def->maxvcpus);
 | 
			
		||||
     if (NS_FAILED(rc)) {
 | 
			
		||||
         vboxError(VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
-                  _("could not set the number of virtual CPUs to: %lu, rc=%08x"),
 | 
			
		||||
-                  def->vcpus, (unsigned)rc);
 | 
			
		||||
+                  _("could not set the number of virtual CPUs to: %u, rc=%08x"),
 | 
			
		||||
+                  def->maxvcpus, (unsigned)rc);
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
 #if VBOX_API_VERSION < 3001
 | 
			
		||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
 | 
			
		||||
index 5ffc3c8..456b477 100644
 | 
			
		||||
--- a/src/xen/xend_internal.c
 | 
			
		||||
+++ b/src/xen/xend_internal.c
 | 
			
		||||
@@ -2190,7 +2190,8 @@ xenDaemonParseSxpr(virConnectPtr conn,
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    def->vcpus = sexpr_int(root, "domain/vcpus");
 | 
			
		||||
+    def->maxvcpus = sexpr_int(root, "domain/vcpus");
 | 
			
		||||
+    def->vcpus = def->maxvcpus;
 | 
			
		||||
 | 
			
		||||
     tmp = sexpr_node(root, "domain/on_poweroff");
 | 
			
		||||
     if (tmp != NULL) {
 | 
			
		||||
@@ -5649,7 +5650,7 @@ xenDaemonFormatSxprInput(virDomainInputDefPtr input,
 | 
			
		||||
  *
 | 
			
		||||
  * Generate an SEXPR representing the domain configuration.
 | 
			
		||||
  *
 | 
			
		||||
- * Returns the 0 terminatedi S-Expr string or NULL in case of error.
 | 
			
		||||
+ * Returns the 0 terminated S-Expr string or NULL in case of error.
 | 
			
		||||
  *         the caller must free() the returned value.
 | 
			
		||||
  */
 | 
			
		||||
 char *
 | 
			
		||||
@@ -5666,7 +5667,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 | 
			
		||||
     virBufferAsprintf(&buf, "(name '%s')", def->name);
 | 
			
		||||
     virBufferAsprintf(&buf, "(memory %lu)(maxmem %lu)",
 | 
			
		||||
                       def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
 | 
			
		||||
-    virBufferAsprintf(&buf, "(vcpus %lu)", def->vcpus);
 | 
			
		||||
+    virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
 | 
			
		||||
 | 
			
		||||
     if (def->cpumask) {
 | 
			
		||||
         char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
 | 
			
		||||
@@ -5761,7 +5762,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 | 
			
		||||
             else
 | 
			
		||||
                 virBufferAsprintf(&buf, "(kernel '%s')", def->os.loader);
 | 
			
		||||
 | 
			
		||||
-            virBufferAsprintf(&buf, "(vcpus %lu)", def->vcpus);
 | 
			
		||||
+            virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
 | 
			
		||||
 | 
			
		||||
             for (i = 0 ; i < def->os.nBootDevs ; i++) {
 | 
			
		||||
                 switch (def->os.bootDevs[i]) {
 | 
			
		||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
 | 
			
		||||
index 8e42a1c..bf20a64 100644
 | 
			
		||||
--- a/src/xen/xm_internal.c
 | 
			
		||||
+++ b/src/xen/xm_internal.c
 | 
			
		||||
@@ -678,6 +678,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
 | 
			
		||||
     int i;
 | 
			
		||||
     const char *defaultArch, *defaultMachine;
 | 
			
		||||
     int vmlocaltime = 0;
 | 
			
		||||
+    unsigned long count;
 | 
			
		||||
 | 
			
		||||
     if (VIR_ALLOC(def) < 0) {
 | 
			
		||||
         virReportOOMError();
 | 
			
		||||
@@ -770,9 +771,11 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
 | 
			
		||||
     def->mem.cur_balloon *= 1024;
 | 
			
		||||
     def->mem.max_balloon *= 1024;
 | 
			
		||||
 | 
			
		||||
-
 | 
			
		||||
-    if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
 | 
			
		||||
+    if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
 | 
			
		||||
+        (unsigned short) count != count)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
+    def->maxvcpus = count;
 | 
			
		||||
+    def->vcpus = def->maxvcpus;
 | 
			
		||||
 | 
			
		||||
     if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
@@ -1650,7 +1653,7 @@ int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
 | 
			
		||||
     if (!(entry = virHashLookup(priv->configCache, filename)))
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
 | 
			
		||||
-    entry->def->vcpus = vcpus;
 | 
			
		||||
+    entry->def->maxvcpus = entry->def->vcpus = vcpus;
 | 
			
		||||
 | 
			
		||||
     /* If this fails, should we try to undo our changes to the
 | 
			
		||||
      * in-memory representation of the config file. I say not!
 | 
			
		||||
@@ -2241,7 +2244,7 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
 | 
			
		||||
     if (xenXMConfigSetInt(conf, "memory", def->mem.cur_balloon / 1024) < 0)
 | 
			
		||||
         goto no_memory;
 | 
			
		||||
 | 
			
		||||
-    if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
 | 
			
		||||
+    if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
 | 
			
		||||
         goto no_memory;
 | 
			
		||||
 | 
			
		||||
     if ((def->cpumask != NULL) &&
 | 
			
		||||
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
 | 
			
		||||
index 7d4ab8d..5ccdede 100644
 | 
			
		||||
--- a/src/xenapi/xenapi_driver.c
 | 
			
		||||
+++ b/src/xenapi/xenapi_driver.c
 | 
			
		||||
@@ -1335,7 +1335,7 @@ xenapiDomainDumpXML (virDomainPtr dom, int flags ATTRIBUTE_UNUSED)
 | 
			
		||||
     } else {
 | 
			
		||||
         defPtr->mem.cur_balloon = memory;
 | 
			
		||||
     }
 | 
			
		||||
-    defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
 | 
			
		||||
+    defPtr->maxvcpus = defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
 | 
			
		||||
     enum xen_on_normal_exit action;
 | 
			
		||||
     if (xen_vm_get_actions_after_shutdown(session, &action, vm)) {
 | 
			
		||||
         defPtr->onPoweroff = xenapiNormalExitEnum2virDomainLifecycle(action);
 | 
			
		||||
diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c
 | 
			
		||||
index be55491..a7e2a4b 100644
 | 
			
		||||
--- a/src/xenapi/xenapi_utils.c
 | 
			
		||||
+++ b/src/xenapi/xenapi_utils.c
 | 
			
		||||
@@ -510,8 +510,8 @@ createVMRecordFromXml (virConnectPtr conn, virDomainDefPtr def,
 | 
			
		||||
     else
 | 
			
		||||
         (*record)->memory_dynamic_max = (*record)->memory_static_max;
 | 
			
		||||
 | 
			
		||||
-    if (def->vcpus) {
 | 
			
		||||
-        (*record)->vcpus_max = (int64_t) def->vcpus;
 | 
			
		||||
+    if (def->maxvcpus) {
 | 
			
		||||
+        (*record)->vcpus_max = (int64_t) def->maxvcpus;
 | 
			
		||||
         (*record)->vcpus_at_startup = (int64_t) def->vcpus;
 | 
			
		||||
     }
 | 
			
		||||
     if (def->onPoweroff)
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										197
									
								
								docs/api_extension/0009-support-all-flags-in-test-driver.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								docs/api_extension/0009-support-all-flags-in-test-driver.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
From 6c9e6b956453d0f0c4ff542ef8a184d663a39266 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Mon, 4 Oct 2010 17:01:12 -0600
 | 
			
		||||
Subject: [PATCH 09/15] vcpu: support all flags in test driver
 | 
			
		||||
 | 
			
		||||
* src/test/test_driver.c (testDomainGetVcpusFlags)
 | 
			
		||||
(testDomainSetVcpusFlags): Support all flags.
 | 
			
		||||
(testDomainUpdateVCPUs): Update cpu count here.
 | 
			
		||||
---
 | 
			
		||||
 src/test/test_driver.c |  128 ++++++++++++++++++++++++++++++++++++++++-------
 | 
			
		||||
 1 files changed, 109 insertions(+), 19 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
 | 
			
		||||
index b70c80d..a9d3d89 100644
 | 
			
		||||
--- a/src/test/test_driver.c
 | 
			
		||||
+++ b/src/test/test_driver.c
 | 
			
		||||
@@ -450,6 +450,7 @@ testDomainUpdateVCPUs(virConnectPtr conn,
 | 
			
		||||
                 goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
+    dom->def->vcpus = nvcpus;
 | 
			
		||||
     ret = 0;
 | 
			
		||||
 cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
@@ -2032,12 +2033,51 @@ cleanup:
 | 
			
		||||
 static int
 | 
			
		||||
 testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
-    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
-        testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+    testConnPtr privconn = domain->conn->privateData;
 | 
			
		||||
+    virDomainObjPtr vm;
 | 
			
		||||
+    virDomainDefPtr def;
 | 
			
		||||
+    int ret = -1;
 | 
			
		||||
+
 | 
			
		||||
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_CONFIG |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
 | 
			
		||||
+
 | 
			
		||||
+    /* Exactly one of LIVE or CONFIG must be set.  */
 | 
			
		||||
+    if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
 | 
			
		||||
+        testError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                  _("invalid flag combination: (0x%x)"), flags);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    return testGetMaxVCPUs(domain->conn, "test");
 | 
			
		||||
+    testDriverLock(privconn);
 | 
			
		||||
+    vm = virDomainFindByUUID(&privconn->domains, domain->uuid);
 | 
			
		||||
+    testDriverUnlock(privconn);
 | 
			
		||||
+
 | 
			
		||||
+    if (!vm) {
 | 
			
		||||
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
 | 
			
		||||
+        virUUIDFormat(domain->uuid, uuidstr);
 | 
			
		||||
+        testError(VIR_ERR_NO_DOMAIN,
 | 
			
		||||
+                  _("no domain with matching uuid '%s'"), uuidstr);
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        if (!virDomainObjIsActive(vm)) {
 | 
			
		||||
+            testError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                      _("domain not active"));
 | 
			
		||||
+            goto cleanup;
 | 
			
		||||
+        }
 | 
			
		||||
+        def = vm->def;
 | 
			
		||||
+    } else {
 | 
			
		||||
+        def = vm->newDef ? vm->newDef : vm->def;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
 | 
			
		||||
+
 | 
			
		||||
+cleanup:
 | 
			
		||||
+    if (vm)
 | 
			
		||||
+        virDomainObjUnlock(vm);
 | 
			
		||||
+    return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
@@ -2053,21 +2093,30 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
 | 
			
		||||
 {
 | 
			
		||||
     testConnPtr privconn = domain->conn->privateData;
 | 
			
		||||
     virDomainObjPtr privdom = NULL;
 | 
			
		||||
+    virDomainDefPtr def;
 | 
			
		||||
     int ret = -1, maxvcpus;
 | 
			
		||||
 | 
			
		||||
-    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
-        testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
 | 
			
		||||
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_CONFIG |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
 | 
			
		||||
+
 | 
			
		||||
+    /* At least one of LIVE or CONFIG must be set.  MAXIMUM cannot be
 | 
			
		||||
+     * mixed with LIVE.  */
 | 
			
		||||
+    if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
 | 
			
		||||
+        (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
 | 
			
		||||
+         (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
 | 
			
		||||
+        testError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                  _("invalid flag combination: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (!nrCpus || (maxvcpus = testGetMaxVCPUs(domain->conn, NULL)) < nrCpus) {
 | 
			
		||||
+        testError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                  _("argument out of range: %d"), nrCpus);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
-
 | 
			
		||||
-    /* Do this first before locking */
 | 
			
		||||
-    maxvcpus = testDomainGetMaxVcpus(domain);
 | 
			
		||||
-    if (maxvcpus < 0)
 | 
			
		||||
-        goto cleanup;
 | 
			
		||||
 | 
			
		||||
     testDriverLock(privconn);
 | 
			
		||||
-    privdom = virDomainFindByName(&privconn->domains,
 | 
			
		||||
-                                  domain->name);
 | 
			
		||||
+    privdom = virDomainFindByUUID(&privconn->domains, domain->uuid);
 | 
			
		||||
     testDriverUnlock(privconn);
 | 
			
		||||
 | 
			
		||||
     if (privdom == NULL) {
 | 
			
		||||
@@ -2075,13 +2124,17 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    if (!virDomainObjIsActive(privdom)) {
 | 
			
		||||
+    if (!virDomainObjIsActive(privdom) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
 | 
			
		||||
         testError(VIR_ERR_OPERATION_INVALID,
 | 
			
		||||
                   "%s", _("cannot hotplug vcpus for an inactive domain"));
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    /* We allow more cpus in guest than host */
 | 
			
		||||
+    /* We allow more cpus in guest than host, but not more than the
 | 
			
		||||
+     * domain's starting limit.  */
 | 
			
		||||
+    if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
 | 
			
		||||
+        VIR_DOMAIN_VCPU_LIVE && privdom->def->maxvcpus < maxvcpus)
 | 
			
		||||
+        maxvcpus = privdom->def->maxvcpus;
 | 
			
		||||
     if (nrCpus > maxvcpus) {
 | 
			
		||||
         testError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
                   "requested cpu amount exceeds maximum (%d > %d)",
 | 
			
		||||
@@ -2089,12 +2142,49 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    /* Update VCPU state for the running domain */
 | 
			
		||||
-    if (testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0) < 0)
 | 
			
		||||
-        goto cleanup;
 | 
			
		||||
+    switch (flags) {
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
 | 
			
		||||
+        def = privdom->def;
 | 
			
		||||
+        if (virDomainObjIsActive(privdom)) {
 | 
			
		||||
+            if (privdom->newDef)
 | 
			
		||||
+                def = privdom->newDef;
 | 
			
		||||
+            else {
 | 
			
		||||
+                testError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                          _("no persistent state"));
 | 
			
		||||
+                goto cleanup;
 | 
			
		||||
+            }
 | 
			
		||||
+        }
 | 
			
		||||
+        def->maxvcpus = nrCpus;
 | 
			
		||||
+        if (nrCpus < def->vcpus)
 | 
			
		||||
+            def->vcpus = nrCpus;
 | 
			
		||||
+        ret = 0;
 | 
			
		||||
+        break;
 | 
			
		||||
 | 
			
		||||
-    privdom->def->vcpus = nrCpus;
 | 
			
		||||
-    ret = 0;
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_CONFIG:
 | 
			
		||||
+        def = privdom->def;
 | 
			
		||||
+        if (virDomainObjIsActive(privdom)) {
 | 
			
		||||
+            if (privdom->newDef)
 | 
			
		||||
+                def = privdom->newDef;
 | 
			
		||||
+            else {
 | 
			
		||||
+                testError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                          _("no persistent state"));
 | 
			
		||||
+                goto cleanup;
 | 
			
		||||
+            }
 | 
			
		||||
+        }
 | 
			
		||||
+        def->vcpus = nrCpus;
 | 
			
		||||
+        ret = 0;
 | 
			
		||||
+        break;
 | 
			
		||||
+
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_LIVE:
 | 
			
		||||
+        ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
 | 
			
		||||
+        break;
 | 
			
		||||
+
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
 | 
			
		||||
+        ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
 | 
			
		||||
+        if (ret == 0 && privdom->newDef)
 | 
			
		||||
+            privdom->newDef->vcpus = nrCpus;
 | 
			
		||||
+        break;
 | 
			
		||||
+    }
 | 
			
		||||
 | 
			
		||||
 cleanup:
 | 
			
		||||
     if (privdom)
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,122 @@
 | 
			
		||||
From d67c189e80e6aef7adf13e5763365555cfc1a02a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Wed, 29 Sep 2010 15:58:47 -0600
 | 
			
		||||
Subject: [PATCH 10/15] vcpu: improve vcpu support in qemu command line
 | 
			
		||||
 | 
			
		||||
* src/qemu/qemu_conf.c (qemuParseCommandLineSmp): Distinguish
 | 
			
		||||
between vcpus and maxvcpus, for new enough qemu.
 | 
			
		||||
* tests/qemuargv2xmltest.c (mymain): Add new test.
 | 
			
		||||
* tests/qemuxml2argvtest.c (mymain): Likewise.
 | 
			
		||||
* tests/qemuxml2xmltest.c (mymain): Likewise.
 | 
			
		||||
* tests/qemuxml2argvdata/qemuxml2argv-smp.args: New file.
 | 
			
		||||
---
 | 
			
		||||
 src/qemu/qemu_conf.c                         |   13 +++++++++----
 | 
			
		||||
 tests/qemuargv2xmltest.c                     |    2 ++
 | 
			
		||||
 tests/qemuxml2argvdata/qemuxml2argv-smp.args |    1 +
 | 
			
		||||
 tests/qemuxml2argvtest.c                     |    2 ++
 | 
			
		||||
 tests/qemuxml2xmltest.c                      |    2 ++
 | 
			
		||||
 5 files changed, 16 insertions(+), 4 deletions(-)
 | 
			
		||||
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smp.args
 | 
			
		||||
 | 
			
		||||
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
 | 
			
		||||
index 38c8351..ffe184b 100644
 | 
			
		||||
--- a/src/qemu/qemu_conf.c
 | 
			
		||||
+++ b/src/qemu/qemu_conf.c
 | 
			
		||||
@@ -3714,6 +3714,8 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
 | 
			
		||||
     virBufferAsprintf(&buf, "%u", def->vcpus);
 | 
			
		||||
 | 
			
		||||
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
 | 
			
		||||
+        if (def->vcpus != def->maxvcpus)
 | 
			
		||||
+            virBufferAsprintf(&buf, ",maxcpus=%u", def->maxvcpus);
 | 
			
		||||
         /* sockets, cores, and threads are either all zero
 | 
			
		||||
          * or all non-zero, thus checking one of them is enough */
 | 
			
		||||
         if (def->cpu && def->cpu->sockets) {
 | 
			
		||||
@@ -3726,12 +3728,12 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
 | 
			
		||||
             virBufferAsprintf(&buf, ",cores=%u", 1);
 | 
			
		||||
             virBufferAsprintf(&buf, ",threads=%u", 1);
 | 
			
		||||
         }
 | 
			
		||||
-    }
 | 
			
		||||
-    if (def->vcpus != def->maxvcpus) {
 | 
			
		||||
+    } else if (def->vcpus != def->maxvcpus) {
 | 
			
		||||
         virBufferFreeAndReset(&buf);
 | 
			
		||||
+        /* FIXME - consider hot-unplugging cpus after boot for older qemu */
 | 
			
		||||
         qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 | 
			
		||||
                         _("setting current vcpu count less than maximum is "
 | 
			
		||||
-                          "not supported yet"));
 | 
			
		||||
+                          "not supported with this QEMU binary"));
 | 
			
		||||
         return NULL;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
@@ -6153,6 +6155,7 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
 | 
			
		||||
     unsigned int sockets = 0;
 | 
			
		||||
     unsigned int cores = 0;
 | 
			
		||||
     unsigned int threads = 0;
 | 
			
		||||
+    unsigned int maxcpus = 0;
 | 
			
		||||
     int i;
 | 
			
		||||
     int nkws;
 | 
			
		||||
     char **kws;
 | 
			
		||||
@@ -6180,12 +6183,14 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
 | 
			
		||||
                 cores = n;
 | 
			
		||||
             else if (STREQ(kws[i], "threads"))
 | 
			
		||||
                 threads = n;
 | 
			
		||||
+            else if (STREQ(kws[i], "maxcpus"))
 | 
			
		||||
+                maxcpus = n;
 | 
			
		||||
             else
 | 
			
		||||
                 goto syntax;
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    dom->maxvcpus = dom->vcpus;
 | 
			
		||||
+    dom->maxvcpus = maxcpus ? maxcpus : dom->vcpus;
 | 
			
		||||
 | 
			
		||||
     if (sockets && cores && threads) {
 | 
			
		||||
         virCPUDefPtr cpu;
 | 
			
		||||
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
 | 
			
		||||
index 4f9ec84..d941b0b 100644
 | 
			
		||||
--- a/tests/qemuargv2xmltest.c
 | 
			
		||||
+++ b/tests/qemuargv2xmltest.c
 | 
			
		||||
@@ -221,6 +221,8 @@ mymain(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
     DO_TEST("hostdev-pci-address");
 | 
			
		||||
 | 
			
		||||
+    DO_TEST("smp");
 | 
			
		||||
+
 | 
			
		||||
     DO_TEST_FULL("restore-v1", 0, "stdio");
 | 
			
		||||
     DO_TEST_FULL("restore-v2", 0, "stdio");
 | 
			
		||||
     DO_TEST_FULL("restore-v2", 0, "exec:cat");
 | 
			
		||||
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smp.args b/tests/qemuxml2argvdata/qemuxml2argv-smp.args
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..3ec8f15
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smp.args
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1,maxcpus=2,sockets=2,cores=1,threads=1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
 | 
			
		||||
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
 | 
			
		||||
index 92d5b18..551d6c4 100644
 | 
			
		||||
--- a/tests/qemuxml2argvtest.c
 | 
			
		||||
+++ b/tests/qemuxml2argvtest.c
 | 
			
		||||
@@ -385,6 +385,8 @@ mymain(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
     DO_TEST("qemu-ns", 0);
 | 
			
		||||
 | 
			
		||||
+    DO_TEST("smp", QEMUD_CMD_FLAG_SMP_TOPOLOGY);
 | 
			
		||||
+
 | 
			
		||||
     free(driver.stateDir);
 | 
			
		||||
     virCapabilitiesFree(driver.caps);
 | 
			
		||||
 | 
			
		||||
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
 | 
			
		||||
index a33d435..cdc4390 100644
 | 
			
		||||
--- a/tests/qemuxml2xmltest.c
 | 
			
		||||
+++ b/tests/qemuxml2xmltest.c
 | 
			
		||||
@@ -180,6 +180,8 @@ mymain(int argc, char **argv)
 | 
			
		||||
     DO_TEST("encrypted-disk");
 | 
			
		||||
     DO_TEST("memtune");
 | 
			
		||||
 | 
			
		||||
+    DO_TEST("smp");
 | 
			
		||||
+
 | 
			
		||||
     /* These tests generate different XML */
 | 
			
		||||
     DO_TEST_DIFFERENT("balloon-device-auto");
 | 
			
		||||
     DO_TEST_DIFFERENT("channel-virtio-auto");
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,169 @@
 | 
			
		||||
From 28a3605906385cba43df77051dc26e865f237b09 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Wed, 29 Sep 2010 17:40:45 -0600
 | 
			
		||||
Subject: [PATCH 11/15] vcpu: complete vcpu support in qemu driver
 | 
			
		||||
 | 
			
		||||
* src/qemu/qemu_driver.c (qemudDomainSetVcpusFlags)
 | 
			
		||||
(qemudDomainGetVcpusFlags): Support all feasible flag
 | 
			
		||||
combinations.
 | 
			
		||||
---
 | 
			
		||||
 src/qemu/qemu_driver.c |  100 ++++++++++++++++++++++++++++++++++++++++-------
 | 
			
		||||
 1 files changed, 85 insertions(+), 15 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 | 
			
		||||
index c66dc04..a9e057f 100644
 | 
			
		||||
--- a/src/qemu/qemu_driver.c
 | 
			
		||||
+++ b/src/qemu/qemu_driver.c
 | 
			
		||||
@@ -5941,13 +5941,27 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
 {
 | 
			
		||||
     struct qemud_driver *driver = dom->conn->privateData;
 | 
			
		||||
     virDomainObjPtr vm;
 | 
			
		||||
+    virDomainDefPtr def;
 | 
			
		||||
     const char * type;
 | 
			
		||||
     int max;
 | 
			
		||||
     int ret = -1;
 | 
			
		||||
 | 
			
		||||
-    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
-        qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
-                        flags);
 | 
			
		||||
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_CONFIG |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
 | 
			
		||||
+
 | 
			
		||||
+    /* At least one of LIVE or CONFIG must be set.  MAXIMUM cannot be
 | 
			
		||||
+     * mixed with LIVE.  */
 | 
			
		||||
+    if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
 | 
			
		||||
+        (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
 | 
			
		||||
+         (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
 | 
			
		||||
+        qemuReportError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                        _("invalid flag combination: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
 | 
			
		||||
+        qemuReportError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                        _("argument out of range: %d"), nvcpus);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
@@ -5966,7 +5980,7 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
     if (qemuDomainObjBeginJob(vm) < 0)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
 | 
			
		||||
-    if (!virDomainObjIsActive(vm)) {
 | 
			
		||||
+    if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
 | 
			
		||||
         qemuReportError(VIR_ERR_OPERATION_INVALID,
 | 
			
		||||
                          "%s", _("domain is not running"));
 | 
			
		||||
         goto endjob;
 | 
			
		||||
@@ -5985,6 +5999,11 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
         goto endjob;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
+    if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
 | 
			
		||||
+        VIR_DOMAIN_VCPU_LIVE && vm->def->maxvcpus < max) {
 | 
			
		||||
+        max = vm->def->maxvcpus;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if (nvcpus > max) {
 | 
			
		||||
         qemuReportError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
                         _("requested vcpus is greater than max allowable"
 | 
			
		||||
@@ -5992,7 +6011,49 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
         goto endjob;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    ret = qemudDomainHotplugVcpus(vm, nvcpus);
 | 
			
		||||
+    switch (flags) {
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
 | 
			
		||||
+        def = vm->def;
 | 
			
		||||
+        if (virDomainObjIsActive(vm)) {
 | 
			
		||||
+            if (vm->newDef)
 | 
			
		||||
+                def = vm->newDef;
 | 
			
		||||
+            else{
 | 
			
		||||
+                qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                                _("no persistent state"));
 | 
			
		||||
+                goto endjob;
 | 
			
		||||
+            }
 | 
			
		||||
+        }
 | 
			
		||||
+        def->maxvcpus = nvcpus;
 | 
			
		||||
+        if (nvcpus < vm->newDef->vcpus)
 | 
			
		||||
+            def->vcpus = nvcpus;
 | 
			
		||||
+        ret = 0;
 | 
			
		||||
+        break;
 | 
			
		||||
+
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_CONFIG:
 | 
			
		||||
+        def = vm->def;
 | 
			
		||||
+        if (virDomainObjIsActive(vm)) {
 | 
			
		||||
+            if (vm->newDef)
 | 
			
		||||
+                def = vm->newDef;
 | 
			
		||||
+            else {
 | 
			
		||||
+                qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                                _("no persistent state"));
 | 
			
		||||
+                goto endjob;
 | 
			
		||||
+            }
 | 
			
		||||
+        }
 | 
			
		||||
+        def->vcpus = nvcpus;
 | 
			
		||||
+        ret = 0;
 | 
			
		||||
+        break;
 | 
			
		||||
+
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_LIVE:
 | 
			
		||||
+        ret = qemudDomainHotplugVcpus(vm, nvcpus);
 | 
			
		||||
+        break;
 | 
			
		||||
+
 | 
			
		||||
+    case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
 | 
			
		||||
+        ret = qemudDomainHotplugVcpus(vm, nvcpus);
 | 
			
		||||
+        if (ret == 0 && vm->newDef)
 | 
			
		||||
+            vm->newDef->vcpus = nvcpus;
 | 
			
		||||
+        break;
 | 
			
		||||
+    }
 | 
			
		||||
 | 
			
		||||
 endjob:
 | 
			
		||||
     if (qemuDomainObjEndJob(vm) == 0)
 | 
			
		||||
@@ -6171,12 +6232,17 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     struct qemud_driver *driver = dom->conn->privateData;
 | 
			
		||||
     virDomainObjPtr vm;
 | 
			
		||||
-    const char *type;
 | 
			
		||||
+    virDomainDefPtr def;
 | 
			
		||||
     int ret = -1;
 | 
			
		||||
 | 
			
		||||
-    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
-        qemuReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
-                        flags);
 | 
			
		||||
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_CONFIG |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
 | 
			
		||||
+
 | 
			
		||||
+    /* Exactly one of LIVE or CONFIG must be set.  */
 | 
			
		||||
+    if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
 | 
			
		||||
+        qemuReportError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                        _("invalid flag combination: (0x%x)"), flags);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
@@ -6192,14 +6258,18 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
 | 
			
		||||
-        qemuReportError(VIR_ERR_INTERNAL_ERROR,
 | 
			
		||||
-                        _("unknown virt type in domain definition '%d'"),
 | 
			
		||||
-                        vm->def->virtType);
 | 
			
		||||
-        goto cleanup;
 | 
			
		||||
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        if (!virDomainObjIsActive(vm)) {
 | 
			
		||||
+            qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                            _("domain not active"));
 | 
			
		||||
+            goto cleanup;
 | 
			
		||||
+        }
 | 
			
		||||
+        def = vm->def;
 | 
			
		||||
+    } else {
 | 
			
		||||
+        def = vm->newDef ? vm->newDef : vm->def;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    ret = qemudGetMaxVCPUs(NULL, type);
 | 
			
		||||
+    ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
 | 
			
		||||
 | 
			
		||||
 cleanup:
 | 
			
		||||
     if (vm)
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,294 @@
 | 
			
		||||
From 0fab10e5ed971ab4f960a53e9640b0672f4b8ac3 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Tue, 5 Oct 2010 08:18:52 -0600
 | 
			
		||||
Subject: [PATCH 12/15] vcpu: improve vcpu support in xen command line
 | 
			
		||||
 | 
			
		||||
This patch series focuses on xendConfigVersion 2 (xm_internal) and 3
 | 
			
		||||
(xend_internal), but leaves out changes for xenapi drivers.
 | 
			
		||||
 | 
			
		||||
See this link for more details about vcpu_avail for xm usage.
 | 
			
		||||
http://lists.xensource.com/archives/html/xen-devel/2009-11/msg01061.html
 | 
			
		||||
 | 
			
		||||
This relies on the fact that def->maxvcpus can be at most 32 with xen.
 | 
			
		||||
 | 
			
		||||
* src/xen/xend_internal.c (xenDaemonParseSxpr)
 | 
			
		||||
(sexpr_to_xend_domain_info, xenDaemonFormatSxpr): Use vcpu_avail
 | 
			
		||||
when current vcpus is less than maximum.
 | 
			
		||||
* src/xen/xm_internal.c (xenXMDomainConfigParse)
 | 
			
		||||
(xenXMDomainConfigFormat): Likewise.
 | 
			
		||||
* tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr: New file.
 | 
			
		||||
* tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr: Likewise.
 | 
			
		||||
* tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml: Likewise.
 | 
			
		||||
* tests/xmconfigdata/test-paravirt-vcpu.cfg: Likewise.
 | 
			
		||||
* tests/xmconfigdata/test-paravirt-vcpu.xml: Likewise.
 | 
			
		||||
* tests/xml2sexprtest.c (mymain): New test.
 | 
			
		||||
* tests/sexpr2xmltest.c (mymain): Likewise.
 | 
			
		||||
* tests/xmconfigtest.c (mymain): Likewise.
 | 
			
		||||
---
 | 
			
		||||
 src/xen/xend_internal.c                      |   19 +++++++++++++--
 | 
			
		||||
 src/xen/xm_internal.c                        |   10 ++++++-
 | 
			
		||||
 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr |    1 +
 | 
			
		||||
 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml   |   27 +++++++++++++++++++++
 | 
			
		||||
 tests/sexpr2xmltest.c                        |    1 +
 | 
			
		||||
 tests/xmconfigdata/test-paravirt-vcpu.cfg    |   17 +++++++++++++
 | 
			
		||||
 tests/xmconfigdata/test-paravirt-vcpu.xml    |   32 ++++++++++++++++++++++++++
 | 
			
		||||
 tests/xmconfigtest.c                         |    1 +
 | 
			
		||||
 tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr |    1 +
 | 
			
		||||
 tests/xml2sexprtest.c                        |    1 +
 | 
			
		||||
 10 files changed, 105 insertions(+), 5 deletions(-)
 | 
			
		||||
 create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
 | 
			
		||||
 create mode 100644 tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
 | 
			
		||||
 create mode 100644 tests/xmconfigdata/test-paravirt-vcpu.cfg
 | 
			
		||||
 create mode 100644 tests/xmconfigdata/test-paravirt-vcpu.xml
 | 
			
		||||
 create mode 100644 tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
 | 
			
		||||
 | 
			
		||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
 | 
			
		||||
index 456b477..dfc6415 100644
 | 
			
		||||
--- a/src/xen/xend_internal.c
 | 
			
		||||
+++ b/src/xen/xend_internal.c
 | 
			
		||||
@@ -44,6 +44,7 @@
 | 
			
		||||
 #include "xen_hypervisor.h"
 | 
			
		||||
 #include "xs_internal.h" /* To extract VNC port & Serial console TTY */
 | 
			
		||||
 #include "memory.h"
 | 
			
		||||
+#include "count-one-bits.h"
 | 
			
		||||
 | 
			
		||||
 /* required for cpumap_t */
 | 
			
		||||
 #include <xen/dom0_ops.h>
 | 
			
		||||
@@ -2191,7 +2192,9 @@ xenDaemonParseSxpr(virConnectPtr conn,
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     def->maxvcpus = sexpr_int(root, "domain/vcpus");
 | 
			
		||||
-    def->vcpus = def->maxvcpus;
 | 
			
		||||
+    def->vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
 | 
			
		||||
+    if (!def->vcpus || def->maxvcpus < def->vcpus)
 | 
			
		||||
+        def->vcpus = def->maxvcpus;
 | 
			
		||||
 | 
			
		||||
     tmp = sexpr_node(root, "domain/on_poweroff");
 | 
			
		||||
     if (tmp != NULL) {
 | 
			
		||||
@@ -2433,7 +2436,7 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
 | 
			
		||||
                           virDomainInfoPtr info)
 | 
			
		||||
 {
 | 
			
		||||
     const char *flags;
 | 
			
		||||
-
 | 
			
		||||
+    int vcpus;
 | 
			
		||||
 | 
			
		||||
     if ((root == NULL) || (info == NULL))
 | 
			
		||||
         return (-1);
 | 
			
		||||
@@ -2464,7 +2467,11 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
 | 
			
		||||
             info->state = VIR_DOMAIN_NOSTATE;
 | 
			
		||||
     }
 | 
			
		||||
     info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000;
 | 
			
		||||
-    info->nrVirtCpu = sexpr_int(root, "domain/vcpus");
 | 
			
		||||
+    vcpus = sexpr_int(root, "domain/vcpus");
 | 
			
		||||
+    info->nrVirtCpu = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
 | 
			
		||||
+    if (!info->nrVirtCpu || vcpus < info->nrVirtCpu)
 | 
			
		||||
+        info->nrVirtCpu = vcpus;
 | 
			
		||||
+
 | 
			
		||||
     return (0);
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
@@ -5668,6 +5675,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 | 
			
		||||
     virBufferAsprintf(&buf, "(memory %lu)(maxmem %lu)",
 | 
			
		||||
                       def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
 | 
			
		||||
     virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
 | 
			
		||||
+    /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is 32.  */
 | 
			
		||||
+    if (def->vcpus < def->maxvcpus)
 | 
			
		||||
+        virBufferAsprintf(&buf, "(vcpu_avail %u)", (1U << def->vcpus) - 1);
 | 
			
		||||
 | 
			
		||||
     if (def->cpumask) {
 | 
			
		||||
         char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
 | 
			
		||||
@@ -5763,6 +5773,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 | 
			
		||||
                 virBufferAsprintf(&buf, "(kernel '%s')", def->os.loader);
 | 
			
		||||
 | 
			
		||||
             virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus);
 | 
			
		||||
+            if (def->vcpus < def->maxvcpus)
 | 
			
		||||
+                virBufferAsprintf(&buf, "(vcpu_avail %u)",
 | 
			
		||||
+                                  (1U << def->vcpus) - 1);
 | 
			
		||||
 | 
			
		||||
             for (i = 0 ; i < def->os.nBootDevs ; i++) {
 | 
			
		||||
                 switch (def->os.bootDevs[i]) {
 | 
			
		||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
 | 
			
		||||
index bf20a64..f7121ab 100644
 | 
			
		||||
--- a/src/xen/xm_internal.c
 | 
			
		||||
+++ b/src/xen/xm_internal.c
 | 
			
		||||
@@ -46,6 +46,7 @@
 | 
			
		||||
 #include "util.h"
 | 
			
		||||
 #include "memory.h"
 | 
			
		||||
 #include "logging.h"
 | 
			
		||||
+#include "count-one-bits.h"
 | 
			
		||||
 | 
			
		||||
 #define VIR_FROM_THIS VIR_FROM_XENXM
 | 
			
		||||
 | 
			
		||||
@@ -772,10 +773,12 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
 | 
			
		||||
     def->mem.max_balloon *= 1024;
 | 
			
		||||
 | 
			
		||||
     if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
 | 
			
		||||
-        (unsigned short) count != count)
 | 
			
		||||
+        MAX_VIRT_CPUS < count)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
     def->maxvcpus = count;
 | 
			
		||||
-    def->vcpus = def->maxvcpus;
 | 
			
		||||
+    if (xenXMConfigGetULong(conf, "vcpu_avail", &count, -1) < 0)
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    def->vcpus = MIN(count_one_bits(count), def->maxvcpus);
 | 
			
		||||
 | 
			
		||||
     if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
 | 
			
		||||
         goto cleanup;
 | 
			
		||||
@@ -2246,6 +2249,9 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
 | 
			
		||||
 | 
			
		||||
     if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
 | 
			
		||||
         goto no_memory;
 | 
			
		||||
+    if (def->vcpus < def->maxvcpus &&
 | 
			
		||||
+        xenXMConfigSetInt(conf, "vcpu_avail", (1U << def->vcpus) - 1) < 0)
 | 
			
		||||
+        goto no_memory;
 | 
			
		||||
 | 
			
		||||
     if ((def->cpumask != NULL) &&
 | 
			
		||||
         ((cpus = virDomainCpuSetFormat(def->cpumask,
 | 
			
		||||
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..2be6822
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
+(domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os  ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w'))))
 | 
			
		||||
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..0d6bf11
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml
 | 
			
		||||
@@ -0,0 +1,27 @@
 | 
			
		||||
+<domain type='xen' id='6'>
 | 
			
		||||
+  <name>pvtest</name>
 | 
			
		||||
+  <uuid>596a5d21-71f4-8fb2-e068-e2386a5c413e</uuid>
 | 
			
		||||
+  <memory>430080</memory>
 | 
			
		||||
+  <currentMemory>430080</currentMemory>
 | 
			
		||||
+  <vcpu current='2'>4</vcpu>
 | 
			
		||||
+  <os>
 | 
			
		||||
+    <type>linux</type>
 | 
			
		||||
+    <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
 | 
			
		||||
+    <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
 | 
			
		||||
+    <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os  </cmdline>
 | 
			
		||||
+  </os>
 | 
			
		||||
+  <clock offset='utc'/>
 | 
			
		||||
+  <on_poweroff>destroy</on_poweroff>
 | 
			
		||||
+  <on_reboot>destroy</on_reboot>
 | 
			
		||||
+  <on_crash>destroy</on_crash>
 | 
			
		||||
+  <devices>
 | 
			
		||||
+    <disk type='file' device='disk'>
 | 
			
		||||
+      <driver name='file'/>
 | 
			
		||||
+      <source file='/root/some.img'/>
 | 
			
		||||
+      <target dev='xvda' bus='xen'/>
 | 
			
		||||
+    </disk>
 | 
			
		||||
+    <console type='pty'>
 | 
			
		||||
+      <target type='xen' port='0'/>
 | 
			
		||||
+    </console>
 | 
			
		||||
+  </devices>
 | 
			
		||||
+</domain>
 | 
			
		||||
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
 | 
			
		||||
index d62b44f..f100dd8 100644
 | 
			
		||||
--- a/tests/sexpr2xmltest.c
 | 
			
		||||
+++ b/tests/sexpr2xmltest.c
 | 
			
		||||
@@ -132,6 +132,7 @@ mymain(int argc, char **argv)
 | 
			
		||||
     DO_TEST("pv-vfb-type-crash", "pv-vfb-type-crash", 3);
 | 
			
		||||
     DO_TEST("fv-autoport", "fv-autoport", 3);
 | 
			
		||||
     DO_TEST("pv-bootloader", "pv-bootloader", 1);
 | 
			
		||||
+    DO_TEST("pv-vcpus", "pv-vcpus", 1);
 | 
			
		||||
 | 
			
		||||
     DO_TEST("disk-file", "disk-file", 2);
 | 
			
		||||
     DO_TEST("disk-block", "disk-block", 2);
 | 
			
		||||
diff --git a/tests/xmconfigdata/test-paravirt-vcpu.cfg b/tests/xmconfigdata/test-paravirt-vcpu.cfg
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..24c78f4
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/xmconfigdata/test-paravirt-vcpu.cfg
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
+name = "XenGuest1"
 | 
			
		||||
+uuid = "c7a5fdb0-cdaf-9455-926a-d65c16db1809"
 | 
			
		||||
+maxmem = 579
 | 
			
		||||
+memory = 394
 | 
			
		||||
+vcpus = 4
 | 
			
		||||
+vcpu_avail = 3
 | 
			
		||||
+bootloader = "/usr/bin/pygrub"
 | 
			
		||||
+on_poweroff = "destroy"
 | 
			
		||||
+on_reboot = "restart"
 | 
			
		||||
+on_crash = "restart"
 | 
			
		||||
+sdl = 0
 | 
			
		||||
+vnc = 1
 | 
			
		||||
+vncunused = 1
 | 
			
		||||
+vnclisten = "127.0.0.1"
 | 
			
		||||
+vncpasswd = "123poi"
 | 
			
		||||
+disk = [ "phy:/dev/HostVG/XenGuest1,xvda,w" ]
 | 
			
		||||
+vif = [ "mac=00:16:3e:66:94:9c,bridge=br0,script=vif-bridge" ]
 | 
			
		||||
diff --git a/tests/xmconfigdata/test-paravirt-vcpu.xml b/tests/xmconfigdata/test-paravirt-vcpu.xml
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..0be9456
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/xmconfigdata/test-paravirt-vcpu.xml
 | 
			
		||||
@@ -0,0 +1,32 @@
 | 
			
		||||
+<domain type='xen'>
 | 
			
		||||
+  <name>XenGuest1</name>
 | 
			
		||||
+  <uuid>c7a5fdb0-cdaf-9455-926a-d65c16db1809</uuid>
 | 
			
		||||
+  <memory>592896</memory>
 | 
			
		||||
+  <currentMemory>403456</currentMemory>
 | 
			
		||||
+  <vcpu current='2'>4</vcpu>
 | 
			
		||||
+  <bootloader>/usr/bin/pygrub</bootloader>
 | 
			
		||||
+  <os>
 | 
			
		||||
+    <type arch='i686' machine='xenpv'>linux</type>
 | 
			
		||||
+  </os>
 | 
			
		||||
+  <clock offset='utc'/>
 | 
			
		||||
+  <on_poweroff>destroy</on_poweroff>
 | 
			
		||||
+  <on_reboot>restart</on_reboot>
 | 
			
		||||
+  <on_crash>restart</on_crash>
 | 
			
		||||
+  <devices>
 | 
			
		||||
+    <disk type='block' device='disk'>
 | 
			
		||||
+      <driver name='phy'/>
 | 
			
		||||
+      <source dev='/dev/HostVG/XenGuest1'/>
 | 
			
		||||
+      <target dev='xvda' bus='xen'/>
 | 
			
		||||
+    </disk>
 | 
			
		||||
+    <interface type='bridge'>
 | 
			
		||||
+      <mac address='00:16:3e:66:94:9c'/>
 | 
			
		||||
+      <source bridge='br0'/>
 | 
			
		||||
+      <script path='vif-bridge'/>
 | 
			
		||||
+    </interface>
 | 
			
		||||
+    <console type='pty'>
 | 
			
		||||
+      <target type='xen' port='0'/>
 | 
			
		||||
+    </console>
 | 
			
		||||
+    <input type='mouse' bus='xen'/>
 | 
			
		||||
+    <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
 | 
			
		||||
+  </devices>
 | 
			
		||||
+</domain>
 | 
			
		||||
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
 | 
			
		||||
index 221b322..ea00747 100644
 | 
			
		||||
--- a/tests/xmconfigtest.c
 | 
			
		||||
+++ b/tests/xmconfigtest.c
 | 
			
		||||
@@ -210,6 +210,7 @@ mymain(int argc, char **argv)
 | 
			
		||||
     DO_TEST("paravirt-new-pvfb-vncdisplay", 3);
 | 
			
		||||
     DO_TEST("paravirt-net-e1000", 3);
 | 
			
		||||
     DO_TEST("paravirt-net-vifname", 3);
 | 
			
		||||
+    DO_TEST("paravirt-vcpu", 2);
 | 
			
		||||
     DO_TEST("fullvirt-old-cdrom", 1);
 | 
			
		||||
     DO_TEST("fullvirt-new-cdrom", 2);
 | 
			
		||||
     DO_TEST("fullvirt-utc", 2);
 | 
			
		||||
diff --git a/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..e886545
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/tests/xml2sexprdata/xml2sexpr-pv-vcpus.sexpr
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
+(vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d21-71f4-8fb2-e068-e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os  ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w'))))
 | 
			
		||||
\ No newline at end of file
 | 
			
		||||
diff --git a/tests/xml2sexprtest.c b/tests/xml2sexprtest.c
 | 
			
		||||
index 77cf760..9cf8d39 100644
 | 
			
		||||
--- a/tests/xml2sexprtest.c
 | 
			
		||||
+++ b/tests/xml2sexprtest.c
 | 
			
		||||
@@ -118,6 +118,7 @@ mymain(int argc, char **argv)
 | 
			
		||||
     DO_TEST("pv-vfb-new", "pv-vfb-new", "pvtest", 3);
 | 
			
		||||
     DO_TEST("pv-vfb-new-auto", "pv-vfb-new-auto", "pvtest", 3);
 | 
			
		||||
     DO_TEST("pv-bootloader", "pv-bootloader", "pvtest", 1);
 | 
			
		||||
+    DO_TEST("pv-vcpus", "pv-vcpus", "pvtest", 1);
 | 
			
		||||
 | 
			
		||||
     DO_TEST("disk-file", "disk-file", "pvtest", 2);
 | 
			
		||||
     DO_TEST("disk-block", "disk-block", "pvtest", 2);
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										216
									
								
								docs/api_extension/0013-improve-getting-xen-vcpu-counts.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								docs/api_extension/0013-improve-getting-xen-vcpu-counts.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,216 @@
 | 
			
		||||
From 290ea33111be7bdf1f1381b90de33eb0e67c1a15 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Wed, 6 Oct 2010 17:54:41 -0600
 | 
			
		||||
Subject: [PATCH 13/15] vcpu: improve support for getting xen vcpu counts
 | 
			
		||||
 | 
			
		||||
* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Support
 | 
			
		||||
more flags.
 | 
			
		||||
* src/xen/xend_internal.h (xenDaemonDomainGetVcpusFlags): New
 | 
			
		||||
prototype.
 | 
			
		||||
* src/xen/xm_internal.h (xenXMDomainGetVcpusFlags): Likewise.
 | 
			
		||||
* src/xen/xend_internal.c (virDomainGetVcpusFlags): New function.
 | 
			
		||||
* src/xen/xm_internal.c (xenXMDomainGetVcpusFlags): Likewise.
 | 
			
		||||
---
 | 
			
		||||
 src/xen/xen_driver.c    |   31 +++++++++++++++++++--------
 | 
			
		||||
 src/xen/xend_internal.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 src/xen/xend_internal.h |    2 +
 | 
			
		||||
 src/xen/xm_internal.c   |   47 ++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 src/xen/xm_internal.h   |    1 +
 | 
			
		||||
 5 files changed, 124 insertions(+), 9 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
 | 
			
		||||
index d6c9c57..fe2ff86 100644
 | 
			
		||||
--- a/src/xen/xen_driver.c
 | 
			
		||||
+++ b/src/xen/xen_driver.c
 | 
			
		||||
@@ -1142,20 +1142,33 @@ static int
 | 
			
		||||
 xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     GET_PRIVATE(dom->conn);
 | 
			
		||||
-    int i, ret;
 | 
			
		||||
+    int ret;
 | 
			
		||||
 | 
			
		||||
-    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
-        xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
-                        flags);
 | 
			
		||||
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_CONFIG |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
 | 
			
		||||
+
 | 
			
		||||
+    /* Exactly one of LIVE or CONFIG must be set.  */
 | 
			
		||||
+    if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
 | 
			
		||||
+        xenUnifiedError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                        _("invalid flag combination: (0x%x)"), flags);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
-    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
 | 
			
		||||
-        if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
 | 
			
		||||
-            ret = drivers[i]->domainGetMaxVcpus (dom);
 | 
			
		||||
-            if (ret != 0) return ret;
 | 
			
		||||
-        }
 | 
			
		||||
+    if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
 | 
			
		||||
+        ret = xenDaemonDomainGetVcpusFlags(dom, flags);
 | 
			
		||||
+        if (ret != -2)
 | 
			
		||||
+            return ret;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
 | 
			
		||||
+        ret = xenXMDomainGetVcpusFlags(dom, flags);
 | 
			
		||||
+        if (ret != -2)
 | 
			
		||||
+            return ret;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM))
 | 
			
		||||
+        return xenHypervisorGetVcpuMax(dom);
 | 
			
		||||
 | 
			
		||||
+    xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
 | 
			
		||||
     return -1;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
 | 
			
		||||
index dfc6415..3642296 100644
 | 
			
		||||
--- a/src/xen/xend_internal.c
 | 
			
		||||
+++ b/src/xen/xend_internal.c
 | 
			
		||||
@@ -3620,6 +3620,58 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
+ * xenDaemonDomainGetVcpusFlags:
 | 
			
		||||
+ * @domain: pointer to domain object
 | 
			
		||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
 | 
			
		||||
+ *
 | 
			
		||||
+ * Extract information about virtual CPUs of domain according to flags.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns the number of vcpus on success, -1 if an error message was
 | 
			
		||||
+ * issued, and -2 if the unified driver should keep trying.
 | 
			
		||||
+
 | 
			
		||||
+ */
 | 
			
		||||
+int
 | 
			
		||||
+xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    struct sexpr *root;
 | 
			
		||||
+    int ret;
 | 
			
		||||
+    xenUnifiedPrivatePtr priv;
 | 
			
		||||
+
 | 
			
		||||
+    if (domain == NULL || domain->conn == NULL || domain->name == NULL) {
 | 
			
		||||
+        virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
 | 
			
		||||
+
 | 
			
		||||
+    /* If xendConfigVersion is 2, then we can only report _LIVE (and
 | 
			
		||||
+     * xm_internal reports _CONFIG).  If it is 3, then _LIVE and
 | 
			
		||||
+     * _CONFIG are always in sync for a running system.  */
 | 
			
		||||
+    if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
 | 
			
		||||
+        return -2;
 | 
			
		||||
+    if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) {
 | 
			
		||||
+        virXendError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                     _("domain not active"));
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
 | 
			
		||||
+    if (root == NULL)
 | 
			
		||||
+        return -1;
 | 
			
		||||
+
 | 
			
		||||
+    ret = sexpr_int(root, "domain/vcpus");
 | 
			
		||||
+    if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM)) {
 | 
			
		||||
+        int vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
 | 
			
		||||
+        if (vcpus)
 | 
			
		||||
+            ret = MIN(vcpus, ret);
 | 
			
		||||
+    }
 | 
			
		||||
+    if (!ret)
 | 
			
		||||
+        ret = -2;
 | 
			
		||||
+    sexpr_free(root);
 | 
			
		||||
+    return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
  * virDomainGetVcpus:
 | 
			
		||||
  * @domain: pointer to domain object, or NULL for Domain0
 | 
			
		||||
  * @info: pointer to an array of virVcpuInfo structures (OUT)
 | 
			
		||||
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
 | 
			
		||||
index c757716..923cebd 100644
 | 
			
		||||
--- a/src/xen/xend_internal.h
 | 
			
		||||
+++ b/src/xen/xend_internal.h
 | 
			
		||||
@@ -155,6 +155,8 @@ int	xenDaemonDomainPinVcpu		(virDomainPtr domain,
 | 
			
		||||
                                          unsigned int vcpu,
 | 
			
		||||
                                          unsigned char *cpumap,
 | 
			
		||||
                                          int maplen);
 | 
			
		||||
+int     xenDaemonDomainGetVcpusFlags    (virDomainPtr domain,
 | 
			
		||||
+                                         unsigned int flags);
 | 
			
		||||
 int	xenDaemonDomainGetVcpus		(virDomainPtr domain,
 | 
			
		||||
                                          virVcpuInfoPtr info,
 | 
			
		||||
                                          int maxinfo,
 | 
			
		||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
 | 
			
		||||
index f7121ab..4ea4245 100644
 | 
			
		||||
--- a/src/xen/xm_internal.c
 | 
			
		||||
+++ b/src/xen/xm_internal.c
 | 
			
		||||
@@ -1671,6 +1671,53 @@ cleanup:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
+ * xenXMDomainGetVcpusFlags:
 | 
			
		||||
+ * @domain: pointer to domain object
 | 
			
		||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
 | 
			
		||||
+ *
 | 
			
		||||
+ * Extract information about virtual CPUs of domain according to flags.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns the number of vcpus on success, -1 if an error message was
 | 
			
		||||
+ * issued, and -2 if the unified driver should keep trying.
 | 
			
		||||
+ */
 | 
			
		||||
+int
 | 
			
		||||
+xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    xenUnifiedPrivatePtr priv;
 | 
			
		||||
+    const char *filename;
 | 
			
		||||
+    xenXMConfCachePtr entry;
 | 
			
		||||
+    int ret = -2;
 | 
			
		||||
+
 | 
			
		||||
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
 | 
			
		||||
+        xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (domain->id != -1)
 | 
			
		||||
+        return -2;
 | 
			
		||||
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        xenXMError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    priv = domain->conn->privateData;
 | 
			
		||||
+    xenUnifiedLock(priv);
 | 
			
		||||
+
 | 
			
		||||
+    if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+
 | 
			
		||||
+    if (!(entry = virHashLookup(priv->configCache, filename)))
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+
 | 
			
		||||
+    ret = ((flags & VIR_DOMAIN_VCPU_MAXIMUM) ? entry->def->maxvcpus
 | 
			
		||||
+           : entry->def->vcpus);
 | 
			
		||||
+
 | 
			
		||||
+cleanup:
 | 
			
		||||
+    xenUnifiedUnlock(priv);
 | 
			
		||||
+    return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
  * xenXMDomainPinVcpu:
 | 
			
		||||
  * @domain: pointer to domain object
 | 
			
		||||
  * @vcpu: virtual CPU number (reserved)
 | 
			
		||||
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
 | 
			
		||||
index 3ad3456..3295fbd 100644
 | 
			
		||||
--- a/src/xen/xm_internal.h
 | 
			
		||||
+++ b/src/xen/xm_internal.h
 | 
			
		||||
@@ -45,6 +45,7 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
 | 
			
		||||
 int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
 | 
			
		||||
 unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
 | 
			
		||||
 int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
 | 
			
		||||
+int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
 | 
			
		||||
 int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
 | 
			
		||||
                        unsigned char *cpumap, int maplen);
 | 
			
		||||
 virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname);
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										342
									
								
								docs/api_extension/0014-improve-setting-xen-vcpu-counts.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								docs/api_extension/0014-improve-setting-xen-vcpu-counts.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,342 @@
 | 
			
		||||
From e443a003129a172a7332f3cb6e40b3c39363ed5e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Thu, 14 Oct 2010 16:17:18 -0600
 | 
			
		||||
Subject: [PATCH 14/15] vcpu: improve support for setting xen vcpu counts
 | 
			
		||||
 | 
			
		||||
Tested with RHEL 5.6 (xendConfigVersion 2, where xend_internal
 | 
			
		||||
controls live domains and xm_internal controls inactive domains).
 | 
			
		||||
Hopefully this works with xendConfigVersion 3 (where xend_internal
 | 
			
		||||
controls everything).
 | 
			
		||||
 | 
			
		||||
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpusFlags): Support
 | 
			
		||||
more flags.
 | 
			
		||||
(xenUnifiedGetMaxVcpus): Export.
 | 
			
		||||
* src/xen/xm_internal.h (xenXMDomainSetVcpusFlags): New prototype.
 | 
			
		||||
* src/xen/xend_internal.h (xenDaemonDomainSetVcpusFlags): Likewise.
 | 
			
		||||
* src/xen/xen_driver.h (xenUnifiedGetMaxVcpus): Likewise.
 | 
			
		||||
* src/xen/xm_internal.c (xenXMDomainSetVcpusFlags): New function.
 | 
			
		||||
* src/xen/xend_internal.c (xenDaemonDomainSetVcpusFlags): Likewise.
 | 
			
		||||
---
 | 
			
		||||
 src/xen/xen_driver.c    |   60 ++++++++++++++++++++++++---------
 | 
			
		||||
 src/xen/xen_driver.h    |    1 +
 | 
			
		||||
 src/xen/xend_internal.c |   76 +++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 src/xen/xend_internal.h |    3 ++
 | 
			
		||||
 src/xen/xm_internal.c   |   83 +++++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 src/xen/xm_internal.h   |    2 +
 | 
			
		||||
 6 files changed, 208 insertions(+), 17 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
 | 
			
		||||
index fe2ff86..66e8518 100644
 | 
			
		||||
--- a/src/xen/xen_driver.c
 | 
			
		||||
+++ b/src/xen/xen_driver.c
 | 
			
		||||
@@ -508,7 +508,7 @@ xenUnifiedIsSecure(virConnectPtr conn)
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
-static int
 | 
			
		||||
+int
 | 
			
		||||
 xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
 | 
			
		||||
 {
 | 
			
		||||
     GET_PRIVATE(conn);
 | 
			
		||||
@@ -1073,36 +1073,62 @@ xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
 | 
			
		||||
                                unsigned int flags)
 | 
			
		||||
 {
 | 
			
		||||
     GET_PRIVATE(dom->conn);
 | 
			
		||||
-    int i;
 | 
			
		||||
+    int ret;
 | 
			
		||||
+
 | 
			
		||||
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_CONFIG |
 | 
			
		||||
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
 | 
			
		||||
 | 
			
		||||
-    if (flags != VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
-        xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
 | 
			
		||||
-                        flags);
 | 
			
		||||
+    /* At least one of LIVE or CONFIG must be set.  MAXIMUM cannot be
 | 
			
		||||
+     * mixed with LIVE.  */
 | 
			
		||||
+    if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
 | 
			
		||||
+        (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
 | 
			
		||||
+         (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
 | 
			
		||||
+        xenUnifiedError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                        _("invalid flag combination: (0x%x)"), flags);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
 | 
			
		||||
+        xenUnifiedError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                        _("argument out of range: %d"), nvcpus);
 | 
			
		||||
         return -1;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     /* Try non-hypervisor methods first, then hypervisor direct method
 | 
			
		||||
      * as a last resort.
 | 
			
		||||
      */
 | 
			
		||||
-    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
 | 
			
		||||
-        if (i != XEN_UNIFIED_HYPERVISOR_OFFSET &&
 | 
			
		||||
-            priv->opened[i] &&
 | 
			
		||||
-            drivers[i]->domainSetVcpus &&
 | 
			
		||||
-            drivers[i]->domainSetVcpus (dom, nvcpus) == 0)
 | 
			
		||||
-            return 0;
 | 
			
		||||
-
 | 
			
		||||
-    if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] &&
 | 
			
		||||
-        drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus &&
 | 
			
		||||
-        drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus (dom, nvcpus) == 0)
 | 
			
		||||
-        return 0;
 | 
			
		||||
+    if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
 | 
			
		||||
+        ret = xenDaemonDomainSetVcpusFlags(dom, nvcpus, flags);
 | 
			
		||||
+        if (ret != -2)
 | 
			
		||||
+            return ret;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
 | 
			
		||||
+        ret = xenXMDomainSetVcpusFlags(dom, nvcpus, flags);
 | 
			
		||||
+        if (ret != -2)
 | 
			
		||||
+            return ret;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (flags == VIR_DOMAIN_VCPU_LIVE)
 | 
			
		||||
+        return xenHypervisorSetVcpus(dom, nvcpus);
 | 
			
		||||
 | 
			
		||||
+    xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
 | 
			
		||||
     return -1;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
 xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
 | 
			
		||||
 {
 | 
			
		||||
-    return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
 | 
			
		||||
+    unsigned int flags = VIR_DOMAIN_VCPU_LIVE;
 | 
			
		||||
+    xenUnifiedPrivatePtr priv;
 | 
			
		||||
+
 | 
			
		||||
+    /* Per the documented API, it is hypervisor-dependent whether this
 | 
			
		||||
+     * affects just _LIVE or _LIVE|_CONFIG; in xen's case, that
 | 
			
		||||
+     * depends on xendConfigVersion.  */
 | 
			
		||||
+    if (dom) {
 | 
			
		||||
+        priv = dom->conn->privateData;
 | 
			
		||||
+        if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4)
 | 
			
		||||
+            flags |= VIR_DOMAIN_VCPU_CONFIG;
 | 
			
		||||
+    }
 | 
			
		||||
+    return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags);
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static int
 | 
			
		||||
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
 | 
			
		||||
index 3e7c1d0..115a26a 100644
 | 
			
		||||
--- a/src/xen/xen_driver.h
 | 
			
		||||
+++ b/src/xen/xen_driver.h
 | 
			
		||||
@@ -220,6 +220,7 @@ int  xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr info,
 | 
			
		||||
 void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
 | 
			
		||||
                                     virDomainEventPtr event);
 | 
			
		||||
 unsigned long xenUnifiedVersion(void);
 | 
			
		||||
+int xenUnifiedGetMaxVcpus(virConnectPtr conn, const char *type);
 | 
			
		||||
 | 
			
		||||
 # ifndef PROXY
 | 
			
		||||
 void xenUnifiedLock(xenUnifiedPrivatePtr priv);
 | 
			
		||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
 | 
			
		||||
index 3642296..55c2cc4 100644
 | 
			
		||||
--- a/src/xen/xend_internal.c
 | 
			
		||||
+++ b/src/xen/xend_internal.c
 | 
			
		||||
@@ -3535,6 +3535,82 @@ xenDaemonLookupByID(virConnectPtr conn, int id) {
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
+ * xenDaemonDomainSetVcpusFlags:
 | 
			
		||||
+ * @domain: pointer to domain object
 | 
			
		||||
+ * @nvcpus: the new number of virtual CPUs for this domain
 | 
			
		||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
 | 
			
		||||
+ *
 | 
			
		||||
+ * Change virtual CPUs allocation of domain according to flags.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns 0 on success, -1 if an error message was issued, and -2 if
 | 
			
		||||
+ * the unified driver should keep trying.
 | 
			
		||||
+ */
 | 
			
		||||
+int
 | 
			
		||||
+xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
 | 
			
		||||
+                             unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    char buf[VIR_UUID_BUFLEN];
 | 
			
		||||
+    xenUnifiedPrivatePtr priv;
 | 
			
		||||
+    int max;
 | 
			
		||||
+
 | 
			
		||||
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
 | 
			
		||||
+        || (vcpus < 1)) {
 | 
			
		||||
+        virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
+        return (-1);
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
 | 
			
		||||
+
 | 
			
		||||
+    if ((domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) ||
 | 
			
		||||
+        (flags & VIR_DOMAIN_VCPU_MAXIMUM))
 | 
			
		||||
+        return -2;
 | 
			
		||||
+
 | 
			
		||||
+    /* With xendConfigVersion 2, only _LIVE is supported.  With
 | 
			
		||||
+     * xendConfigVersion 3, only _LIVE|_CONFIG is supported for
 | 
			
		||||
+     * running domains, or _CONFIG for inactive domains.  */
 | 
			
		||||
+    if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) {
 | 
			
		||||
+        if (flags & VIR_DOMAIN_VCPU_CONFIG) {
 | 
			
		||||
+            virXendError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                         _("Xend version does not support modifying "
 | 
			
		||||
+                           "persistent config"));
 | 
			
		||||
+            return -1;
 | 
			
		||||
+        }
 | 
			
		||||
+    } else if (domain->id < 0) {
 | 
			
		||||
+        if (flags & VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+            virXendError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                         _("domain not running"));
 | 
			
		||||
+            return -1;
 | 
			
		||||
+        }
 | 
			
		||||
+    } else {
 | 
			
		||||
+        if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) !=
 | 
			
		||||
+            (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) {
 | 
			
		||||
+            virXendError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                         _("Xend only supports modifying both live and "
 | 
			
		||||
+                           "persistent config"));
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /* Unfortunately, xend_op does not validate whether this exceeds
 | 
			
		||||
+     * the maximum.  */
 | 
			
		||||
+    flags |= VIR_DOMAIN_VCPU_MAXIMUM;
 | 
			
		||||
+    if ((max = xenDaemonDomainGetVcpusFlags(domain, flags)) < 0) {
 | 
			
		||||
+        virXendError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                     _("could not determin max vcpus for the domain"));
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (vcpus > max) {
 | 
			
		||||
+        virXendError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                     _("requested vcpus is greater than max allowable"
 | 
			
		||||
+                       " vcpus for the domain: %d > %d"), vcpus, max);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    snprintf(buf, sizeof(buf), "%d", vcpus);
 | 
			
		||||
+    return xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
 | 
			
		||||
+                   buf, NULL);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
  * xenDaemonDomainSetVcpus:
 | 
			
		||||
  * @domain: pointer to domain object
 | 
			
		||||
  * @nvcpus: the new number of virtual CPUs for this domain
 | 
			
		||||
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
 | 
			
		||||
index 923cebd..53f5d2c 100644
 | 
			
		||||
--- a/src/xen/xend_internal.h
 | 
			
		||||
+++ b/src/xen/xend_internal.h
 | 
			
		||||
@@ -151,6 +151,9 @@ int xenDaemonDomainUndefine(virDomainPtr domain);
 | 
			
		||||
 | 
			
		||||
 int	xenDaemonDomainSetVcpus		(virDomainPtr domain,
 | 
			
		||||
                                          unsigned int vcpus);
 | 
			
		||||
+int	xenDaemonDomainSetVcpusFlags	(virDomainPtr domain,
 | 
			
		||||
+                                         unsigned int vcpus,
 | 
			
		||||
+                                         unsigned int flags);
 | 
			
		||||
 int	xenDaemonDomainPinVcpu		(virDomainPtr domain,
 | 
			
		||||
                                          unsigned int vcpu,
 | 
			
		||||
                                          unsigned char *cpumap,
 | 
			
		||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
 | 
			
		||||
index 4ea4245..2b8e51e 100644
 | 
			
		||||
--- a/src/xen/xm_internal.c
 | 
			
		||||
+++ b/src/xen/xm_internal.c
 | 
			
		||||
@@ -1670,6 +1670,89 @@ cleanup:
 | 
			
		||||
     return ret;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
+/*
 | 
			
		||||
+ * xenXMDomainSetVcpusFlags:
 | 
			
		||||
+ * @domain: pointer to domain object
 | 
			
		||||
+ * @nvcpus: number of vcpus
 | 
			
		||||
+ * @flags: bitwise-ORd from virDomainVcpuFlags
 | 
			
		||||
+ *
 | 
			
		||||
+ * Change virtual CPUs allocation of domain according to flags.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns 0 on success, -1 if an error message was issued, and -2 if
 | 
			
		||||
+ * the unified driver should keep trying.
 | 
			
		||||
+ */
 | 
			
		||||
+int
 | 
			
		||||
+xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
 | 
			
		||||
+                         unsigned int flags)
 | 
			
		||||
+{
 | 
			
		||||
+    xenUnifiedPrivatePtr priv;
 | 
			
		||||
+    const char *filename;
 | 
			
		||||
+    xenXMConfCachePtr entry;
 | 
			
		||||
+    int ret = -1;
 | 
			
		||||
+    int max;
 | 
			
		||||
+
 | 
			
		||||
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
 | 
			
		||||
+        xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (domain->conn->flags & VIR_CONNECT_RO) {
 | 
			
		||||
+        xenXMError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (domain->id != -1)
 | 
			
		||||
+        return -2;
 | 
			
		||||
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
 | 
			
		||||
+        xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
 | 
			
		||||
+                   _("domain is not running"));
 | 
			
		||||
+        return -1;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    priv = domain->conn->privateData;
 | 
			
		||||
+    xenUnifiedLock(priv);
 | 
			
		||||
+
 | 
			
		||||
+    if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+
 | 
			
		||||
+    if (!(entry = virHashLookup(priv->configCache, filename)))
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+
 | 
			
		||||
+    /* Hypervisor maximum. */
 | 
			
		||||
+    if ((max = xenUnifiedGetMaxVcpus(domain->conn, NULL)) < 0) {
 | 
			
		||||
+        xenXMError(VIR_ERR_INTERNAL_ERROR, "%s",
 | 
			
		||||
+                   _("could not determin max vcpus for the domain"));
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    }
 | 
			
		||||
+    /* Can't specify a current larger than stored maximum; but
 | 
			
		||||
+     * reducing maximum can silently reduce current.  */
 | 
			
		||||
+    if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM))
 | 
			
		||||
+        max = entry->def->maxvcpus;
 | 
			
		||||
+    if (vcpus > max) {
 | 
			
		||||
+        xenXMError(VIR_ERR_INVALID_ARG,
 | 
			
		||||
+                   _("requested vcpus is greater than max allowable"
 | 
			
		||||
+                     " vcpus for the domain: %d > %d"), vcpus, max);
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
 | 
			
		||||
+        entry->def->maxvcpus = vcpus;
 | 
			
		||||
+        if (entry->def->vcpus > vcpus)
 | 
			
		||||
+            entry->def->vcpus = vcpus;
 | 
			
		||||
+    } else {
 | 
			
		||||
+        entry->def->vcpus = vcpus;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /* If this fails, should we try to undo our changes to the
 | 
			
		||||
+     * in-memory representation of the config file. I say not!
 | 
			
		||||
+     */
 | 
			
		||||
+    if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
 | 
			
		||||
+        goto cleanup;
 | 
			
		||||
+    ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+cleanup:
 | 
			
		||||
+    xenUnifiedUnlock(priv);
 | 
			
		||||
+    return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * xenXMDomainGetVcpusFlags:
 | 
			
		||||
  * @domain: pointer to domain object
 | 
			
		||||
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
 | 
			
		||||
index 3295fbd..a46e1a2 100644
 | 
			
		||||
--- a/src/xen/xm_internal.h
 | 
			
		||||
+++ b/src/xen/xm_internal.h
 | 
			
		||||
@@ -45,6 +45,8 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
 | 
			
		||||
 int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
 | 
			
		||||
 unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
 | 
			
		||||
 int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
 | 
			
		||||
+int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
 | 
			
		||||
+                             unsigned int flags);
 | 
			
		||||
 int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
 | 
			
		||||
 int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
 | 
			
		||||
                        unsigned char *cpumap, int maplen);
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										228
									
								
								docs/api_extension/0015-remove-dead-xen-code.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								docs/api_extension/0015-remove-dead-xen-code.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,228 @@
 | 
			
		||||
From b013788742183afec9aa5068d3cfd185a3b5c62e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Blake <eblake@redhat.com>
 | 
			
		||||
Date: Thu, 7 Oct 2010 08:59:27 -0600
 | 
			
		||||
Subject: [PATCH 15/15] vcpu: remove dead xen code
 | 
			
		||||
 | 
			
		||||
* src/xen/xen_driver.h (xenUnifiedDriver): Remove now-unused
 | 
			
		||||
domainGetMaxVcpus, domainSetVcpus.
 | 
			
		||||
* src/xen/proxy_internal.c (xenProxyDriver): Likewise.
 | 
			
		||||
* src/xen/xen_hypervisor.c (xenHypervisorDriver): Likewise.
 | 
			
		||||
* src/xen/xen_inotify.c (xenInotifyDriver): Likewise.
 | 
			
		||||
* src/xen/xend_internal.c (xenDaemonDriver)
 | 
			
		||||
(xenDaemonDomainSetVcpus): Likewise.
 | 
			
		||||
* src/xen/xm_internal.c (xenXMDriver, xenXMDomainSetVcpus):
 | 
			
		||||
Likewise.
 | 
			
		||||
* src/xen/xs_internal.c (xenStoreDriver): Likewise.
 | 
			
		||||
---
 | 
			
		||||
 src/xen/proxy_internal.c |    2 --
 | 
			
		||||
 src/xen/xen_driver.h     |    4 +---
 | 
			
		||||
 src/xen/xen_hypervisor.c |    2 --
 | 
			
		||||
 src/xen/xen_inotify.c    |    2 --
 | 
			
		||||
 src/xen/xend_internal.c  |   33 ---------------------------------
 | 
			
		||||
 src/xen/xm_internal.c    |   43 -------------------------------------------
 | 
			
		||||
 src/xen/xs_internal.c    |    2 --
 | 
			
		||||
 7 files changed, 1 insertions(+), 87 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/xen/proxy_internal.c b/src/xen/proxy_internal.c
 | 
			
		||||
index 335dfc4..4033727 100644
 | 
			
		||||
--- a/src/xen/proxy_internal.c
 | 
			
		||||
+++ b/src/xen/proxy_internal.c
 | 
			
		||||
@@ -67,10 +67,8 @@ struct xenUnifiedDriver xenProxyDriver = {
 | 
			
		||||
     NULL, /* domainSave */
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
-    NULL, /* domainSetVcpus */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
-    NULL, /* domainGetMaxVcpus */
 | 
			
		||||
     NULL, /* listDefinedDomains */
 | 
			
		||||
     NULL, /* numOfDefinedDomains */
 | 
			
		||||
     NULL, /* domainCreate */
 | 
			
		||||
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
 | 
			
		||||
index 115a26a..53f97d4 100644
 | 
			
		||||
--- a/src/xen/xen_driver.h
 | 
			
		||||
+++ b/src/xen/xen_driver.h
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
 /*
 | 
			
		||||
  * xen_unified.c: Unified Xen driver.
 | 
			
		||||
  *
 | 
			
		||||
- * Copyright (C) 2007 Red Hat, Inc.
 | 
			
		||||
+ * Copyright (C) 2007, 2010 Red Hat, Inc.
 | 
			
		||||
  *
 | 
			
		||||
  * See COPYING.LIB for the License of this software
 | 
			
		||||
  *
 | 
			
		||||
@@ -84,10 +84,8 @@ struct xenUnifiedDriver {
 | 
			
		||||
         virDrvDomainSave		domainSave;
 | 
			
		||||
         virDrvDomainRestore		domainRestore;
 | 
			
		||||
         virDrvDomainCoreDump		domainCoreDump;
 | 
			
		||||
-        virDrvDomainSetVcpus		domainSetVcpus;
 | 
			
		||||
         virDrvDomainPinVcpu		domainPinVcpu;
 | 
			
		||||
         virDrvDomainGetVcpus		domainGetVcpus;
 | 
			
		||||
-        virDrvDomainGetMaxVcpus		domainGetMaxVcpus;
 | 
			
		||||
         virDrvListDefinedDomains	listDefinedDomains;
 | 
			
		||||
         virDrvNumOfDefinedDomains	numOfDefinedDomains;
 | 
			
		||||
         virDrvDomainCreate		domainCreate;
 | 
			
		||||
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
 | 
			
		||||
index 6246513..3797865 100644
 | 
			
		||||
--- a/src/xen/xen_hypervisor.c
 | 
			
		||||
+++ b/src/xen/xen_hypervisor.c
 | 
			
		||||
@@ -784,10 +784,8 @@ struct xenUnifiedDriver xenHypervisorDriver = {
 | 
			
		||||
     NULL, /* domainSave */
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
-    xenHypervisorSetVcpus, /* domainSetVcpus */
 | 
			
		||||
     xenHypervisorPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     xenHypervisorGetVcpus, /* domainGetVcpus */
 | 
			
		||||
-    xenHypervisorGetVcpuMax, /* domainGetMaxVcpus */
 | 
			
		||||
     NULL, /* listDefinedDomains */
 | 
			
		||||
     NULL, /* numOfDefinedDomains */
 | 
			
		||||
     NULL, /* domainCreate */
 | 
			
		||||
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
 | 
			
		||||
index d24b20f..9507061 100644
 | 
			
		||||
--- a/src/xen/xen_inotify.c
 | 
			
		||||
+++ b/src/xen/xen_inotify.c
 | 
			
		||||
@@ -71,10 +71,8 @@ struct xenUnifiedDriver xenInotifyDriver = {
 | 
			
		||||
     NULL, /* domainSave */
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
-    NULL, /* domainSetVcpus */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
-    NULL, /* domainGetMaxVcpus */
 | 
			
		||||
     NULL, /* listDefinedDomains */
 | 
			
		||||
     NULL, /* numOfDefinedDomains */
 | 
			
		||||
     NULL, /* domainCreate */
 | 
			
		||||
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
 | 
			
		||||
index 55c2cc4..b90c331 100644
 | 
			
		||||
--- a/src/xen/xend_internal.c
 | 
			
		||||
+++ b/src/xen/xend_internal.c
 | 
			
		||||
@@ -3611,37 +3611,6 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
- * xenDaemonDomainSetVcpus:
 | 
			
		||||
- * @domain: pointer to domain object
 | 
			
		||||
- * @nvcpus: the new number of virtual CPUs for this domain
 | 
			
		||||
- *
 | 
			
		||||
- * Dynamically change the number of virtual CPUs used by the domain.
 | 
			
		||||
- *
 | 
			
		||||
- * Returns 0 for success; -1 (with errno) on error
 | 
			
		||||
- */
 | 
			
		||||
-int
 | 
			
		||||
-xenDaemonDomainSetVcpus(virDomainPtr domain, unsigned int vcpus)
 | 
			
		||||
-{
 | 
			
		||||
-    char buf[VIR_UUID_BUFLEN];
 | 
			
		||||
-    xenUnifiedPrivatePtr priv;
 | 
			
		||||
-
 | 
			
		||||
-    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
 | 
			
		||||
-     || (vcpus < 1)) {
 | 
			
		||||
-        virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
-        return (-1);
 | 
			
		||||
-    }
 | 
			
		||||
-
 | 
			
		||||
-    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
 | 
			
		||||
-
 | 
			
		||||
-    if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
 | 
			
		||||
-        return(-1);
 | 
			
		||||
-
 | 
			
		||||
-    snprintf(buf, sizeof(buf), "%d", vcpus);
 | 
			
		||||
-    return(xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
 | 
			
		||||
-                   buf, NULL));
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-/**
 | 
			
		||||
  * xenDaemonDomainPinCpu:
 | 
			
		||||
  * @domain: pointer to domain object
 | 
			
		||||
  * @vcpu: virtual CPU number
 | 
			
		||||
@@ -5213,10 +5182,8 @@ struct xenUnifiedDriver xenDaemonDriver = {
 | 
			
		||||
     xenDaemonDomainSave,         /* domainSave */
 | 
			
		||||
     xenDaemonDomainRestore,      /* domainRestore */
 | 
			
		||||
     xenDaemonDomainCoreDump,     /* domainCoreDump */
 | 
			
		||||
-    xenDaemonDomainSetVcpus,     /* domainSetVcpus */
 | 
			
		||||
     xenDaemonDomainPinVcpu,      /* domainPinVcpu */
 | 
			
		||||
     xenDaemonDomainGetVcpus,     /* domainGetVcpus */
 | 
			
		||||
-    NULL,                        /* domainGetMaxVcpus */
 | 
			
		||||
     xenDaemonListDefinedDomains, /* listDefinedDomains */
 | 
			
		||||
     xenDaemonNumOfDefinedDomains,/* numOfDefinedDomains */
 | 
			
		||||
     xenDaemonDomainCreate,       /* domainCreate */
 | 
			
		||||
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
 | 
			
		||||
index 2b8e51e..430d40b 100644
 | 
			
		||||
--- a/src/xen/xm_internal.c
 | 
			
		||||
+++ b/src/xen/xm_internal.c
 | 
			
		||||
@@ -103,10 +103,8 @@ struct xenUnifiedDriver xenXMDriver = {
 | 
			
		||||
     NULL, /* domainSave */
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
-    xenXMDomainSetVcpus, /* domainSetVcpus */
 | 
			
		||||
     xenXMDomainPinVcpu, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
-    NULL, /* domainGetMaxVcpus */
 | 
			
		||||
     xenXMListDefinedDomains, /* listDefinedDomains */
 | 
			
		||||
     xenXMNumOfDefinedDomains, /* numOfDefinedDomains */
 | 
			
		||||
     xenXMDomainCreate, /* domainCreate */
 | 
			
		||||
@@ -1630,47 +1628,6 @@ cleanup:
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
- * Set the VCPU count in config
 | 
			
		||||
- */
 | 
			
		||||
-int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
 | 
			
		||||
-    xenUnifiedPrivatePtr priv;
 | 
			
		||||
-    const char *filename;
 | 
			
		||||
-    xenXMConfCachePtr entry;
 | 
			
		||||
-    int ret = -1;
 | 
			
		||||
-
 | 
			
		||||
-    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
 | 
			
		||||
-        xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 | 
			
		||||
-        return (-1);
 | 
			
		||||
-    }
 | 
			
		||||
-    if (domain->conn->flags & VIR_CONNECT_RO)
 | 
			
		||||
-        return (-1);
 | 
			
		||||
-    if (domain->id != -1)
 | 
			
		||||
-        return (-1);
 | 
			
		||||
-
 | 
			
		||||
-    priv = domain->conn->privateData;
 | 
			
		||||
-    xenUnifiedLock(priv);
 | 
			
		||||
-
 | 
			
		||||
-    if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
 | 
			
		||||
-        goto cleanup;
 | 
			
		||||
-
 | 
			
		||||
-    if (!(entry = virHashLookup(priv->configCache, filename)))
 | 
			
		||||
-        goto cleanup;
 | 
			
		||||
-
 | 
			
		||||
-    entry->def->maxvcpus = entry->def->vcpus = vcpus;
 | 
			
		||||
-
 | 
			
		||||
-    /* If this fails, should we try to undo our changes to the
 | 
			
		||||
-     * in-memory representation of the config file. I say not!
 | 
			
		||||
-     */
 | 
			
		||||
-    if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
 | 
			
		||||
-        goto cleanup;
 | 
			
		||||
-    ret = 0;
 | 
			
		||||
-
 | 
			
		||||
-cleanup:
 | 
			
		||||
-    xenUnifiedUnlock(priv);
 | 
			
		||||
-    return ret;
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-/*
 | 
			
		||||
  * xenXMDomainSetVcpusFlags:
 | 
			
		||||
  * @domain: pointer to domain object
 | 
			
		||||
  * @nvcpus: number of vcpus
 | 
			
		||||
diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c
 | 
			
		||||
index 9296f25..a9817b1 100644
 | 
			
		||||
--- a/src/xen/xs_internal.c
 | 
			
		||||
+++ b/src/xen/xs_internal.c
 | 
			
		||||
@@ -67,10 +67,8 @@ struct xenUnifiedDriver xenStoreDriver = {
 | 
			
		||||
     NULL, /* domainSave */
 | 
			
		||||
     NULL, /* domainRestore */
 | 
			
		||||
     NULL, /* domainCoreDump */
 | 
			
		||||
-    NULL, /* domainSetVcpus */
 | 
			
		||||
     NULL, /* domainPinVcpu */
 | 
			
		||||
     NULL, /* domainGetVcpus */
 | 
			
		||||
-    NULL, /* domainGetMaxVcpus */
 | 
			
		||||
     NULL, /* listDefinedDomains */
 | 
			
		||||
     NULL, /* numOfDefinedDomains */
 | 
			
		||||
     NULL, /* domainCreate */
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2618
									
								
								docs/apibuild.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2618
									
								
								docs/apibuild.py
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 10 KiB  | 
@@ -1,8 +1,8 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>Applications using libvirt</h1>
 | 
			
		||||
    <h1>Applications using <strong>libvirt</strong></h1>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      This page provides an illustration of the wide variety of
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
 | 
			
		||||
    <ul id="toc"></ul>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="add">Add an application</a></h2>
 | 
			
		||||
    <h2><a name="add">Add an application</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
      To add an application not listed on this page, send a message
 | 
			
		||||
@@ -19,18 +19,35 @@
 | 
			
		||||
      be added here, or simply send a patch against the documentation
 | 
			
		||||
      in the libvirt.git docs subdirectory.
 | 
			
		||||
      If your application uses libvirt as its API,
 | 
			
		||||
      the following graphics are available for your website to advertise
 | 
			
		||||
      the following graphic is available for your website to advertise
 | 
			
		||||
      support for libvirt:
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <p class="image">
 | 
			
		||||
      <img src="logos/logo-square-powered-96.png" alt="libvirt powered"/>
 | 
			
		||||
      <img src="logos/logo-square-powered-128.png" alt="libvirt powered"/>
 | 
			
		||||
      <img src="logos/logo-square-powered-192.png" alt="libvirt powered"/>
 | 
			
		||||
      <img src="logos/logo-square-powered-256.png" alt="libvirt powered"/>
 | 
			
		||||
      <img src="madeWith.png" alt="Made with libvirt"/>
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="command">Command line tools</a></h2>
 | 
			
		||||
    <h2><a name="clientserver">Client/Server applications</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://archipelproject.org">Archipel</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Archipel is a libvirt-based solution to manage and supervise virtual
 | 
			
		||||
        machines.  It uses XMPP for all communication. There is no web
 | 
			
		||||
        service or custom protocol.  You just need at least one XMPP server,
 | 
			
		||||
        like eJabberd, to start playing with it.  This allows Archipel to
 | 
			
		||||
        work completely real time.  You never have to refresh the user
 | 
			
		||||
        interface, you'll be notified as soon as something happens. You can
 | 
			
		||||
        even use your favorite chat clients to command your infrastructure.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Isn't it great to be able to open a chat conversation with your
 | 
			
		||||
        virtual machine and say things like "How are you today?" or "Hey,
 | 
			
		||||
        please reboot"?
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="command">Command line tools</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://libguestfs.org">guestfish</a></dt>
 | 
			
		||||
@@ -45,21 +62,21 @@
 | 
			
		||||
        management tasks on all libvirt managed domains, networks and
 | 
			
		||||
        storage. This is part of the libvirt core distribution.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://virt-manager.org/">virt-clone</a></dt>
 | 
			
		||||
      <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="https://people.redhat.com/rjones/virt-df/">virt-df</a></dt>
 | 
			
		||||
      <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="https://virt-manager.org/">virt-image</a></dt>
 | 
			
		||||
      <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
 | 
			
		||||
@@ -67,26 +84,26 @@
 | 
			
		||||
        into the domain XML format for execution under any libvirt
 | 
			
		||||
        hypervisor meeting the pre-requisites.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://virt-manager.org/">virt-install</a></dt>
 | 
			
		||||
      <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="https://people.redhat.com/rjones/virt-top/">virt-top</a></dt>
 | 
			
		||||
      <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>
 | 
			
		||||
      <dt>
 | 
			
		||||
        <a href="https://people.redhat.com/~rjones/virt-what/">virt-what</a>
 | 
			
		||||
        <a href="http://people.redhat.com/~rjones/virt-what/">virt-what</a>
 | 
			
		||||
      </dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        virt-what is a shell script for detecting if the program is running
 | 
			
		||||
        in a virtual machine.  It prints out a list of facts about the
 | 
			
		||||
        virtual machine, derived from heuristics.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://sourceware.org/systemtap/">stap</a></dt>
 | 
			
		||||
      <dt><a href="http://sourceware.org/systemtap/">stap</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        SystemTap is a tool used to gather rich information about a running
 | 
			
		||||
        system through the use of scripts. Starting from v2.4, the front-end
 | 
			
		||||
@@ -99,15 +116,9 @@
 | 
			
		||||
        machines. It is a command line tool for developers that makes it very
 | 
			
		||||
        fast and easy to deploy and re-deploy an environment of vm's.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://github.com/virt-lightning/virt-lightning">virt-lightning</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Virt-Lightning uses libvirt, cloud-init and libguestfs to allow anyone
 | 
			
		||||
        to quickly start a new VM. Very much like a container CLI, but with a
 | 
			
		||||
        virtual machine.
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="configmgmt">Configuration Management</a></h2>
 | 
			
		||||
    <h2><a name="configmgmt">Configuration Management</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://wiki.lcfg.org/bin/view/LCFG/LcfgLibvirt">LCFG</a></dt>
 | 
			
		||||
@@ -125,10 +136,10 @@
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="continuousintegration">Continuous Integration</a></h2>
 | 
			
		||||
    <h2><a name="continuousintegration">Continuous Integration</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://docs.buildbot.net/latest/manual/configuration/workers-libvirt.html">BuildBot</a></dt>
 | 
			
		||||
      <dt><a href="http://buildbot.net/buildbot/docs/current/Libvirt.html">BuildBot</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        BuildBot is a system to automate the compile/test cycle required
 | 
			
		||||
        by most software projects.  CVS commits trigger new builds, run on
 | 
			
		||||
@@ -138,7 +149,7 @@
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://wiki.jenkins-ci.org/display/JENKINS/Libvirt+Slaves+Plugin">Jenkins</a></dt>
 | 
			
		||||
      <dt><a href="http://wiki.jenkins-ci.org/display/JENKINS/Libvirt+Slaves+Plugin">Jenkins</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        This plugin for Jenkins adds a way to control guest domains hosted
 | 
			
		||||
        on Xen or QEMU/KVM.  You configure a Jenkins Slave,
 | 
			
		||||
@@ -149,7 +160,7 @@
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="conversion">Conversion</a></h2>
 | 
			
		||||
    <h2><a name="conversion">Conversion</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://libguestfs.org/virt-p2v.1.html">virt-p2v</a></dt>
 | 
			
		||||
@@ -180,37 +191,26 @@
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="desktop">Desktop applications</a></h2>
 | 
			
		||||
    <h2><a name="desktop">Desktop applications</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://virt-manager.org/">virt-manager</a></dt>
 | 
			
		||||
      <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
 | 
			
		||||
        up to managing 10-20 hosts and their VMs.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://virt-manager.org/">virt-viewer</a></dt>
 | 
			
		||||
      <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>
 | 
			
		||||
      <dt><a href="https://f1ash.github.io/qt-virt-manager">qt-virt-manager</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        The Qt GUI for create and control VMs and another virtual entities
 | 
			
		||||
        (aka networks, storages, interfaces, secrets, network filters).
 | 
			
		||||
        Contains integrated LXC/SPICE/VNC viewer for accessing the graphical or
 | 
			
		||||
        text console associated with a virtual machine or container.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://f1ash.github.io/qt-virt-manager/#virtual-machines-viewer">qt-remote-viewer</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        The Qt VNC/SPICE viewer for access to remote desktops or VMs.
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="iaas">Infrastructure as a Service (IaaS)</a></h2>
 | 
			
		||||
    <h2><a name="iaas">Infrastructure as a Service (IaaS)</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://cc1.ifj.edu.pl">Cracow Cloud One</a></dt>
 | 
			
		||||
@@ -220,11 +220,21 @@
 | 
			
		||||
        it easy to benefit from private Cloud Computing technology.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
      <dt><a href="https://github.com/eucalyptus/eucalyptus">Eucalyptus</a></dt>
 | 
			
		||||
      <dt><a href="http://www.emotivecloud.net">EMOTIVE Cloud</a></dt>
 | 
			
		||||
      <dd>The EMOTIVE (Elastic Management Of Tasks In Virtualized
 | 
			
		||||
        Environments) middleware allows executing tasks and providing
 | 
			
		||||
        virtualized environments to the users with Xen, KVM or
 | 
			
		||||
        VirtualBox hypervisor. EMOTIVE's main feature is VM management
 | 
			
		||||
        with different scheduling policies. It can be also used as a
 | 
			
		||||
        cloud provider and is very easy to extend thanks to its
 | 
			
		||||
        modular Web Services architecture.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
      <dt><a href="http://www.eucalyptus.com">Eucalyptus</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Eucalyptus is an on-premise Infrastructure as a Service cloud
 | 
			
		||||
        software platform that is open source and
 | 
			
		||||
        AWS-compatible. Eucalyptus uses libvirt virtualization API to
 | 
			
		||||
        AWS-compatible. Eucalyptus uses libivrt virtualization API to
 | 
			
		||||
        directly interact with Xen and KVM hypervisors.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +254,7 @@
 | 
			
		||||
        management.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
      <dt><a href="https://www.openstack.org">OpenStack</a></dt>
 | 
			
		||||
      <dt><a href="http://www.openstack.org">OpenStack</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        OpenStack is a "cloud operating system" usable for both public
 | 
			
		||||
        and private clouds.  Its various parts take care of compute,
 | 
			
		||||
@@ -252,29 +262,9 @@
 | 
			
		||||
        using a dashboard.  Compute part uses libvirt to manage VM
 | 
			
		||||
        life-cycle, monitoring and so on.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
      <dt><a href="https://github.com/gustavfranssonnyvell/cherrypop">Cherrypop</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        A cloud software with no masters or central points. Nodes
 | 
			
		||||
        autodetect other nodes and autodistribute virtual
 | 
			
		||||
        machines and autodivide up the workload. Also there is no
 | 
			
		||||
        minimum limit for hosts, well, one might be nice. It's
 | 
			
		||||
        perfect for setting up low-end servers in a cloud or a
 | 
			
		||||
        cloud where you want the most bang for the bucks.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
      <dt><a href="http://en.zstack.io/">ZStack</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        ZStack is an open source IaaS software that aims to automate the
 | 
			
		||||
        management of all resources (compute, storage, networking, etc.) in a
 | 
			
		||||
        datacenter by using APIs, thus conforming to the principles of a
 | 
			
		||||
        software-defined datacenter. The key strengths of ZStack in terms of
 | 
			
		||||
        management are scalability, performance, and a fast, user-friendly
 | 
			
		||||
        deployment.
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="libraries">Libraries</a></h2>
 | 
			
		||||
    <h2><a name="libraries">Libraries</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://libguestfs.org">libguestfs</a></dt>
 | 
			
		||||
@@ -290,7 +280,7 @@
 | 
			
		||||
        Windows Registry in Windows guests.
 | 
			
		||||
      </dd>
 | 
			
		||||
 | 
			
		||||
      <dt><a href="https://sandbox.libvirt.org">libvirt-sandbox</a></dt>
 | 
			
		||||
      <dt><a href="http://sandbox.libvirt.org">libvirt-sandbox</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        A library and command line tools for simplifying the creation of
 | 
			
		||||
        application sandboxes using virtualization technology. It currently
 | 
			
		||||
@@ -303,14 +293,14 @@
 | 
			
		||||
        Allows using simple ruby objects to manipulate
 | 
			
		||||
        hypervisors, guests, storage, network etc.  It is
 | 
			
		||||
        based on top of
 | 
			
		||||
        the <a href="https://libvirt.org/ruby">native ruby bindings</a>.
 | 
			
		||||
        the <a href="http://libvirt.org/ruby">native ruby bindings</a>.
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="livecd">LiveCD / Appliances</a></h2>
 | 
			
		||||
    <h2><a name="livecd">LiveCD / Appliances</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://libguestfs.org/virt-v2v/">virt-p2v</a></dt>
 | 
			
		||||
      <dt><a href="http://et.redhat.com/~rjones/virt-p2v/">virt-p2v</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        An older tool for converting a physical machine into a virtual
 | 
			
		||||
        machine.  It is a LiveCD which is booted on the machine to be
 | 
			
		||||
@@ -320,9 +310,9 @@
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="monitoring">Monitoring</a></h2>
 | 
			
		||||
    <h2><a name="monitoring">Monitoring</a></h2>
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://collectd.org/plugins/libvirt.shtml">collectd</a></dt>
 | 
			
		||||
      <dt><a href="http://collectd.org/plugins/libvirt.shtml">collectd</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        The libvirt-plugin is part of <a href="http://collectd.org/">collectd</a>
 | 
			
		||||
        and gathers statistics about virtualized guests on a system. This
 | 
			
		||||
@@ -331,19 +321,19 @@
 | 
			
		||||
        For a full description, please refer to the libvirt section in the
 | 
			
		||||
        collectd.conf(5) manual page.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="http://www.sflow.net/">Host sFlow</a></dt>
 | 
			
		||||
      <dt><a href="http://host-sflow.sourceforge.net/">Host sFlow</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Host sFlow is a lightweight agent running on KVM hypervisors that
 | 
			
		||||
        links to libvirt library and exports standardized cpu, memory, network
 | 
			
		||||
        and disk metrics for all virtual machines.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://honk.sigxcpu.org/projects/libvirt/#munin">Munin</a></dt>
 | 
			
		||||
      <dt><a href="http://honk.sigxcpu.org/projects/libvirt/#munin">Munin</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        The plugins provided by Guido Günther allow to monitor various things
 | 
			
		||||
        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://people.redhat.com/rjones/nagios-virt/">Nagios-virt</a></dt>
 | 
			
		||||
      <dt><a href="http://et.redhat.com/~rjones/nagios-virt/">Nagios-virt</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Nagios-virt is a configuration tool to add monitoring of your
 | 
			
		||||
        virtualised domains to <a href="http://www.nagios.org/">Nagios</a>.
 | 
			
		||||
@@ -351,20 +341,18 @@
 | 
			
		||||
        your Xen or QEMU/KVM guests, or to integrate with your existing Nagios
 | 
			
		||||
        installation.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="http://www.pcp.io/man/man1/pmdalibvirt.1.html">PCP</a></dt>
 | 
			
		||||
      <dt><a href="http://community.zenoss.org/docs/DOC-4687">Zenoss</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        The PCP libvirt PMDA (plugin) is part of the
 | 
			
		||||
        <a href="http://pcp.io/">PCP</a> toolkit and provides
 | 
			
		||||
        hypervisor and guest information and complete set of guest performance
 | 
			
		||||
        metrics. It supports pCPU, vCPU, memory, block device, network interface,
 | 
			
		||||
        and performance event metrics for each virtual guest.
 | 
			
		||||
        The Zenoss libvirt Zenpack adds support for monitoring virtualization
 | 
			
		||||
        servers.  It has been tested with KVM, QEMU, VMware ESX, and VMware
 | 
			
		||||
        GSX.
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="provisioning">Provisioning</a></h2>
 | 
			
		||||
    <h2><a name="provisioning">Provisioning</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/Tivoli+Provisioning+Manager">Tivoli Provisioning Manager</a></dt>
 | 
			
		||||
      <dt><a href="http://www.ibm.com/software/tivoli/products/prov-mgr/">Tivoli Provisioning Manager</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Part of the IBM Tivoli family, Tivoli Provisioning Manager (TPM) is
 | 
			
		||||
        an IT lifecycle automation product.  It
 | 
			
		||||
@@ -374,7 +362,7 @@
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://theforeman.org">Foreman</a></dt>
 | 
			
		||||
      <dt><a href="http://theforeman.org">Foreman</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
      Foreman is an open source web based application aimed to be a
 | 
			
		||||
      Single Address For All Machines Life Cycle Management. Foreman:
 | 
			
		||||
@@ -395,10 +383,10 @@
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <h2><a id="web">Web applications</a></h2>
 | 
			
		||||
    <h2><a name="web">Web applications</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="http://www.abiquo.com/">AbiCloud</a></dt>
 | 
			
		||||
      <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
 | 
			
		||||
@@ -406,22 +394,14 @@
 | 
			
		||||
        infrastructure. You can deploy a new service just dragging and
 | 
			
		||||
        dropping a VM.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://kimchi-project.github.io/kimchi/">Kimchi</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Kimchi is an HTML5 based management tool for KVM. It is designed to
 | 
			
		||||
        make it as easy as possible to get started with KVM and create your first guest.
 | 
			
		||||
 | 
			
		||||
        Kimchi manages KVM guests through libvirt. The management interface is accessed
 | 
			
		||||
        over the web using a browser that supports HTML5.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://ovirt.org/">oVirt</a></dt>
 | 
			
		||||
      <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="https://ispsystem.com/en/software/vmmanager">VMmanager</a></dt>
 | 
			
		||||
      <dt><a href="http://ispsystem.com/en/software/vmmanager">VMmanager</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        VMmanager is a software solution for virtualization management
 | 
			
		||||
        that can be used both for hosting virtual machines and
 | 
			
		||||
@@ -430,7 +410,7 @@
 | 
			
		||||
        functions, such as live migration that allows for load
 | 
			
		||||
        balancing between cluster nodes, monitoring CPU, memory.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://mist.io/">mist.io</a></dt>
 | 
			
		||||
      <dt><a href="http://mist.io/">mist.io</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Mist.io is an open source project and a service that can assist you in
 | 
			
		||||
        managing your virtual machines on a unified way, providing a simple
 | 
			
		||||
@@ -438,42 +418,16 @@
 | 
			
		||||
        providers, OpenStack based public/private clouds, Docker servers, bare
 | 
			
		||||
        metal servers and now KVM hypervisors).
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://ravada.upc.edu/">Ravada</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Ravada is an open source tool for managing Virtual Desktop
 | 
			
		||||
        Infrastructure (VDI). It is very easy to install and use. Following
 | 
			
		||||
        the documentation, you'll be ready to deploy virtual machines in
 | 
			
		||||
        minutes. The only requirements for the users are a Web browser and
 | 
			
		||||
        a lightweight remote viewer.
 | 
			
		||||
      </dd>
 | 
			
		||||
      <dt><a href="https://github.com/cutelyst/Virtlyst">Virtlyst</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Virtlyst is an open source web application built with C++11, Cutelyst and Qt.
 | 
			
		||||
        It features:
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>Low memory usage (around 5 MiB of RAM)</li>
 | 
			
		||||
          <li>Look and feel easily customized with HTML templates that use the Django syntax</li>
 | 
			
		||||
          <li>VNC/Spice console directly in the browser using websockets on the same HTTP port</li>
 | 
			
		||||
          <li>Host and Domain statistics graphs (CPU, Memory, IO, Network)</li>
 | 
			
		||||
          <li>Connect to multiple libvirtd instances (over local Unix domain socket, SSH, TCP and TLS)</li>
 | 
			
		||||
          <li>Manage Storage Pools, Storage Volumes, Networks, Interfaces, and Secrets</li>
 | 
			
		||||
          <li>Create and launch VMs</li>
 | 
			
		||||
          <li>Configure VMs with easy panels or go pro and edit the VM's XML</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
    <h2><a id="other">Other</a></h2>
 | 
			
		||||
    <h2><a name="mobile">Mobile applications</a></h2>
 | 
			
		||||
 | 
			
		||||
    <dl>
 | 
			
		||||
      <dt><a href="https://cuckoosandbox.org/">Cuckoo Sandbox</a></dt>
 | 
			
		||||
      <dt><a href="https://market.android.com/details?id=vm.manager">VM Manager</a></dt>
 | 
			
		||||
      <dd>
 | 
			
		||||
        Cuckoo Sandbox is a malware analysis system.  You can throw
 | 
			
		||||
        any suspicious file at it and in a matter of seconds Cuckoo
 | 
			
		||||
        will provide you back some detailed results outlining what
 | 
			
		||||
        such file did when executed inside an isolated environment.
 | 
			
		||||
        And libvirt is one of the backends that can be used for the
 | 
			
		||||
        isolated environment.
 | 
			
		||||
        VM Manager is VM (libvirt) manager (over SSH) application. VM Manager
 | 
			
		||||
        is an application for libvirt VM / Domain management over SSH.
 | 
			
		||||
        Please keep in mind that this software is under heavy development.
 | 
			
		||||
      </dd>
 | 
			
		||||
    </dl>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								docs/archdomain.html.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								docs/archdomain.html.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>Domain management architecture</h1>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user