mirror of
				https://gitlab.com/libvirt/libvirt.git
				synced 2025-10-30 20:24:58 +03:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			v6.0.0-rc1
			...
			v1.3.1-mai
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | be5d96d547 | ||
|  | 980109c41c | ||
|  | 84d35ef500 | ||
|  | b25ca8143a | ||
|  | ec7040c000 | ||
|  | 6a293aa29e | ||
|  | 598845b4f6 | ||
|  | 5f71b6ed14 | ||
|  | 7ed7246b4c | ||
|  | 2d5370eba6 | ||
|  | 73c3997f0f | ||
|  | f464e07f21 | ||
|  | d8cc67931c | ||
|  | bce46d6a89 | ||
|  | 58832fe437 | 
| @@ -1,40 +0,0 @@ | ||||
| -I@abs_top_builddir@ | ||||
| -I@abs_top_srcdir@ | ||||
| -I@abs_top_builddir@/gnulib/lib | ||||
| -I@abs_top_srcdir@/gnulib/lib | ||||
| -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 | ||||
							
								
								
									
										229
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										229
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,44 +1,213 @@ | ||||
| # 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/.gitignore | ||||
| /build-aux/compile | ||||
| /build-aux/depcomp | ||||
| /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 | ||||
| /m4/* | ||||
| Makefile.in | ||||
|  | ||||
| # gnulib related ignores | ||||
| !/gnulib/lib/Makefile.am | ||||
| !/gnulib/tests/Makefile.am | ||||
| *.rej | ||||
| *~ | ||||
| /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 | ||||
| /examples/rename/rename | ||||
| /gnulib/lib/* | ||||
| /gnulib/m4/* | ||||
| /gnulib/tests/* | ||||
|  | ||||
| # git related ignores | ||||
| *.orig | ||||
| .git-module-status | ||||
|  | ||||
| # libvirt related ignores | ||||
| /build/ | ||||
| /ci/scratch/ | ||||
| /include/libvirt/libvirt-common.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_admin.syms | ||||
| /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/logging/log_daemon_dispatch_stubs.h | ||||
| /src/logging/log_protocol.[ch] | ||||
| /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/test_virtlogd.aug | ||||
| /src/util/virkeymaps.h | ||||
| /src/virt-aa-helper | ||||
| /src/virtlockd | ||||
| /src/virtlockd.8 | ||||
| /src/virtlockd.8.in | ||||
| /src/virtlockd.init | ||||
| /src/virtlogd | ||||
| /src/virtlogd.8 | ||||
| /src/virtlogd.8.in | ||||
| /src/virtlogd.init | ||||
| /tests/*.log | ||||
| /tests/*.pid | ||||
| /tests/*.trs | ||||
| /tests/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-admin | ||||
| /tools/virt-*-validate | ||||
| /tools/virt-sanlock-cleanup | ||||
| /tools/wireshark/src/plugin.c | ||||
| /tools/wireshark/src/libvirt | ||||
| /update.log | ||||
| GPATH | ||||
| GRTAGS | ||||
| GTAGS | ||||
| Makefile | ||||
| Makefile.in | ||||
| 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 | ||||
							
								
								
									
										5
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,3 @@ | ||||
| [submodule "gnulib"] | ||||
| 	path = .gnulib | ||||
| 	url = https://git.savannah.gnu.org/git/gnulib.git/ | ||||
| [submodule "keycodemapdb"] | ||||
| 	path = src/keycodemapdb | ||||
| 	url = https://gitlab.com/keycodemap/keycodemapdb.git | ||||
| 	url = git://git.sv.gnu.org/gnulib.git | ||||
|   | ||||
| @@ -1,3 +0,0 @@ | ||||
| [gitpublishprofile "default"] | ||||
| base = master | ||||
| to = libvir-list@redhat.com | ||||
							
								
								
									
										2
									
								
								.gnulib
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								.gnulib
									
									
									
									
									
								
							 Submodule .gnulib updated: 7d06937892...6cc32c63e8
									
								
							
							
								
								
									
										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> | ||||
|   | ||||
							
								
								
									
										118
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,118 +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" | ||||
|         - MINGW="mingw32" | ||||
|       script: | ||||
|         - make -C ci/ ci-build@$IMAGE CI_CONFIGURE="$MINGW-configure" | ||||
|     - services: | ||||
|         - docker | ||||
|       env: | ||||
|         - IMAGE="fedora-30" | ||||
|         - MINGW="mingw64" | ||||
|       script: | ||||
|         - make -C ci/ ci-build@$IMAGE CI_CONFIGURE="$MINGW-configure" | ||||
|     - 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,45 +0,0 @@ | ||||
| flags = [ | ||||
|   '-I@abs_top_builddir@', | ||||
|   '-I@abs_top_srcdir@', | ||||
|   '-I@abs_top_builddir@/gnulib/lib', | ||||
|   '-I@abs_top_srcdir@/gnulib/lib', | ||||
|   '-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 } | ||||
							
								
								
									
										14
									
								
								AUTHORS.in
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								AUTHORS.in
									
									
									
									
									
								
							| @@ -10,30 +10,26 @@ 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 +45,6 @@ Chris Lalancette <clalance@redhat.com> | ||||
| Dan Smith <danms@us.ibm.com> | ||||
| Dave Allan <dallan@redhat.com> | ||||
| Dave Leskovec <dlesko@linux.vnet.ibm.com> | ||||
| Dmitry Guryanov <dguryanov@parallels.com> | ||||
| Guannan Ren <gren@redhat.com> | ||||
| Jim Meyering <meyering@redhat.com> | ||||
| John Levon <john.levon@sun.com> | ||||
| @@ -64,6 +59,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 +88,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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										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 | ||||
							
								
								
									
										140
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								Makefile.am
									
									
									
									
									
								
							| @@ -19,104 +19,58 @@ | ||||
| LCOV = lcov | ||||
| GENHTML = genhtml | ||||
|  | ||||
| # when building from tarball -Werror isn't auto enabled | ||||
| # so force it explicitly | ||||
| DISTCHECK_CONFIGURE_FLAGS = --enable-werror | ||||
|  | ||||
| SUBDIRS = . gnulib/lib include/libvirt src tools docs gnulib/tests \ | ||||
| SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \ | ||||
|   tests po examples | ||||
|  | ||||
| XZ_OPT ?= -v -T0 | ||||
| export XZ_OPT | ||||
|  | ||||
| ACLOCAL_AMFLAGS = -I m4 | ||||
|  | ||||
| EXTRA_DIST = \ | ||||
|   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) | ||||
|   AUTHORS.in | ||||
|  | ||||
| pkgconfigdir = $(libdir)/pkgconfig | ||||
| pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc libvirt-admin.pc | ||||
| pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc | ||||
|  | ||||
| NEWS: \ | ||||
| 	  $(srcdir)/docs/news.xml \ | ||||
| 	  $(srcdir)/docs/news-ascii.xsl \ | ||||
| 	  $(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,28 +83,28 @@ clean-cov: | ||||
|  | ||||
| MAINTAINERCLEANFILES = .git-module-status | ||||
|  | ||||
| distclean-local: clean-GNUmakefile | ||||
| clean-GNUmakefile: | ||||
| 	test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile | ||||
| # disable this check | ||||
| distuninstallcheck: | ||||
|  | ||||
| dist-hook: gen-AUTHORS | ||||
| dist-hook: gen-ChangeLog 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/ $@ | ||||
|   | ||||
| @@ -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,7 +24,7 @@ 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 | ||||
|  | ||||
| As an optional step, if you already have a copy of the gnulib git | ||||
| @@ -34,14 +33,10 @@ reduce download time and disk space requirements: | ||||
|  | ||||
|         $ export GNULIB_SRCDIR=/path/to/gnulib | ||||
|  | ||||
| We require to have the build directory different than the source directory: | ||||
|  | ||||
|         $ mkdir build && cd build | ||||
|  | ||||
| The next step is to get all required pieces from gnulib, | ||||
| to run autoreconf, and to invoke ../autogen.sh: | ||||
| to run autoreconf, and to invoke ./configure: | ||||
|  | ||||
|         $ ../autogen.sh | ||||
|         $ ./autogen.sh | ||||
|  | ||||
| And there you are!  Just | ||||
|  | ||||
| @@ -51,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 | ||||
							
								
								
									
										269
									
								
								autogen.sh
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								autogen.sh
									
									
									
									
									
								
							| @@ -1,208 +1,117 @@ | ||||
| #!/bin/sh | ||||
| # Run this to generate all the initial makefiles, etc. | ||||
|  | ||||
| die() | ||||
| { | ||||
|     echo "error: $1" >&2 | ||||
| set -e | ||||
|  | ||||
| srcdir=`dirname "$0"` | ||||
| test -z "$srcdir" && srcdir=. | ||||
|  | ||||
| THEDIR=`pwd` | ||||
| cd "$srcdir" | ||||
|  | ||||
| test -f src/libvirt.c || { | ||||
|     echo "You must run this script in the top-level libvirt directory" | ||||
|     exit 1 | ||||
| } | ||||
|  | ||||
| starting_point=$(pwd) | ||||
|  | ||||
| srcdir=$(dirname "$0") | ||||
| test "$srcdir" || srcdir=. | ||||
|  | ||||
| cd "$srcdir" || { | ||||
|     die "Failed to cd into $srcdir" | ||||
| } | ||||
|  | ||||
| test -f src/libvirt.c || { | ||||
|     die "$0 must live in the top-level libvirt directory" | ||||
| } | ||||
|  | ||||
| dry_run= | ||||
| EXTRA_ARGS= | ||||
| no_git= | ||||
| gnulib_srcdir= | ||||
| extra_args= | ||||
| while test "$#" -gt 0; do | ||||
|     case "$1" in | ||||
|     --dry-run) | ||||
|         # This variable will serve both as an indicator of the fact that | ||||
|         # a dry run has been requested, and to store the result of the | ||||
|         # dry run. It will be ultimately used as return code for the | ||||
|         # script: 0 means no action is necessary, 2 means that autogen.sh | ||||
|         # needs to be executed, and 1 is reserved for failures | ||||
|         dry_run=0 | ||||
|         shift | ||||
|         ;; | ||||
|     --no-git) | ||||
|         no_git=" $1" | ||||
|         shift | ||||
|         ;; | ||||
|     --gnulib-srcdir=*) | ||||
|         gnulib_srcdir=" $1" | ||||
|         shift | ||||
|         ;; | ||||
|     --gnulib-srcdir) | ||||
|         gnulib_srcdir=" $1=$2" | ||||
|         shift | ||||
|         shift | ||||
|         ;; | ||||
|     --system) | ||||
|         prefix=/usr | ||||
|         sysconfdir=/etc | ||||
|         localstatedir=/var | ||||
|         if test -d $prefix/lib64; then | ||||
|             libdir=$prefix/lib64 | ||||
|         else | ||||
|             libdir=$prefix/lib | ||||
|         fi | ||||
|         extra_args="--prefix=$prefix --localstatedir=$localstatedir" | ||||
|         extra_args="$extra_args --sysconfdir=$sysconfdir --libdir=$libdir" | ||||
|         shift | ||||
|         ;; | ||||
|     *) | ||||
|         # All remaining arguments will be passed to configure verbatim | ||||
|         break | ||||
|         ;; | ||||
|     esac | ||||
| done | ||||
| no_git="$no_git$gnulib_srcdir" | ||||
| if test "x$1" = "x--no-git"; then | ||||
|   no_git=" $1" | ||||
|   shift | ||||
|   case "$1 $2" in | ||||
|     --gnulib-srcdir=*) no_git="$no_git $1"; shift ;; | ||||
|     --gnulib-srcdir\ *) no_git="$no_git $1=$2"; shift; shift;; | ||||
|   esac | ||||
| fi | ||||
| if test -z "$NOCONFIGURE" ; then | ||||
|   if test "x$1" = "x--system"; then | ||||
|     shift | ||||
|     prefix=/usr | ||||
|     libdir=$prefix/lib | ||||
|     sysconfdir=/etc | ||||
|     localstatedir=/var | ||||
|     if [ -d /usr/lib64 ]; then | ||||
|       libdir=$prefix/lib64 | ||||
|     fi | ||||
|     EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir" | ||||
|     echo "Running ./configure with $EXTRA_ARGS $@" | ||||
|   else | ||||
|     if test -z "$*" && test ! -f "$THEDIR/config.status"; then | ||||
|         echo "I am going to run ./configure with no arguments - if you wish" | ||||
|         echo "to pass any to it, please specify them on the $0 command line." | ||||
|     fi | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| gnulib_hash() | ||||
| # Compute the hash we'll use to determine whether rerunning bootstrap | ||||
| # is required.  The first is just the SHA1 that selects a gnulib snapshot. | ||||
| # The second ensures that whenever we change the set of gnulib modules used | ||||
| # by this package, we rerun bootstrap to pull in the matching set of files. | ||||
| # The third ensures that whenever we change the set of local gnulib diffs, | ||||
| # we rerun bootstrap to pull in those diffs. | ||||
| bootstrap_hash() | ||||
| { | ||||
|     local no_git=$1 | ||||
|  | ||||
|     if test "$no_git"; then | ||||
|         echo "no-git" | ||||
|         echo no-git | ||||
|         return | ||||
|     fi | ||||
|  | ||||
|     # Compute the hash we'll use to determine whether rerunning bootstrap | ||||
|     # is required. The first is just the SHA1 that selects a gnulib snapshot. | ||||
|     # The second ensures that whenever we change the set of gnulib modules used | ||||
|     # by this package, we rerun bootstrap to pull in the matching set of files. | ||||
|     # The third ensures that whenever we change the set of local gnulib diffs, | ||||
|     # we rerun bootstrap to pull in those diffs. | ||||
|     git submodule status .gnulib | awk '{ print $1 }' | ||||
|     git submodule status | sed 's/^[ +-]//;s/ .*//' | ||||
|     git hash-object bootstrap.conf | ||||
|     git ls-tree -d HEAD gnulib/local | awk '{ print $3 }' | ||||
|     git ls-tree -d HEAD gnulib/local | awk '{print $3}' | ||||
| } | ||||
|  | ||||
| # Only look into git submodules if we're in a git checkout | ||||
| # Ensure that whenever we pull in a gnulib update or otherwise change to a | ||||
| # different version (i.e., when switching branches), we also rerun ./bootstrap. | ||||
| # Also, running 'make rpm' tends to litter the po/ directory, and some people | ||||
| # like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates | ||||
| # the required file po/Makevars. | ||||
| # Only run bootstrap from a git checkout, never from a tarball. | ||||
| if test -d .git || test -f .git; then | ||||
|  | ||||
|     # Check for dirty submodules | ||||
|     if test -z "$CLEAN_SUBMODULE"; then | ||||
|         for path in $(git submodule status | awk '{ print $2 }'); do | ||||
|             case "$(git diff "$path")" in | ||||
|                 *-dirty*) | ||||
|                     echo "error: $path is dirty, please investigate" >&2 | ||||
|                     echo "set CLEAN_SUBMODULE to discard submodule changes" >&2 | ||||
|                     exit 1 | ||||
|                     ;; | ||||
|             esac | ||||
|         done | ||||
|     curr_status=.git-module-status t= | ||||
|     if test "$no_git"; then | ||||
|         t=no-git | ||||
|     elif test -d .gnulib; then | ||||
|         t=$(bootstrap_hash; git diff .gnulib) | ||||
|     fi | ||||
|     if test "$CLEAN_SUBMODULE" && test -z "$no_git"; then | ||||
|         if test -z "$dry_run"; then | ||||
|             echo "Cleaning up submodules..." | ||||
|             git submodule foreach 'git clean -dfqx && git reset --hard' || { | ||||
|                 die "Cleaning up submodules failed" | ||||
|             } | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     # Update all submodules. If any of the submodules has not been | ||||
|     # initialized yet, it will be initialized now; moreover, any submodule | ||||
|     # with uncommitted changes will be returned to the expected state | ||||
|     echo "Updating submodules..." | ||||
|     git submodule update --init || { | ||||
|         die "Updating submodules failed" | ||||
|     } | ||||
|  | ||||
|     # The expected hash, eg. the one computed after the last | ||||
|     # successful bootstrap run, is stored on disk | ||||
|     state_file=.git-module-status | ||||
|     expected_hash=$(cat "$state_file" 2>/dev/null) | ||||
|     actual_hash=$(gnulib_hash "$no_git") | ||||
|  | ||||
|     if test "$actual_hash" = "$expected_hash" && test -f AUTHORS; then | ||||
|         # The gnulib hash matches our expectations, and all the files | ||||
|         # that can only be generated through bootstrap are present: | ||||
|         # we just need to run autoreconf. Unless we're performing a | ||||
|         # dry run, of course... | ||||
|         if test -z "$dry_run"; then | ||||
|             echo "Running autoreconf..." | ||||
|             autoreconf -if || { | ||||
|                 die "autoreconf failed" | ||||
|             } | ||||
|         fi | ||||
|     case $t:${CLEAN_SUBMODULE+set} in | ||||
|         *:set) ;; | ||||
|         *-dirty*) | ||||
|             echo "error: gnulib submodule is dirty, please investigate" 2>&1 | ||||
|             echo "set env-var CLEAN_SUBMODULE to discard gnulib changes" 2>&1 | ||||
|             exit 1 ;; | ||||
|     esac | ||||
|     # Keep this test in sync with cfg.mk:_update_required | ||||
|     if test "$t" = "$(cat $curr_status 2>/dev/null)" \ | ||||
|         && test -f "po/Makevars" && test -f AUTHORS; then | ||||
|         # good, it's up to date, all we need is autoreconf | ||||
|         autoreconf -if | ||||
|     else | ||||
|         # Whenever the gnulib submodule or any of the related bits | ||||
|         # has been changed in some way (see gnulib_hash) we need to | ||||
|         # run bootstrap again. If we're performing a dry run, we | ||||
|         # change the return code instead to signal our caller | ||||
|         if test "$dry_run"; then | ||||
|             dry_run=2 | ||||
|         else | ||||
|             echo "Running bootstrap..." | ||||
|             ./bootstrap$no_git --bootstrap-sync || { | ||||
|                 die "bootstrap failed" | ||||
|             } | ||||
|             gnulib_hash >"$state_file" | ||||
|         if test -z "$no_git" && test ${CLEAN_SUBMODULE+set}; then | ||||
|             echo cleaning up submodules... | ||||
|             git submodule foreach 'git clean -dfqx && git reset --hard' | ||||
|         fi | ||||
|         echo running bootstrap$no_git... | ||||
|         ./bootstrap$no_git --bootstrap-sync && bootstrap_hash > $curr_status \ | ||||
|             || { echo "Failed to bootstrap, please investigate."; exit 1; } | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| # When performing a dry run, we can stop here | ||||
| test "$dry_run" && exit "$dry_run" | ||||
| test -n "$NOCONFIGURE" && exit 0 | ||||
|  | ||||
| # If asked not to run configure, we can stop here | ||||
| test "$NOCONFIGURE" && exit 0 | ||||
| cd "$THEDIR" | ||||
|  | ||||
| cd "$starting_point" || { | ||||
|     die "Failed to cd into $starting_point" | ||||
| } | ||||
|  | ||||
| if test "$OBJ_DIR"; then | ||||
|     mkdir -p "$OBJ_DIR" || { | ||||
|         die "Failed to create $OBJ_DIR" | ||||
|     } | ||||
|     cd "$OBJ_DIR" || { | ||||
|         die "Failed to cd into $OBJ_DIR" | ||||
|     } | ||||
| if test "x$OBJ_DIR" != x; then | ||||
|     mkdir -p "$OBJ_DIR" | ||||
|     cd "$OBJ_DIR" | ||||
| fi | ||||
|  | ||||
| # Make sure we can find GNU make and tell the user | ||||
| # the right command to run | ||||
| MAKE= | ||||
| for cmd in make gmake; do | ||||
|     if $cmd -v 2>&1 | grep -q "GNU Make"; then | ||||
|         MAKE=$cmd | ||||
|         break | ||||
|     fi | ||||
| done | ||||
| test "$MAKE" || { | ||||
|     die "GNU make is required to build libvirt" | ||||
| } | ||||
|  | ||||
| if test -z "$*" && test -z "$extra_args" && test -f config.status; then | ||||
|     echo "Running config.status..." | ||||
|     ./config.status --recheck || { | ||||
|         die "config.status failed" | ||||
|     } | ||||
| if test -z "$*" && test -z "$EXTRA_ARGS" && test -f config.status; then | ||||
|     ./config.status --recheck | ||||
| else | ||||
|     if test -z "$*" && test -z "$extra_args"; then | ||||
|         echo "I am going to run configure with no arguments - if you wish" | ||||
|         echo "to pass any to it, please specify them on the $0 command line." | ||||
|     else | ||||
|         echo "Running configure with $extra_args $@" | ||||
|     fi | ||||
|     "$srcdir/configure" $extra_args "$@" || { | ||||
|         die "configure failed" | ||||
|     } | ||||
| fi | ||||
|  | ||||
| echo | ||||
| echo "Now type '$MAKE' to compile libvirt." | ||||
|     $srcdir/configure $EXTRA_ARGS "$@" | ||||
| fi && { | ||||
|     echo | ||||
|     echo "Now type 'make' to compile libvirt." | ||||
| } | ||||
|   | ||||
							
								
								
									
										345
									
								
								bootstrap
									
									
									
									
									
								
							
							
						
						
									
										345
									
								
								bootstrap
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | ||||
| #! /bin/sh | ||||
| # Print a version string. | ||||
| scriptversion=2019-01-04.17; # UTC | ||||
| scriptversion=2014-12-08.12; # UTC | ||||
|  | ||||
| # Bootstrap this package from checked-out sources. | ||||
|  | ||||
| # Copyright (C) 2003-2020 Free Software Foundation, Inc. | ||||
| # Copyright (C) 2003-2016 Free Software Foundation, Inc. | ||||
|  | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| @@ -17,7 +17,7 @@ scriptversion=2019-01-04.17; # UTC | ||||
| # 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/>. | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| # Originally written by Paul Eggert.  The canonical version of this | ||||
| # script is maintained as build-aux/bootstrap in gnulib, however, to | ||||
| @@ -42,13 +42,11 @@ export LC_ALL | ||||
|  | ||||
| local_gl_dir=gl | ||||
|  | ||||
| # Honor $PERL, but work even if there is none. | ||||
| # Honour $PERL, but work even if there is none | ||||
| PERL="${PERL-perl}" | ||||
|  | ||||
| me=$0 | ||||
|  | ||||
| default_gnulib_url=git://git.sv.gnu.org/gnulib | ||||
|  | ||||
| usage() { | ||||
|   cat <<EOF | ||||
| Usage: $me [OPTION]... | ||||
| @@ -78,37 +76,6 @@ contents are read as shell variables to configure the bootstrap. | ||||
| For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR | ||||
| are honored. | ||||
|  | ||||
| Gnulib sources can be fetched in various ways: | ||||
|  | ||||
|  * If this package is in a git repository with a 'gnulib' submodule | ||||
|    configured, then that submodule is initialized and updated and sources | ||||
|    are fetched from there.  If \$GNULIB_SRCDIR is set (directly or via | ||||
|    --gnulib-srcdir) and is a git repository, then it is used as a reference. | ||||
|  | ||||
|  * Otherwise, if \$GNULIB_SRCDIR is set (directly or via --gnulib-srcdir), | ||||
|    then sources are fetched from that local directory.  If it is a git | ||||
|    repository and \$GNULIB_REVISION is set, then that revision is checked | ||||
|    out. | ||||
|  | ||||
|  * Otherwise, if this package is in a git repository with a 'gnulib' | ||||
|    submodule configured, then that submodule is initialized and updated and | ||||
|    sources are fetched from there. | ||||
|  | ||||
|  * Otherwise, if the 'gnulib' directory does not exist, Gnulib sources are | ||||
|    cloned into that directory using git from \$GNULIB_URL, defaulting to | ||||
|    $default_gnulib_url. | ||||
|    If \$GNULIB_REVISION is set, then that revision is checked out. | ||||
|  | ||||
|  * Otherwise, the existing Gnulib sources in the 'gnulib' directory are | ||||
|    used.  If it is a git repository and \$GNULIB_REVISION is set, then that | ||||
|    revision is checked out. | ||||
|  | ||||
| If you maintain a package and want to pin a particular revision of the | ||||
| Gnulib sources that has been tested with your package, then there are two | ||||
| possible approaches: either configure a 'gnulib' submodule with the | ||||
| appropriate revision, or set \$GNULIB_REVISION (and if necessary | ||||
| \$GNULIB_URL) in $me.conf. | ||||
|  | ||||
| Running without arguments will suffice in most cases. | ||||
| EOF | ||||
| } | ||||
| @@ -162,12 +129,19 @@ bootstrap_post_import_hook() { :; } | ||||
| # Override it via your own definition in bootstrap.conf. | ||||
| bootstrap_epilogue() { :; } | ||||
|  | ||||
| # The command to download all .po files for a specified domain into a | ||||
| # specified directory.  Fill in the first %s with the destination | ||||
| # directory and the second with the domain name. | ||||
| # The command to download all .po files for a specified domain into | ||||
| # a specified directory.  Fill in the first %s is the domain name, and | ||||
| # the second with the destination directory.  Use rsync's -L and -r | ||||
| # options because the latest/%s directory and the .po files within are | ||||
| # all symlinks. | ||||
| po_download_command_format=\ | ||||
| "wget --mirror --level=1 -nd -nv -A.po -P '%s' \ | ||||
|  https://translationproject.org/latest/%s/" | ||||
| "rsync --delete --exclude '*.s1' -Lrtvz \ | ||||
|  'translationproject.org::tp/latest/%s/' '%s'" | ||||
|  | ||||
| # Fallback for downloading .po files (if rsync fails). | ||||
| po_download_command_format2=\ | ||||
| "wget --mirror -nd -q -np -A.po -P '%s' \ | ||||
|  http://translationproject.org/latest/%s/" | ||||
|  | ||||
| # Prefer a non-empty tarname (4th argument of AC_INIT if given), else | ||||
| # fall back to the package name (1st argument with munging) | ||||
| @@ -196,15 +170,7 @@ source_base=lib | ||||
| m4_base=m4 | ||||
| doc_base=doc | ||||
| tests_base=tests | ||||
| gnulib_extra_files=" | ||||
|         build-aux/install-sh | ||||
|         build-aux/mdate-sh | ||||
|         build-aux/texinfo.tex | ||||
|         build-aux/depcomp | ||||
|         build-aux/config.guess | ||||
|         build-aux/config.sub | ||||
|         doc/INSTALL | ||||
| " | ||||
| gnulib_extra_files='' | ||||
|  | ||||
| # Additional gnulib-tool options to use.  Use "\newline" to break lines. | ||||
| gnulib_tool_option_extras= | ||||
| @@ -298,18 +264,24 @@ case "$0" in | ||||
|   *) test -r "$0.conf" && . ./"$0.conf" ;; | ||||
| esac | ||||
|  | ||||
| # Extra files from gnulib, which override files from other sources. | ||||
| test -z "${gnulib_extra_files}" && \ | ||||
|   gnulib_extra_files=" | ||||
|         build-aux/install-sh | ||||
|         build-aux/mdate-sh | ||||
|         build-aux/texinfo.tex | ||||
|         build-aux/depcomp | ||||
|         build-aux/config.guess | ||||
|         build-aux/config.sub | ||||
|         doc/INSTALL | ||||
| " | ||||
|  | ||||
| if test "$vc_ignore" = auto; then | ||||
|   vc_ignore= | ||||
|   test -d .git && vc_ignore=.gitignore | ||||
|   test -d CVS && vc_ignore="$vc_ignore .cvsignore" | ||||
| fi | ||||
|  | ||||
| if test x"$gnulib_modules$gnulib_files$gnulib_extra_files" = x; then | ||||
|   use_gnulib=false | ||||
| else | ||||
|   use_gnulib=true | ||||
| fi | ||||
|  | ||||
| # Translate configuration into internal form. | ||||
|  | ||||
| # Parse options. | ||||
| @@ -446,30 +418,28 @@ sort_ver() { # sort -V is not generally available | ||||
|   done | ||||
| } | ||||
|  | ||||
| get_version_sed=' | ||||
| # Move version to start of line. | ||||
| s/.*[v ]\([0-9]\)/\1/ | ||||
|  | ||||
| # Skip lines that do not start with version. | ||||
| /^[0-9]/!d | ||||
|  | ||||
| # Remove characters after the version. | ||||
| s/[^.a-z0-9-].*// | ||||
|  | ||||
| # The first component must be digits only. | ||||
| s/^\([0-9]*\)[a-z-].*/\1/ | ||||
|  | ||||
| #the following essentially does s/5.005/5.5/ | ||||
| s/\.0*\([1-9]\)/.\1/g | ||||
| p | ||||
| q' | ||||
|  | ||||
| get_version() { | ||||
|   app=$1 | ||||
|  | ||||
|   $app --version >/dev/null 2>&1 || { $app --version; return 1; } | ||||
|  | ||||
|   $app --version 2>&1 | sed -n "$get_version_sed" | ||||
|   $app --version 2>&1 | | ||||
|   sed -n '# Move version to start of line. | ||||
|           s/.*[v ]\([0-9]\)/\1/ | ||||
|  | ||||
|           # Skip lines that do not start with version. | ||||
|           /^[0-9]/!d | ||||
|  | ||||
|           # Remove characters after the version. | ||||
|           s/[^.a-z0-9-].*// | ||||
|  | ||||
|           # The first component must be digits only. | ||||
|           s/^\([0-9]*\)[a-z-].*/\1/ | ||||
|  | ||||
|           #the following essentially does s/5.005/5.5/ | ||||
|           s/\.0*\([1-9]\)/.\1/g | ||||
|           p | ||||
|           q' | ||||
| } | ||||
|  | ||||
| check_versions() { | ||||
| @@ -640,101 +610,95 @@ git_modules_config () { | ||||
|   test -f .gitmodules && git config --file .gitmodules "$@" | ||||
| } | ||||
|  | ||||
| if $use_gnulib; then | ||||
|   if $use_git; then | ||||
|     gnulib_path=$(git_modules_config submodule.gnulib.path) | ||||
|     test -z "$gnulib_path" && gnulib_path=gnulib | ||||
| if $use_git; then | ||||
|   gnulib_path=$(git_modules_config submodule.gnulib.path) | ||||
|   test -z "$gnulib_path" && gnulib_path=gnulib | ||||
| fi | ||||
|  | ||||
| # Get gnulib files.  Populate $GNULIB_SRCDIR, possibly updating a | ||||
| # submodule, for use in the rest of the script. | ||||
|  | ||||
| case ${GNULIB_SRCDIR--} in | ||||
| -) | ||||
|   # Note that $use_git is necessarily true in this case. | ||||
|   if git_modules_config submodule.gnulib.url >/dev/null; then | ||||
|     echo "$0: getting gnulib files..." | ||||
|     git submodule init -- "$gnulib_path" || exit $? | ||||
|     git submodule update -- "$gnulib_path" || exit $? | ||||
|  | ||||
|   elif [ ! -d "$gnulib_path" ]; then | ||||
|     echo "$0: getting gnulib files..." | ||||
|  | ||||
|     trap cleanup_gnulib 1 2 13 15 | ||||
|  | ||||
|     shallow= | ||||
|     git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' | ||||
|     git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" || | ||||
|       cleanup_gnulib | ||||
|  | ||||
|     trap - 1 2 13 15 | ||||
|   fi | ||||
|  | ||||
|   # Get gnulib files.  Populate $GNULIB_SRCDIR, possibly updating a | ||||
|   # submodule, for use in the rest of the script. | ||||
|  | ||||
|   case ${GNULIB_SRCDIR--} in | ||||
|   -) | ||||
|     # Note that $use_git is necessarily true in this case. | ||||
|     if git_modules_config submodule.gnulib.url >/dev/null; then | ||||
|       echo "$0: getting gnulib files..." | ||||
|       git submodule init -- "$gnulib_path" || exit $? | ||||
|       git submodule update -- "$gnulib_path" || exit $? | ||||
|  | ||||
|     elif [ ! -d "$gnulib_path" ]; then | ||||
|       echo "$0: getting gnulib files..." | ||||
|  | ||||
|       trap cleanup_gnulib 1 2 13 15 | ||||
|  | ||||
|       shallow= | ||||
|       if test -z "$GNULIB_REVISION"; then | ||||
|         git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' | ||||
|   GNULIB_SRCDIR=$gnulib_path | ||||
|   ;; | ||||
| *) | ||||
|   # Use GNULIB_SRCDIR directly or as a reference. | ||||
|   if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ | ||||
|         git_modules_config submodule.gnulib.url >/dev/null; then | ||||
|     echo "$0: getting gnulib files..." | ||||
|     if git submodule -h|grep -- --reference > /dev/null; then | ||||
|       # Prefer the one-liner available in git 1.6.4 or newer. | ||||
|       git submodule update --init --reference "$GNULIB_SRCDIR" \ | ||||
|         "$gnulib_path" || exit $? | ||||
|     else | ||||
|       # This fallback allows at least git 1.5.5. | ||||
|       if test -f "$gnulib_path"/gnulib-tool; then | ||||
|         # Since file already exists, assume submodule init already complete. | ||||
|         git submodule update -- "$gnulib_path" || exit $? | ||||
|       else | ||||
|         # Older git can't clone into an empty directory. | ||||
|         rmdir "$gnulib_path" 2>/dev/null | ||||
|         git clone --reference "$GNULIB_SRCDIR" \ | ||||
|           "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \ | ||||
|           && git submodule init -- "$gnulib_path" \ | ||||
|           && git submodule update -- "$gnulib_path" \ | ||||
|           || exit $? | ||||
|       fi | ||||
|       git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \ | ||||
|         || cleanup_gnulib | ||||
|  | ||||
|       trap - 1 2 13 15 | ||||
|     fi | ||||
|     GNULIB_SRCDIR=$gnulib_path | ||||
|     ;; | ||||
|   *) | ||||
|     # Use GNULIB_SRCDIR directly or as a reference. | ||||
|     if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ | ||||
|           git_modules_config submodule.gnulib.url >/dev/null; then | ||||
|       echo "$0: getting gnulib files..." | ||||
|       if git submodule -h|grep -- --reference > /dev/null; then | ||||
|         # Prefer the one-liner available in git 1.6.4 or newer. | ||||
|         git submodule update --init --reference "$GNULIB_SRCDIR" \ | ||||
|           "$gnulib_path" || exit $? | ||||
|       else | ||||
|         # This fallback allows at least git 1.5.5. | ||||
|         if test -f "$gnulib_path"/gnulib-tool; then | ||||
|           # Since file already exists, assume submodule init already complete. | ||||
|           git submodule update -- "$gnulib_path" || exit $? | ||||
|         else | ||||
|           # Older git can't clone into an empty directory. | ||||
|           rmdir "$gnulib_path" 2>/dev/null | ||||
|           git clone --reference "$GNULIB_SRCDIR" \ | ||||
|             "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \ | ||||
|             && git submodule init -- "$gnulib_path" \ | ||||
|             && git submodule update -- "$gnulib_path" \ | ||||
|             || exit $? | ||||
|         fi | ||||
|       fi | ||||
|       GNULIB_SRCDIR=$gnulib_path | ||||
|     fi | ||||
|     ;; | ||||
|   esac | ||||
|  | ||||
|   if test -d "$GNULIB_SRCDIR"/.git && test -n "$GNULIB_REVISION" \ | ||||
|      && ! git_modules_config submodule.gnulib.url >/dev/null; then | ||||
|     (cd "$GNULIB_SRCDIR" && git checkout "$GNULIB_REVISION") || cleanup_gnulib | ||||
|   fi | ||||
|   ;; | ||||
| esac | ||||
|  | ||||
|   # $GNULIB_SRCDIR now points to the version of gnulib to use, and | ||||
|   # we no longer need to use git or $gnulib_path below here. | ||||
| # $GNULIB_SRCDIR now points to the version of gnulib to use, and | ||||
| # we no longer need to use git or $gnulib_path below here. | ||||
|  | ||||
|   if $bootstrap_sync; then | ||||
|     cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { | ||||
|       echo "$0: updating bootstrap and restarting..." | ||||
|       case $(sh -c 'echo "$1"' -- a) in | ||||
|         a) ignored=--;; | ||||
|         *) ignored=ignored;; | ||||
|       esac | ||||
|       exec sh -c \ | ||||
|         'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ | ||||
|         $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ | ||||
|         "$0" "$@" --no-bootstrap-sync | ||||
|     } | ||||
|   fi | ||||
|  | ||||
|   gnulib_tool=$GNULIB_SRCDIR/gnulib-tool | ||||
|   <$gnulib_tool || exit $? | ||||
| if $bootstrap_sync; then | ||||
|   cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { | ||||
|     echo "$0: updating bootstrap and restarting..." | ||||
|     case $(sh -c 'echo "$1"' -- a) in | ||||
|       a) ignored=--;; | ||||
|       *) ignored=ignored;; | ||||
|     esac | ||||
|     exec sh -c \ | ||||
|       'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ | ||||
|       $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ | ||||
|       "$0" "$@" --no-bootstrap-sync | ||||
|   } | ||||
| fi | ||||
|  | ||||
| gnulib_tool=$GNULIB_SRCDIR/gnulib-tool | ||||
| <$gnulib_tool || exit $? | ||||
|  | ||||
| # Get translations. | ||||
|  | ||||
| download_po_files() { | ||||
|   subdir=$1 | ||||
|   domain=$2 | ||||
|   echo "$me: getting translations into $subdir for $domain..." | ||||
|   cmd=$(printf "$po_download_command_format" "$subdir" "$domain") | ||||
|   cmd=$(printf "$po_download_command_format" "$domain" "$subdir") | ||||
|   eval "$cmd" && return | ||||
|   # Fallback to HTTP. | ||||
|   cmd=$(printf "$po_download_command_format2" "$subdir" "$domain") | ||||
|   eval "$cmd" | ||||
| } | ||||
|  | ||||
| @@ -824,9 +788,9 @@ symlink_to_dir() | ||||
|       # Leave any existing symlink alone, if it already points to the source, | ||||
|       # so that broken build tools that care about symlink times | ||||
|       # aren't confused into doing unnecessary builds.  Conversely, if the | ||||
|       # existing symlink's timestamp is older than the source, make it afresh, | ||||
|       # existing symlink's time stamp is older than the source, make it afresh, | ||||
|       # so that broken tools aren't confused into skipping needed builds.  See | ||||
|       # <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>. | ||||
|       # <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00326.html>. | ||||
|       test -h "$dst" && | ||||
|       src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 && | ||||
|       dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 && | ||||
| @@ -932,47 +896,36 @@ fi | ||||
|  | ||||
| # Import from gnulib. | ||||
|  | ||||
| if $use_gnulib; then | ||||
|   gnulib_tool_options="\ | ||||
|    --no-changelog\ | ||||
|    --aux-dir=$build_aux\ | ||||
|    --doc-base=$doc_base\ | ||||
|    --lib=$gnulib_name\ | ||||
|    --m4-base=$m4_base/\ | ||||
|    --source-base=$source_base/\ | ||||
|    --tests-base=$tests_base\ | ||||
|    --local-dir=$local_gl_dir\ | ||||
|    $gnulib_tool_option_extras\ | ||||
|   " | ||||
|   if test $use_libtool = 1; then | ||||
|     case "$gnulib_tool_options " in | ||||
|       *' --libtool '*) ;; | ||||
|       *) gnulib_tool_options="$gnulib_tool_options --libtool" ;; | ||||
|     esac | ||||
|   fi | ||||
|   echo "$0: $gnulib_tool $gnulib_tool_options --import ..." | ||||
|   $gnulib_tool $gnulib_tool_options --import $gnulib_modules \ | ||||
|     || die "gnulib-tool failed" | ||||
|  | ||||
|   for file in $gnulib_files; do | ||||
|     symlink_to_dir "$GNULIB_SRCDIR" $file \ | ||||
|       || die "failed to symlink $file" | ||||
|   done | ||||
| gnulib_tool_options="\ | ||||
|  --import\ | ||||
|  --no-changelog\ | ||||
|  --aux-dir $build_aux\ | ||||
|  --doc-base $doc_base\ | ||||
|  --lib $gnulib_name\ | ||||
|  --m4-base $m4_base/\ | ||||
|  --source-base $source_base/\ | ||||
|  --tests-base $tests_base\ | ||||
|  --local-dir $local_gl_dir\ | ||||
|  $gnulib_tool_option_extras\ | ||||
| " | ||||
| if test $use_libtool = 1; then | ||||
|   case "$gnulib_tool_options " in | ||||
|     *' --libtool '*) ;; | ||||
|     *) gnulib_tool_options="$gnulib_tool_options --libtool" ;; | ||||
|   esac | ||||
| fi | ||||
| echo "$0: $gnulib_tool $gnulib_tool_options --import ..." | ||||
| $gnulib_tool $gnulib_tool_options --import $gnulib_modules \ | ||||
|   || die "gnulib-tool failed" | ||||
|  | ||||
| for file in $gnulib_files; do | ||||
|   symlink_to_dir "$GNULIB_SRCDIR" $file \ | ||||
|     || die "failed to symlink $file" | ||||
| done | ||||
|  | ||||
| bootstrap_post_import_hook \ | ||||
|   || die "bootstrap_post_import_hook failed" | ||||
|  | ||||
| # Don't proceed if there are uninitialized submodules.  In particular, | ||||
| # the next step will remove dangling links, which might be links into | ||||
| # uninitialized submodules. | ||||
| # | ||||
| # Uninitialized submodules are listed with an initial dash. | ||||
| if $use_git && git submodule | grep '^-' >/dev/null; then | ||||
|   die "some git submodules are not initialized. "     \ | ||||
|       "Run 'git submodule init' and bootstrap again." | ||||
| fi | ||||
|  | ||||
| # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some | ||||
| # gnulib-populated directories.  Such .m4 files would cause aclocal to fail. | ||||
| # The following requires GNU find 4.2.3 or newer.  Considering the usual | ||||
| @@ -1065,9 +1018,9 @@ bootstrap_epilogue | ||||
| echo "$0: done.  Now you can run './configure'." | ||||
|  | ||||
| # Local variables: | ||||
| # eval: (add-hook 'before-save-hook 'time-stamp) | ||||
| # eval: (add-hook 'write-file-hooks 'time-stamp) | ||||
| # time-stamp-start: "scriptversion=" | ||||
| # time-stamp-format: "%:y-%02m-%02d.%02H" | ||||
| # time-stamp-time-zone: "UTC0" | ||||
| # time-stamp-time-zone: "UTC" | ||||
| # time-stamp-end: "; # UTC" | ||||
| # End: | ||||
|   | ||||
							
								
								
									
										267
									
								
								bootstrap.conf
									
									
									
									
									
								
							
							
						
						
									
										267
									
								
								bootstrap.conf
									
									
									
									
									
								
							| @@ -10,121 +10,136 @@ | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU Lesser General Public License for more details. | ||||
| # GNU General Public License for more details. | ||||
|  | ||||
| # You should have received a copy of the GNU Lesser General Public | ||||
| # License along with this library.  If not, see | ||||
| # <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 | ||||
| ' | ||||
|  | ||||
| # NB the GSocket conversion is non-trivial due to the | ||||
| # different FD vs HANDLE usage in gnulib vs glib. Need | ||||
| # to find a way to duplicate a socket HANDLE before | ||||
| # turning it into a FD, since closing an FD also closes | ||||
| # the original HANDLE. | ||||
|  | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules accept" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules bind" | ||||
| # -> conditional build to avoid Win32 | ||||
| gnulib_modules="$gnulib_modules chown" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules close" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules connect" | ||||
| # -> Meson | ||||
| gnulib_modules="$gnulib_modules configmake" | ||||
| # -> eliminate usage in some manner | ||||
| gnulib_modules="$gnulib_modules environ" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules fcntl" | ||||
| # -> conditional build avoid win32 | ||||
| gnulib_modules="$gnulib_modules fcntl-h" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules getaddrinfo" | ||||
| # -> copy gnuliub win32 impl | ||||
| gnulib_modules="$gnulib_modules getpass" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules getpeername" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules getsockname" | ||||
| # -> copy gnulib STRBUFLEN macro | ||||
| gnulib_modules="$gnulib_modules intprops" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules ioctl" | ||||
| # -> Meson | ||||
| gnulib_modules="$gnulib_modules largefile" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules listen" | ||||
| # -> custom configure check | ||||
| gnulib_modules="$gnulib_modules localeconv" | ||||
| # -> Meson | ||||
| gnulib_modules="$gnulib_modules manywarnings" | ||||
| # -> painful copy gnulib | ||||
| gnulib_modules="$gnulib_modules mgetgroups" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules net_if" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules netdb" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules nonblocking" | ||||
| # -> Just add -lutil to cli | ||||
| gnulib_modules="$gnulib_modules openpty" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules passfd" | ||||
| # -> open code / copy gnulib code | ||||
| gnulib_modules="$gnulib_modules physmem" | ||||
| # -> open code / conditional comp | ||||
| gnulib_modules="$gnulib_modules pipe-posix" | ||||
| # -> open code / conditional comp | ||||
| gnulib_modules="$gnulib_modules pipe2" | ||||
| # -> GMainLoop | ||||
| gnulib_modules="$gnulib_modules poll" | ||||
| # -> Meson | ||||
| gnulib_modules="$gnulib_modules posix-shell" | ||||
| # -> open code conditional logic | ||||
| gnulib_modules="$gnulib_modules pthread_sigmask" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules recv" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules send" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules setsockopt" | ||||
| # -> open code conditional logic | ||||
| gnulib_modules="$gnulib_modules sigaction" | ||||
| # -> open code conditional logic | ||||
| gnulib_modules="$gnulib_modules sigpipe" | ||||
| # -> GSocket | ||||
| gnulib_modules="$gnulib_modules socket" | ||||
| # -> open code conditional or use GIO GFileInfo | ||||
| gnulib_modules="$gnulib_modules stat-time" | ||||
| # -> remove use or open-code it. possibly add to glib | ||||
| gnulib_modules="$gnulib_modules strchrnul" | ||||
| # -> g_strsplit | ||||
| gnulib_modules="$gnulib_modules strtok_r" | ||||
| # -> remove sys/stat.h include from any win32 code paths | ||||
| gnulib_modules="$gnulib_modules sys_stat" | ||||
| # -> remove sys/wait.h include from any win32 code paths | ||||
| gnulib_modules="$gnulib_modules sys_wait" | ||||
| # -> remove from any win32 code paths | ||||
| gnulib_modules="$gnulib_modules termios" | ||||
| # -> GDateTime ? | ||||
| gnulib_modules="$gnulib_modules time_r" | ||||
| # -> obsolete - exists on Linux, MacOS >= ?? & FreeBSD >= 6 | ||||
| gnulib_modules="$gnulib_modules ttyname_r" | ||||
| # -> g_get_os_info in GLib 2.64 but can't use that yet | ||||
| gnulib_modules="$gnulib_modules uname" | ||||
| # -> G_STATIC_ASSERT | ||||
| gnulib_modules="$gnulib_modules verify" | ||||
| # -> remove from Win32 code paths | ||||
| gnulib_modules="$gnulib_modules waitpid" | ||||
| # -> Meson | ||||
| gnulib_modules="$gnulib_modules warnings" | ||||
| # -> open code impl | ||||
| gnulib_modules="$gnulib_modules wcwidth" | ||||
| # 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 | ||||
| @@ -133,6 +148,31 @@ 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+ | ||||
| @@ -160,11 +200,14 @@ local_gl_dir=gnulib/local | ||||
| 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 - | ||||
| rpcgen     - | ||||
| tar        - | ||||
| @@ -172,8 +215,8 @@ xmllint	   - | ||||
| xsltproc   - | ||||
| " | ||||
|  | ||||
| # Automake requires that AUTHORS exist. | ||||
| touch AUTHORS || exit 1 | ||||
| # 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=" | ||||
| @@ -193,9 +236,3 @@ bootstrap_post_import_hook() | ||||
|   sed 's,\.\./\.\./\.\.,../..,g; s/^TESTS /GNULIB_TESTS /' $m > $m-t | ||||
|   mv -f $m-t $m | ||||
| } | ||||
|  | ||||
| bootstrap_epilogue() | ||||
| { | ||||
|     echo "$0: done.  Now you can run 'mkdir build && cd build && ../configure'." | ||||
|     exit 0 | ||||
| } | ||||
|   | ||||
							
								
								
									
										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: | ||||
							
								
								
									
										268
									
								
								ci/Makefile
									
									
									
									
									
								
							
							
						
						
									
										268
									
								
								ci/Makefile
									
									
									
									
									
								
							| @@ -1,268 +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; \ | ||||
| 		sudo \ | ||||
| 		  --login \ | ||||
| 		  --user="#$(CI_UID)" \ | ||||
| 		  --group="#$(CI_GID)" \ | ||||
| 		  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 | ||||
							
								
								
									
										40
									
								
								ci/build.sh
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								ci/build.sh
									
									
									
									
									
								
							| @@ -1,40 +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 | ||||
|  | ||||
| # gl_public_submodule_commit= to disable gnulib's submodule check | ||||
| # which breaks due to way we clone the submodules | ||||
| make -j"$CI_SMP" gl_public_submodule_commit= $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,46 +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; gnulib relies | ||||
|  * on this to be defined in features.h, which should be included from ctype.h. | ||||
|  * This doesn't happen on many non-glibc systems. | ||||
|  * When __GNUC_PREREQ is not defined, gnulib defines it to 0, which breaks things. | ||||
|  * 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 | ||||
|   | ||||
							
								
								
									
										2847
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										2847
									
								
								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: $(top_srcdir)/src/rpc/gendispatch.pl \ | ||||
| 		$(ADMIN_PROTOCOL) | ||||
| 	$(AM_V_GEN)$(PERL) -w $(top_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)	\ | ||||
| 		$(NULL) | ||||
| libvirtd_admin_la_LDFLAGS = \ | ||||
| 		$(PIE_LDFLAGS)		\ | ||||
| 		$(RELRO_LDFLAGS)	\ | ||||
| 		$(COVERAGE_LDFLAGS)	\ | ||||
| 		$(NO_INDIRECT_LDFLAGS)  \ | ||||
| 		$(NULL) | ||||
| 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 | ||||
							
								
								
									
										126
									
								
								daemon/admin_server.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								daemon/admin_server.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| /* | ||||
|  * 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; | ||||
| } | ||||
|  | ||||
| static int | ||||
| adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED, | ||||
|                           unsigned long long *libVer) | ||||
| { | ||||
|     if (libVer) | ||||
|         *libVer = LIBVIR_VERSION_NUMBER; | ||||
|     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__ */ | ||||
							
								
								
									
										522
									
								
								daemon/libvirtd-config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										522
									
								
								daemon/libvirtd-config.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,522 @@ | ||||
| /* | ||||
|  * 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->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; | ||||
|  | ||||
|     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_INT(conf, filename, admin_keepalive_interval); | ||||
|     GET_CONF_UINT(conf, filename, admin_keepalive_count); | ||||
|  | ||||
|     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; | ||||
| } | ||||
							
								
								
									
										106
									
								
								daemon/libvirtd-config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								daemon/libvirtd-config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| /* | ||||
|  * 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 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 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 | ||||
							
								
								
									
										1623
									
								
								daemon/libvirtd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1623
									
								
								daemon/libvirtd.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										460
									
								
								daemon/libvirtd.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										460
									
								
								daemon/libvirtd.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,460 @@ | ||||
| # 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 the category | ||||
| #      given in the VIR_LOG_INIT() at the top of each libvirt source | ||||
| #      file, e.g., "remote", "qemu", or "util.json" (the name in the | ||||
| #      filter can be a substring of the full category name, in order | ||||
| #      to match multiple similar categories), 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 | ||||
|  | ||||
| # | ||||
| # These configuration options are no longer used.  There is no way to | ||||
| # restrict such clients from connecting since they first need to | ||||
| # connect in order to ask for keepalive. | ||||
| # | ||||
| #keepalive_required = 1 | ||||
| #admin_keepalive_required = 1 | ||||
|  | ||||
| # Keepalive settings for the admin interface | ||||
| #admin_keepalive_interval = 5 | ||||
| #admin_keepalive_count = 5 | ||||
							
								
								
									
										91
									
								
								daemon/libvirtd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								daemon/libvirtd.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| /* | ||||
|  * 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; | ||||
| }; | ||||
|  | ||||
| /* 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 | ||||
							
								
								
									
										122
									
								
								daemon/libvirtd.init.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								daemon/libvirtd.init.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| # the following is the LSB init header see | ||||
| # http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html | ||||
| # | ||||
| ### BEGIN INIT INFO | ||||
| # Provides: libvirtd | ||||
| # Default-Start: 3 4 5 | ||||
| # Default-Stop: 0 1 2 6 | ||||
| # Required-Start: $network messagebus virtlogd | ||||
| # Required-Stop: $network messagebus | ||||
| # Should-Start: $named xend avahi-daemon virtlockd | ||||
| # Should-Stop: $named | ||||
| # 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 | ||||
							
								
								
									
										26
									
								
								daemon/libvirtd.service.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								daemon/libvirtd.service.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| [Unit] | ||||
| Description=Virtualization daemon | ||||
| Before=libvirt-guests.service | ||||
| After=network.target | ||||
| After=dbus.service | ||||
| After=iscsid.service | ||||
| After=apparmor.service | ||||
| After=local-fs.target | ||||
| After=remote-fs.target | ||||
| 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 | ||||
| Also=virtlockd.socket | ||||
| Also=virtlogd.socket | ||||
							
								
								
									
										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 | ||||
							
								
								
									
										6828
									
								
								daemon/remote.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6828
									
								
								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_required" = "1" } | ||||
|         { "admin_keepalive_interval" = "5" } | ||||
|         { "admin_keepalive_count" = "5" } | ||||
| @@ -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> | ||||
|   | ||||
							
								
								
									
										628
									
								
								docs/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										628
									
								
								docs/Makefile.am
									
									
									
									
									
								
							| @@ -16,151 +16,72 @@ | ||||
| ## License along with this library.  If not, see | ||||
| ## <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| HTML_DIR = $(docdir)/html | ||||
| PERL = perl | ||||
|  | ||||
| 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) | ||||
| # The directory containing the source code (if it contains documentation). | ||||
| DOC_SOURCE_DIR=../src | ||||
|  | ||||
| modules_admin = libvirt-admin | ||||
| modules_qemu = libvirt-qemu | ||||
| modules_lxc = libvirt-lxc | ||||
| DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt | ||||
|  | ||||
| all: vpathhack | ||||
|  | ||||
| # 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,166 +92,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 | ||||
| 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) > $@ || { 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) > $@ || { 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) > $@ || { 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 \ | ||||
| @@ -343,146 +151,160 @@ 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 \ | ||||
| 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 \ | ||||
|   $(schema_DATA) | ||||
|  | ||||
| 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) > $@ || { 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) $< > $@ || { 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 \ | ||||
| $(APIBUILD_STAMP): $(srcdir)/apibuild.py \ | ||||
| 		$(top_srcdir)/include/libvirt/libvirt.h \ | ||||
| 		$(top_srcdir)/include/libvirt/libvirt-common.h.in \ | ||||
| 		$(top_srcdir)/include/libvirt/libvirt-domain-checkpoint.h \ | ||||
| 		$(top_srcdir)/include/libvirt/libvirt-domain-snapshot.h \ | ||||
| 		$(top_srcdir)/include/libvirt/libvirt-domain.h \ | ||||
| 		$(top_srcdir)/include/libvirt/libvirt-event.h \ | ||||
| @@ -499,23 +321,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> | ||||
| @@ -459,11 +350,11 @@ polkit.addRule(function(action, subject) { | ||||
|  | ||||
|     <p> | ||||
|     See | ||||
|     <a href="https://libvirt.org/git/?p=libvirt.git;a=tree;f=examples/polkit;hb=HEAD">source code</a> | ||||
|     <a href="http://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 +382,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 +392,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 Virtuozzo. | ||||
|     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 | ||||
|  | ||||
							
								
								
									
										2619
									
								
								docs/apibuild.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2619
									
								
								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,7 +220,17 @@ | ||||
|         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 | ||||
| @@ -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, | ||||
| @@ -262,19 +272,9 @@ | ||||
|         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 +290,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 +303,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 +320,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 +331,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 +351,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 +372,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 +393,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 +404,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 +420,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,35 +428,23 @@ | ||||
|         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> | ||||
|     </dl> | ||||
|  | ||||
|     <h2><a name="mobile">Mobile applications</a></h2> | ||||
|  | ||||
|     <dl> | ||||
|       <dt><a href="https://market.android.com/details?id=vm.manager">VM Manager</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> | ||||
|         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> | ||||
|  | ||||
|     <h2><a id="other">Other</a></h2> | ||||
|     <h2><a name="other">Other</a></h2> | ||||
|  | ||||
|     <dl> | ||||
|       <dt><a href="https://cuckoosandbox.org/">Cuckoo Sandbox</a></dt> | ||||
|       <dt><a href="http://cuckoosandbox.org/">Cuckoo Sandbox</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 | ||||
|   | ||||
							
								
								
									
										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> | ||||
| @@ -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 >libvirt architecture</h1> | ||||
| @@ -13,38 +13,54 @@ | ||||
|  | ||||
|     <ul id="toc"></ul> | ||||
|  | ||||
|     <h2><a id="Xen">Xen support</a></h2> | ||||
|     <h2><a name="Xen">Xen support</a></h2> | ||||
|  | ||||
|     <p>When running in a Xen environment, programs using libvirt have to execute | ||||
| in "Domain 0", which is the primary Linux OS loaded on the machine. That OS | ||||
| kernel provides most if not all of the actual drivers used by the set of | ||||
| domains. It also runs the Xen Store, a database of information shared by the | ||||
| hypervisor, the backend drivers, any running domains, and libxl (aka libxenlight). | ||||
| libxl provides a set of APIs for creating and managing domains, which can be used | ||||
| by applications such as the xl tool provided by Xen or libvirt. The hypervisor, | ||||
| hypervisor, the kernels, the drivers and the xen daemon. Xend. The xen daemon | ||||
| supervise the control and execution of the sets of domains. The hypervisor, | ||||
| drivers, kernels and daemons communicate though a shared system bus | ||||
| implemented in the hypervisor. The figure below tries to provide a view of | ||||
| this environment:</p> | ||||
|     <img src="architecture.gif" alt="The Xen architecture" /> | ||||
|     <p>The library will interact with libxl for all management operations | ||||
| on a Xen system.</p> | ||||
|     <p>Note that the libvirt libxl driver only supports root access.</p> | ||||
|     <p>The library can be initialized in 2 ways depending on the level of | ||||
| privilege of the embedding program. If it runs with root access, | ||||
| virConnectOpen() can be used, it will use three different ways to connect to | ||||
| the Xen infrastructure:</p> | ||||
|     <ul> | ||||
|       <li>a connection to the Xen Daemon though an HTTP RPC layer</li> | ||||
|       <li>a read/write connection to the Xen Store</li> | ||||
|       <li>use Xen Hypervisor calls</li> | ||||
|       <li>when used as non-root libvirt connect to a proxy daemon running | ||||
|       as root and providing read-only support</li> | ||||
|     </ul> | ||||
|     <p>The library will usually interact with the Xen daemon for any operation | ||||
| changing the state of the system, but for performance and accuracy reasons | ||||
| may talk directly to the hypervisor when gathering state information at | ||||
| least when possible (i.e. when the running program using libvirt has root | ||||
| privilege access).</p> | ||||
|     <p>If it runs without root access virConnectOpenReadOnly() should be used to | ||||
| connect to initialize the library. It will then fork a libvirt_proxy | ||||
| program running as root and providing read_only access to the API, this is | ||||
| then only useful for reporting and monitoring.</p> | ||||
|  | ||||
|     <h2><a id="QEMU">QEMU and KVM support</a></h2> | ||||
|     <h2><a name="QEmu">QEmu and KVM support</a></h2> | ||||
|  | ||||
|     <p>The model for QEMU and KVM is completely similar, basically KVM is based | ||||
| on QEMU for the process controlling a new domain, only small details differs | ||||
|     <p>The model for QEmu and KVM is completely similar, basically KVM is based | ||||
| on QEmu for the process controlling a new domain, only small details differs | ||||
| between the two. In both case the libvirt API is provided by a controlling | ||||
| process forked by libvirt in the background and which launch and control the | ||||
| QEMU or KVM process. That program called libvirt_qemud talks though a specific | ||||
| protocol to the library, and connects to the console of the QEMU process in | ||||
| QEmu or KVM process. That program called libvirt_qemud talks though a specific | ||||
| protocol to the library, and connects to the console of the QEmu process in | ||||
| order to control and report on its status. Libvirt tries to expose all the | ||||
| emulations models of QEMU, the selection is done when creating the new | ||||
| emulations models of QEmu, the selection is done when creating the new | ||||
| domain, by specifying the architecture and machine type targeted.</p> | ||||
|     <p>The code controlling the QEMU process is available in the | ||||
|     <p>The code controlling the QEmu process is available in the | ||||
| <code>qemud/</code> directory.</p> | ||||
|  | ||||
|     <h2><a id="drivers">Driver based architecture</a></h2> | ||||
|     <h2><a name="drivers">Driver based architecture</a></h2> | ||||
|  | ||||
|     <p>As the previous section explains, libvirt can communicate using different | ||||
| channels with the current hypervisor, and should also be able to use | ||||
| @@ -67,9 +83,9 @@ drivers present in driver.h:</p> | ||||
|     is in the <code>proxy/</code> directory.</li> | ||||
|       <li>xm_internal: provide support for Xen defined but not running | ||||
|     domains.</li> | ||||
|       <li>qemu_internal: implement the driver functions for QEMU and | ||||
|       <li>qemu_internal: implement the driver functions for QEmu and | ||||
|     KVM virtualization engines. It also uses a qemud/ specific daemon | ||||
|     which interacts with the QEMU process to implement libvirt API.</li> | ||||
|     which interacts with the QEmu process to implement libvirt API.</li> | ||||
|       <li>test: this is a test driver useful for regression tests of the | ||||
|     front-end part of libvirt.</li> | ||||
|     </ul> | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user