mirror of
				https://gitlab.com/libvirt/libvirt.git
				synced 2025-11-02 04:24:20 +03:00 
			
		
		
		
	Compare commits
	
		
			258 Commits
		
	
	
		
			v5.4.0
			...
			v0.10.2-ma
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					418a165da6 | ||
| 
						 | 
					a397e887ed | ||
| 
						 | 
					0fa54204f2 | ||
| 
						 | 
					16d55b311a | ||
| 
						 | 
					da038007c2 | ||
| 
						 | 
					1f9e9f830e | ||
| 
						 | 
					b1066acb19 | ||
| 
						 | 
					35ed979698 | ||
| 
						 | 
					41a540c78f | ||
| 
						 | 
					f59d02c487 | ||
| 
						 | 
					95836cb26b | ||
| 
						 | 
					7a9bcfa1cc | ||
| 
						 | 
					5f5e9eb23d | ||
| 
						 | 
					e200284078 | ||
| 
						 | 
					dae75860eb | ||
| 
						 | 
					56222e0428 | ||
| 
						 | 
					6cfc7a5d09 | ||
| 
						 | 
					84da8110c1 | ||
| 
						 | 
					7b5ea428c8 | ||
| 
						 | 
					648bd03118 | ||
| 
						 | 
					455de1215c | ||
| 
						 | 
					77d448e15d | ||
| 
						 | 
					cd03624eec | ||
| 
						 | 
					d0b0b052d3 | ||
| 
						 | 
					595969b2da | ||
| 
						 | 
					53b882aad5 | ||
| 
						 | 
					ecad40d8b8 | ||
| 
						 | 
					cf86d7b3a3 | ||
| 
						 | 
					3812acfeef | ||
| 
						 | 
					fbe85fa4fd | ||
| 
						 | 
					0b2750c28e | ||
| 
						 | 
					c061ff5e4a | ||
| 
						 | 
					f8d1fb438f | ||
| 
						 | 
					6829f0e40a | ||
| 
						 | 
					65b0ee31b1 | ||
| 
						 | 
					4e64a086e1 | ||
| 
						 | 
					f468720661 | ||
| 
						 | 
					27b2639f16 | ||
| 
						 | 
					1bee06a4ab | ||
| 
						 | 
					f5009405f5 | ||
| 
						 | 
					9e674d5b48 | ||
| 
						 | 
					f8085a5471 | ||
| 
						 | 
					a93f2757e2 | ||
| 
						 | 
					7c4b6833bb | ||
| 
						 | 
					0305c271fc | ||
| 
						 | 
					364bbdc4cc | ||
| 
						 | 
					69838772cc | ||
| 
						 | 
					742dd7b75f | ||
| 
						 | 
					05bfbdba00 | ||
| 
						 | 
					39dcf00e72 | ||
| 
						 | 
					69ef9b78c8 | ||
| 
						 | 
					bf95285541 | ||
| 
						 | 
					4f9e72c38f | ||
| 
						 | 
					3b7180f1d4 | ||
| 
						 | 
					0f2eda0da9 | ||
| 
						 | 
					fd00ec8f92 | ||
| 
						 | 
					11f56fc7a8 | ||
| 
						 | 
					8ac4f9ce74 | ||
| 
						 | 
					0b0ecdfc6d | ||
| 
						 | 
					610aadd635 | ||
| 
						 | 
					8e72362ec8 | ||
| 
						 | 
					f50a9b3be1 | ||
| 
						 | 
					6f290666dc | ||
| 
						 | 
					afb32d4a2b | ||
| 
						 | 
					d4e0e86c49 | ||
| 
						 | 
					2bcf1522ff | ||
| 
						 | 
					2c7638fdb4 | ||
| 
						 | 
					879f28a9f3 | ||
| 
						 | 
					119c079c5b | ||
| 
						 | 
					e91f69ed89 | ||
| 
						 | 
					96a49bd8bb | ||
| 
						 | 
					50a1a57e4c | ||
| 
						 | 
					95ea6a38bd | ||
| 
						 | 
					8a57d799ca | ||
| 
						 | 
					741f004378 | ||
| 
						 | 
					66fa059e1a | ||
| 
						 | 
					b03cf6d6bc | ||
| 
						 | 
					f63b9694dc | ||
| 
						 | 
					460e481647 | ||
| 
						 | 
					8cdeb0f85e | ||
| 
						 | 
					f104a2a6b3 | ||
| 
						 | 
					c52667e241 | ||
| 
						 | 
					ba4e7b6344 | ||
| 
						 | 
					5e10d0ef1e | ||
| 
						 | 
					2d6eaba201 | ||
| 
						 | 
					a054aa94e8 | ||
| 
						 | 
					5c31525082 | ||
| 
						 | 
					48baba6a02 | ||
| 
						 | 
					61511ae63a | ||
| 
						 | 
					6b789ea3e0 | ||
| 
						 | 
					52fca883d2 | ||
| 
						 | 
					f8ac83ec2e | ||
| 
						 | 
					9330984eef | ||
| 
						 | 
					1a32232e57 | ||
| 
						 | 
					b8279deda7 | ||
| 
						 | 
					2b47328d44 | ||
| 
						 | 
					536c0e3e4f | ||
| 
						 | 
					891ca055f4 | ||
| 
						 | 
					ecb70714a7 | ||
| 
						 | 
					ab4b82c329 | ||
| 
						 | 
					05dd67417f | ||
| 
						 | 
					d39ef5a01f | ||
| 
						 | 
					84cbd3a98a | ||
| 
						 | 
					475b00440b | ||
| 
						 | 
					88e3b40e76 | ||
| 
						 | 
					0617864e2c | ||
| 
						 | 
					9b625cbcf0 | ||
| 
						 | 
					9774343564 | ||
| 
						 | 
					9034c9286e | ||
| 
						 | 
					6187407154 | ||
| 
						 | 
					8b60ff7f10 | ||
| 
						 | 
					68fb799b46 | ||
| 
						 | 
					8a0bb98d1e | ||
| 
						 | 
					34d3627abc | ||
| 
						 | 
					0e78179d0e | ||
| 
						 | 
					9720cc8195 | ||
| 
						 | 
					2f4d266d1f | ||
| 
						 | 
					e8d28ec3fa | ||
| 
						 | 
					caf1377a12 | ||
| 
						 | 
					a565e20b08 | ||
| 
						 | 
					e4e5a4d349 | ||
| 
						 | 
					2e7298d718 | ||
| 
						 | 
					3926d8571b | ||
| 
						 | 
					e69aaf2f7e | ||
| 
						 | 
					dd35c8dadd | ||
| 
						 | 
					f928284b85 | ||
| 
						 | 
					74aa3ffec2 | ||
| 
						 | 
					49ed3cd1f6 | ||
| 
						 | 
					1083e4183f | ||
| 
						 | 
					7e3b1283f1 | ||
| 
						 | 
					bf8efc3398 | ||
| 
						 | 
					fac1a19dfc | ||
| 
						 | 
					89cecbbecc | ||
| 
						 | 
					1f45a3233c | ||
| 
						 | 
					9d239b5956 | ||
| 
						 | 
					f45dded083 | ||
| 
						 | 
					179216680e | ||
| 
						 | 
					adc0bc4c1d | ||
| 
						 | 
					8b6567005c | ||
| 
						 | 
					2484fb2ef7 | ||
| 
						 | 
					b300c71fbf | ||
| 
						 | 
					ddf4a85db8 | ||
| 
						 | 
					ec48fd7d93 | ||
| 
						 | 
					c18efc8e6e | ||
| 
						 | 
					74aaec03eb | ||
| 
						 | 
					caea712245 | ||
| 
						 | 
					3186eb057c | ||
| 
						 | 
					d070eee1b2 | ||
| 
						 | 
					245c8135fe | ||
| 
						 | 
					e1cb1c06ec | ||
| 
						 | 
					a2e51ac038 | ||
| 
						 | 
					77b780f581 | ||
| 
						 | 
					b222c47b53 | ||
| 
						 | 
					beb086f638 | ||
| 
						 | 
					d3fd617699 | ||
| 
						 | 
					b16a4ca98b | ||
| 
						 | 
					2d49ed5d18 | ||
| 
						 | 
					43995ddcc4 | ||
| 
						 | 
					9a5430414d | ||
| 
						 | 
					d676b742ca | ||
| 
						 | 
					8a95078f98 | ||
| 
						 | 
					ec3f5cad8e | ||
| 
						 | 
					c3cc4c1835 | ||
| 
						 | 
					0004a11879 | ||
| 
						 | 
					58320848d2 | ||
| 
						 | 
					d819936146 | ||
| 
						 | 
					3f3d0944a1 | ||
| 
						 | 
					b29534a6ed | ||
| 
						 | 
					48aaabd99d | ||
| 
						 | 
					3fbab08a52 | ||
| 
						 | 
					337efad95e | ||
| 
						 | 
					c1bbfabd04 | ||
| 
						 | 
					d7751c34b8 | ||
| 
						 | 
					165518d508 | ||
| 
						 | 
					ab02e39f59 | ||
| 
						 | 
					e549450714 | ||
| 
						 | 
					759c7195f0 | ||
| 
						 | 
					3feed5c100 | ||
| 
						 | 
					d564e0a81c | ||
| 
						 | 
					93ac917c95 | ||
| 
						 | 
					9a9527d21f | ||
| 
						 | 
					e9f16f2542 | ||
| 
						 | 
					addce0a74a | ||
| 
						 | 
					9f85b713fa | ||
| 
						 | 
					ff5a1ea09a | ||
| 
						 | 
					03bf498f2c | ||
| 
						 | 
					bd098c1143 | ||
| 
						 | 
					cbee5d8b90 | ||
| 
						 | 
					aa9f65c869 | ||
| 
						 | 
					acb169d0a1 | ||
| 
						 | 
					965e4c3c24 | ||
| 
						 | 
					3d12463644 | ||
| 
						 | 
					6bae2c413d | ||
| 
						 | 
					a5f8a78f90 | ||
| 
						 | 
					10f8762b4f | ||
| 
						 | 
					874a336108 | ||
| 
						 | 
					f1de8d3beb | ||
| 
						 | 
					11b13b3619 | ||
| 
						 | 
					64a9993c17 | ||
| 
						 | 
					cefa64cafd | ||
| 
						 | 
					ec08a738e8 | ||
| 
						 | 
					4c2a38d1ed | ||
| 
						 | 
					2716c78c3f | ||
| 
						 | 
					e620a97a94 | ||
| 
						 | 
					0dd956b9c3 | ||
| 
						 | 
					39db0d2dce | ||
| 
						 | 
					f5650a37f7 | ||
| 
						 | 
					77cecd2bc3 | ||
| 
						 | 
					29a2a91187 | ||
| 
						 | 
					95440c51a0 | ||
| 
						 | 
					ad5afcd14c | ||
| 
						 | 
					3709804d8a | ||
| 
						 | 
					1fd7c2617e | ||
| 
						 | 
					95110e715d | ||
| 
						 | 
					71460b50b7 | ||
| 
						 | 
					81a7baf163 | ||
| 
						 | 
					220d25cd02 | ||
| 
						 | 
					d2c0f2e3b9 | ||
| 
						 | 
					47489d64c6 | ||
| 
						 | 
					88c7f28b5f | ||
| 
						 | 
					9e423dd375 | ||
| 
						 | 
					1bc28c283b | ||
| 
						 | 
					6730e6352f | ||
| 
						 | 
					6d4bca5b1f | ||
| 
						 | 
					cf2d85cdf5 | ||
| 
						 | 
					e302d32f0f | ||
| 
						 | 
					ccc7671135 | ||
| 
						 | 
					5c18805704 | ||
| 
						 | 
					0cfd7b9afe | ||
| 
						 | 
					72ad93f00d | ||
| 
						 | 
					2a85eaee82 | ||
| 
						 | 
					beb9dd9cd9 | ||
| 
						 | 
					ad9d186370 | ||
| 
						 | 
					9875efbdc3 | ||
| 
						 | 
					440c15444a | ||
| 
						 | 
					eed4cb360b | ||
| 
						 | 
					b635baf666 | ||
| 
						 | 
					14cf67e6fb | ||
| 
						 | 
					e37286dadf | ||
| 
						 | 
					650a37faa5 | ||
| 
						 | 
					7e3dab4b9d | ||
| 
						 | 
					fdfb18690d | ||
| 
						 | 
					e81632740f | ||
| 
						 | 
					3c860c40e3 | ||
| 
						 | 
					a8ad93965f | ||
| 
						 | 
					f4e3a2afa5 | ||
| 
						 | 
					c9791620a0 | ||
| 
						 | 
					df2b4be5cb | ||
| 
						 | 
					a05d4ca932 | ||
| 
						 | 
					a5cf2ef4a7 | ||
| 
						 | 
					5292eed6e2 | ||
| 
						 | 
					88589de79c | ||
| 
						 | 
					035d998f01 | ||
| 
						 | 
					6b2a4e2514 | ||
| 
						 | 
					b53782f102 | ||
| 
						 | 
					f35c18c783 | ||
| 
						 | 
					eeaa15b6ea | ||
| 
						 | 
					94090184c2 | 
@@ -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
 | 
					 | 
				
			||||||
							
								
								
									
										6
									
								
								.ctags
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								.ctags
									
									
									
									
									
								
							@@ -1,6 +0,0 @@
 | 
				
			|||||||
--recurse
 | 
					 | 
				
			||||||
--exclude=*.orig
 | 
					 | 
				
			||||||
--exclude=*.html
 | 
					 | 
				
			||||||
--exclude=*.html.in
 | 
					 | 
				
			||||||
--langmap=c:+.h.in
 | 
					 | 
				
			||||||
--c-kinds=+p
 | 
					 | 
				
			||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
../.ctags
 | 
					 | 
				
			||||||
							
								
								
									
										182
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										182
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,11 +1,8 @@
 | 
				
			|||||||
*#*#
 | 
					*#*#
 | 
				
			||||||
*.#*#
 | 
					*.#*#
 | 
				
			||||||
*.[187]
 | 
					 | 
				
			||||||
*.[187].in
 | 
					 | 
				
			||||||
*.a
 | 
					*.a
 | 
				
			||||||
*.cov
 | 
					*.cov
 | 
				
			||||||
*.exe
 | 
					*.exe
 | 
				
			||||||
*.exe.manifest
 | 
					 | 
				
			||||||
*.gcda
 | 
					*.gcda
 | 
				
			||||||
*.gcno
 | 
					*.gcno
 | 
				
			||||||
*.gcov
 | 
					*.gcov
 | 
				
			||||||
@@ -16,18 +13,11 @@
 | 
				
			|||||||
*.loT
 | 
					*.loT
 | 
				
			||||||
*.o
 | 
					*.o
 | 
				
			||||||
*.orig
 | 
					*.orig
 | 
				
			||||||
*.pem
 | 
					 | 
				
			||||||
*.pyc
 | 
					*.pyc
 | 
				
			||||||
*.rej
 | 
					*.rej
 | 
				
			||||||
*.s
 | 
					*.s
 | 
				
			||||||
*.service
 | 
					 | 
				
			||||||
*.socket
 | 
					 | 
				
			||||||
*.swp
 | 
					 | 
				
			||||||
*~
 | 
					*~
 | 
				
			||||||
.#*
 | 
					 | 
				
			||||||
.color_coded
 | 
					 | 
				
			||||||
.deps
 | 
					.deps
 | 
				
			||||||
.dirstamp
 | 
					 | 
				
			||||||
.gdb_history
 | 
					.gdb_history
 | 
				
			||||||
.git
 | 
					.git
 | 
				
			||||||
.git-module-status
 | 
					.git-module-status
 | 
				
			||||||
@@ -35,17 +25,18 @@
 | 
				
			|||||||
.lvimrc
 | 
					.lvimrc
 | 
				
			||||||
.memdump
 | 
					.memdump
 | 
				
			||||||
.sc-start-sc_*
 | 
					.sc-start-sc_*
 | 
				
			||||||
.ycm_extra_conf.py
 | 
					/ABOUT-NLS
 | 
				
			||||||
/AUTHORS
 | 
					/AUTHORS
 | 
				
			||||||
 | 
					/COPYING
 | 
				
			||||||
 | 
					/ChangeLog
 | 
				
			||||||
/GNUmakefile
 | 
					/GNUmakefile
 | 
				
			||||||
/INSTALL
 | 
					/INSTALL
 | 
				
			||||||
/NEWS
 | 
					/NEWS
 | 
				
			||||||
/aclocal.m4
 | 
					/aclocal.m4
 | 
				
			||||||
/autom4te.cache
 | 
					/autom4te.cache
 | 
				
			||||||
/build-aux/*
 | 
					/build-aux
 | 
				
			||||||
 | 
					/build-aux/
 | 
				
			||||||
/build/
 | 
					/build/
 | 
				
			||||||
/ci-tree/
 | 
					 | 
				
			||||||
/confdefs.h
 | 
					 | 
				
			||||||
/config.cache
 | 
					/config.cache
 | 
				
			||||||
/config.guess
 | 
					/config.guess
 | 
				
			||||||
/config.h
 | 
					/config.h
 | 
				
			||||||
@@ -56,41 +47,37 @@
 | 
				
			|||||||
/config.sub
 | 
					/config.sub
 | 
				
			||||||
/configure
 | 
					/configure
 | 
				
			||||||
/configure.lineno
 | 
					/configure.lineno
 | 
				
			||||||
/conftest.*
 | 
					/daemon/*_dispatch.h
 | 
				
			||||||
/docs/aclperms.htmlinc
 | 
					/daemon/libvirt_qemud
 | 
				
			||||||
 | 
					/daemon/libvirtd
 | 
				
			||||||
 | 
					/daemon/libvirtd*.logrotate
 | 
				
			||||||
 | 
					/daemon/libvirtd.8
 | 
				
			||||||
 | 
					/daemon/libvirtd.8.in
 | 
				
			||||||
 | 
					/daemon/libvirtd.init
 | 
				
			||||||
 | 
					/daemon/libvirtd.pod
 | 
				
			||||||
 | 
					/daemon/libvirtd.service
 | 
				
			||||||
 | 
					/daemon/test_libvirtd.aug
 | 
				
			||||||
/docs/apibuild.py.stamp
 | 
					/docs/apibuild.py.stamp
 | 
				
			||||||
/docs/devhelp/libvirt.devhelp
 | 
					/docs/devhelp/libvirt.devhelp
 | 
				
			||||||
/docs/hvsupport.html.in
 | 
					/docs/hvsupport.html.in
 | 
				
			||||||
/docs/libvirt-admin-*.xml
 | 
					 | 
				
			||||||
/docs/libvirt-api.xml
 | 
					/docs/libvirt-api.xml
 | 
				
			||||||
/docs/libvirt-lxc-*.xml
 | 
					 | 
				
			||||||
/docs/libvirt-qemu-*.xml
 | 
					/docs/libvirt-qemu-*.xml
 | 
				
			||||||
/docs/libvirt-refs.xml
 | 
					/docs/libvirt-refs.xml
 | 
				
			||||||
/docs/news.html.in
 | 
					/docs/search.php
 | 
				
			||||||
/docs/todo.html.in
 | 
					/docs/todo.html.in
 | 
				
			||||||
/examples/admin/client_close
 | 
					/examples/domain-events/events-c/event-test
 | 
				
			||||||
/examples/admin/client_info
 | 
					 | 
				
			||||||
/examples/admin/client_limits
 | 
					 | 
				
			||||||
/examples/admin/list_clients
 | 
					 | 
				
			||||||
/examples/admin/list_servers
 | 
					 | 
				
			||||||
/examples/admin/logging
 | 
					 | 
				
			||||||
/examples/admin/threadpool_params
 | 
					 | 
				
			||||||
/examples/object-events/event-test
 | 
					 | 
				
			||||||
/examples/dominfo/info1
 | 
					/examples/dominfo/info1
 | 
				
			||||||
/examples/domsuspend/suspend
 | 
					/examples/domsuspend/suspend
 | 
				
			||||||
/examples/dommigrate/dommigrate
 | 
					 | 
				
			||||||
/examples/domtop/domtop
 | 
					 | 
				
			||||||
/examples/hellolibvirt/hellolibvirt
 | 
					/examples/hellolibvirt/hellolibvirt
 | 
				
			||||||
/examples/openauth/openauth
 | 
					/examples/openauth/openauth
 | 
				
			||||||
/examples/rename/rename
 | 
					 | 
				
			||||||
/gnulib/lib/*
 | 
					/gnulib/lib/*
 | 
				
			||||||
/gnulib/m4/*
 | 
					/gnulib/m4/*
 | 
				
			||||||
/gnulib/tests/*
 | 
					/gnulib/tests/*
 | 
				
			||||||
/include/libvirt/libvirt-common.h
 | 
					/include/libvirt/libvirt.h
 | 
				
			||||||
/libtool
 | 
					/libtool
 | 
				
			||||||
/libvirt-*.tar.xz
 | 
					/libvirt-*.tar.gz
 | 
				
			||||||
/libvirt-[0-9]*
 | 
					/libvirt-[0-9]*
 | 
				
			||||||
/libvirt*.pc
 | 
					/libvirt.pc
 | 
				
			||||||
/libvirt.spec
 | 
					/libvirt.spec
 | 
				
			||||||
/ltconfig
 | 
					/ltconfig
 | 
				
			||||||
/ltmain.sh
 | 
					/ltmain.sh
 | 
				
			||||||
@@ -98,115 +85,116 @@
 | 
				
			|||||||
/maint.mk
 | 
					/maint.mk
 | 
				
			||||||
/mingw-libvirt.spec
 | 
					/mingw-libvirt.spec
 | 
				
			||||||
/mkinstalldirs
 | 
					/mkinstalldirs
 | 
				
			||||||
/po/*gmo
 | 
					/po/*
 | 
				
			||||||
/po/*po
 | 
					 | 
				
			||||||
!/po/*.mini.po
 | 
					 | 
				
			||||||
/po/*pot
 | 
					 | 
				
			||||||
/proxy/
 | 
					/proxy/
 | 
				
			||||||
/python/
 | 
					/python/generated.stamp
 | 
				
			||||||
 | 
					/python/generator.py.stamp
 | 
				
			||||||
 | 
					/python/libvirt-export.c
 | 
				
			||||||
 | 
					/python/libvirt-qemu-export.c
 | 
				
			||||||
 | 
					/python/libvirt-qemu.[ch]
 | 
				
			||||||
 | 
					/python/libvirt.[ch]
 | 
				
			||||||
 | 
					/python/libvirt.py
 | 
				
			||||||
 | 
					/python/libvirt_qemu.py
 | 
				
			||||||
/run
 | 
					/run
 | 
				
			||||||
/sc_*
 | 
					/sc_*
 | 
				
			||||||
/src/.*.stamp
 | 
					/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/admin/admin_server_dispatch_stubs.h
 | 
					 | 
				
			||||||
/src/esx/*.generated.*
 | 
					/src/esx/*.generated.*
 | 
				
			||||||
/src/hyperv/*.generated.*
 | 
					/src/hyperv/*.generated.*
 | 
				
			||||||
/src/libvirt*.def
 | 
					/src/libvirt*.def
 | 
				
			||||||
/src/libvirt.syms
 | 
					/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_*.stp
 | 
				
			||||||
/src/libvirt_*helper
 | 
					/src/libvirt_*helper
 | 
				
			||||||
/src/libvirt_*probes.h
 | 
					/src/libvirt_*probes.h
 | 
				
			||||||
/src/libvirt_lxc
 | 
					/src/libvirt_lxc
 | 
				
			||||||
/src/libvirtd
 | 
					 | 
				
			||||||
/src/libvirtd*.logrotate
 | 
					 | 
				
			||||||
/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/qemu-sanlock.conf
 | 
				
			||||||
/src/locking/test_libvirt_sanlock.aug
 | 
					/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_controller_dispatch.h
 | 
				
			||||||
/src/lxc/lxc_monitor_dispatch.h
 | 
					/src/lxc/lxc_monitor_dispatch.h
 | 
				
			||||||
/src/lxc/lxc_monitor_protocol.c
 | 
					/src/lxc/lxc_protocol.c
 | 
				
			||||||
/src/lxc/lxc_monitor_protocol.h
 | 
					/src/lxc/lxc_protocol.h
 | 
				
			||||||
/src/lxc/lxc_protocol.[ch]
 | 
					 | 
				
			||||||
/src/lxc/test_libvirtd_lxc.aug
 | 
					/src/lxc/test_libvirtd_lxc.aug
 | 
				
			||||||
/src/qemu/test_libvirtd_qemu.aug
 | 
					/src/qemu/test_libvirtd_qemu.aug
 | 
				
			||||||
/src/remote/*_client_bodies.h
 | 
					/src/remote/*_client_bodies.h
 | 
				
			||||||
/src/remote/*_protocol.[ch]
 | 
					/src/remote/*_protocol.[ch]
 | 
				
			||||||
/src/remote/*_stubs.h
 | 
					 | 
				
			||||||
/src/rpc/virkeepaliveprotocol.[ch]
 | 
					/src/rpc/virkeepaliveprotocol.[ch]
 | 
				
			||||||
/src/rpc/virnetprotocol.[ch]
 | 
					/src/rpc/virnetprotocol.[ch]
 | 
				
			||||||
/src/test_libvirt*.aug
 | 
					/src/test_libvirt*.aug
 | 
				
			||||||
/src/test_virtlockd.aug
 | 
					/src/util/virkeymaps.h
 | 
				
			||||||
/src/test_virtlogd.aug
 | 
					 | 
				
			||||||
/src/util/virkeycodetable*.h
 | 
					 | 
				
			||||||
/src/util/virkeynametable*.h
 | 
					 | 
				
			||||||
/src/virt-aa-helper
 | 
					/src/virt-aa-helper
 | 
				
			||||||
/src/virtlockd
 | 
					 | 
				
			||||||
/src/virtlogd
 | 
					 | 
				
			||||||
/src/virt-guest-shutdown.target
 | 
					 | 
				
			||||||
/tests/*.log
 | 
					/tests/*.log
 | 
				
			||||||
/tests/*.pid
 | 
					/tests/*.pid
 | 
				
			||||||
/tests/*.trs
 | 
					/tests/*xml2*test
 | 
				
			||||||
/tests/*test
 | 
					 | 
				
			||||||
/tests/commandhelper
 | 
					/tests/commandhelper
 | 
				
			||||||
/tests/qemucapsprobe
 | 
					/tests/commandtest
 | 
				
			||||||
!/tests/virsh-self-test
 | 
					/tests/conftest
 | 
				
			||||||
!/tests/virt-aa-helper-test
 | 
					/tests/cputest
 | 
				
			||||||
!/tests/virt-admin-self-test
 | 
					/tests/domainsnapshotxml2xmltest
 | 
				
			||||||
/tests/objectlocking
 | 
					/tests/esxutilstest
 | 
				
			||||||
/tests/objectlocking-files.txt
 | 
					/tests/eventtest
 | 
				
			||||||
/tests/objectlocking.cm[ix]
 | 
					/tests/hashtest
 | 
				
			||||||
 | 
					/tests/jsontest
 | 
				
			||||||
 | 
					/tests/libvirtdconftest
 | 
				
			||||||
 | 
					/tests/networkxml2argvtest
 | 
				
			||||||
 | 
					/tests/nodeinfotest
 | 
				
			||||||
 | 
					/tests/nwfilterxml2xmltest
 | 
				
			||||||
 | 
					/tests/object-locking
 | 
				
			||||||
 | 
					/tests/object-locking-files.txt
 | 
				
			||||||
 | 
					/tests/object-locking.cm[ix]
 | 
				
			||||||
 | 
					/tests/openvzutilstest
 | 
				
			||||||
 | 
					/tests/qemuargv2xmltest
 | 
				
			||||||
 | 
					/tests/qemuhelptest
 | 
				
			||||||
 | 
					/tests/qemumonitorjsontest
 | 
				
			||||||
 | 
					/tests/qemumonitortest
 | 
				
			||||||
 | 
					/tests/qemuxmlnstest
 | 
				
			||||||
 | 
					/tests/qparamtest
 | 
				
			||||||
/tests/reconnect
 | 
					/tests/reconnect
 | 
				
			||||||
 | 
					/tests/secaatest
 | 
				
			||||||
 | 
					/tests/seclabeltest
 | 
				
			||||||
 | 
					/tests/securityselinuxtest
 | 
				
			||||||
 | 
					/tests/sexpr2xmltest
 | 
				
			||||||
 | 
					/tests/shunloadtest
 | 
				
			||||||
 | 
					/tests/sockettest
 | 
				
			||||||
/tests/ssh
 | 
					/tests/ssh
 | 
				
			||||||
/tests/test_file_access.txt
 | 
					/tests/statstest
 | 
				
			||||||
/tests/test_conf
 | 
					/tests/storagebackendsheepdogtest
 | 
				
			||||||
 | 
					/tests/utiltest
 | 
				
			||||||
 | 
					/tests/viratomictest
 | 
				
			||||||
 | 
					/tests/virauthconfigtest
 | 
				
			||||||
 | 
					/tests/virbitmaptest
 | 
				
			||||||
 | 
					/tests/virbuftest
 | 
				
			||||||
 | 
					/tests/virdrivermoduletest
 | 
				
			||||||
 | 
					/tests/virhashtest
 | 
				
			||||||
 | 
					/tests/virkeyfiletest
 | 
				
			||||||
 | 
					/tests/virnet*test
 | 
				
			||||||
 | 
					/tests/virshtest
 | 
				
			||||||
 | 
					/tests/virstringtest
 | 
				
			||||||
 | 
					/tests/virtimetest
 | 
				
			||||||
 | 
					/tests/viruritest
 | 
				
			||||||
 | 
					/tests/vmx2xmltest
 | 
				
			||||||
 | 
					/tests/xencapstest
 | 
				
			||||||
 | 
					/tests/xmconfigtest
 | 
				
			||||||
 | 
					/tools/*.[18]
 | 
				
			||||||
 | 
					/tools/libvirt-guests.init
 | 
				
			||||||
 | 
					/tools/libvirt-guests.service
 | 
				
			||||||
/tools/libvirt-guests.sh
 | 
					/tools/libvirt-guests.sh
 | 
				
			||||||
/tools/virt-login-shell
 | 
					 | 
				
			||||||
/tools/virsh
 | 
					/tools/virsh
 | 
				
			||||||
/tools/virsh-*-edit.c
 | 
					/tools/virsh-*-edit.c
 | 
				
			||||||
/tools/virt-admin
 | 
					 | 
				
			||||||
/tools/virt-*-validate
 | 
					/tools/virt-*-validate
 | 
				
			||||||
/tools/virt-sanlock-cleanup
 | 
					/tools/virt-sanlock-cleanup
 | 
				
			||||||
/tools/wireshark/src/libvirt
 | 
					 | 
				
			||||||
/update.log
 | 
					/update.log
 | 
				
			||||||
GPATH
 | 
					 | 
				
			||||||
GRTAGS
 | 
					 | 
				
			||||||
GTAGS
 | 
					 | 
				
			||||||
Makefile
 | 
					Makefile
 | 
				
			||||||
Makefile.in
 | 
					Makefile.in
 | 
				
			||||||
TAGS
 | 
					TAGS
 | 
				
			||||||
coverage
 | 
					coverage
 | 
				
			||||||
cscope.files
 | 
					cscope.files
 | 
				
			||||||
cscope.in.out
 | 
					 | 
				
			||||||
cscope.out
 | 
					cscope.out
 | 
				
			||||||
cscope.po.out
 | 
					 | 
				
			||||||
results.log
 | 
					results.log
 | 
				
			||||||
stamp-h
 | 
					stamp-h
 | 
				
			||||||
stamp-h.in
 | 
					stamp-h.in
 | 
				
			||||||
stamp-h1
 | 
					stamp-h1
 | 
				
			||||||
tags
 | 
					 | 
				
			||||||
!/build-aux/*.pl
 | 
					 | 
				
			||||||
!/gnulib/lib/Makefile.am
 | 
					!/gnulib/lib/Makefile.am
 | 
				
			||||||
!/gnulib/tests/Makefile.am
 | 
					!/gnulib/tests/Makefile.am
 | 
				
			||||||
!/m4/virt-*.m4
 | 
					!/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 both versions, but it is a little
 | 
					 | 
				
			||||||
# overkill. Instead we run half the jobs on 9 and half the jobs
 | 
					 | 
				
			||||||
# on sid to give reasonable cross-coverage.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-9-cross-armv6l:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-9-cross-armv6l:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-9-cross-mipsel:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-9-cross-mipsel:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-9-cross-ppc64le:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-9-cross-ppc64le:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-9-cross-s390x:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-9-cross-s390x:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-sid-cross-aarch64:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-sid-cross-aarch64:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-sid-cross-armv7l:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-sid-cross-armv7l:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-sid-cross-i686:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-sid-cross-i686:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-sid-cross-mips64el:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-sid-cross-mips64el:master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
debian-sid-cross-mips:
 | 
					 | 
				
			||||||
  <<: *job_definition
 | 
					 | 
				
			||||||
  image: quay.io/libvirt/buildenv-debian-sid-cross-mips:master
 | 
					 | 
				
			||||||
							
								
								
									
										5
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,3 @@
 | 
				
			|||||||
[submodule "gnulib"]
 | 
					[submodule "gnulib"]
 | 
				
			||||||
	path = .gnulib
 | 
						path = .gnulib
 | 
				
			||||||
	url = https://git.savannah.gnu.org/git/gnulib.git/
 | 
						url = git://git.sv.gnu.org/gnulib.git
 | 
				
			||||||
[submodule "keycodemapdb"]
 | 
					 | 
				
			||||||
	path = src/keycodemapdb
 | 
					 | 
				
			||||||
	url = https://gitlab.com/keycodemap/keycodemapdb.git
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
[gitpublishprofile "default"]
 | 
					 | 
				
			||||||
base = master
 | 
					 | 
				
			||||||
to = libvir-list@redhat.com
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								.gnulib
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								.gnulib
									
									
									
									
									
								
							 Submodule .gnulib updated: 8089c00979...b4938324b7
									
								
							
							
								
								
									
										23
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								.mailmap
									
									
									
									
									
								
							@@ -5,10 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<bozzolan@gmail.com> <redshift@gmx.com>
 | 
					<bozzolan@gmail.com> <redshift@gmx.com>
 | 
				
			||||||
<charles_duffy@messageone.com> <charles@dyfis.net>
 | 
					<charles_duffy@messageone.com> <charles@dyfis.net>
 | 
				
			||||||
<claudio.bley@gmail.com> <cbley@av-test.de>
 | 
					 | 
				
			||||||
<dfj@redhat.com> <dfj@dfj.bne.redhat.com>
 | 
					<dfj@redhat.com> <dfj@dfj.bne.redhat.com>
 | 
				
			||||||
<dpkshetty@gmail.com> <deepakcs@linux.vnet.ibm.com>
 | 
					 | 
				
			||||||
<dpkshetty@gmail.com> <deepakcs@redhat.com>
 | 
					 | 
				
			||||||
<eblake@redhat.com> <ebb9@byu.net>
 | 
					<eblake@redhat.com> <ebb9@byu.net>
 | 
				
			||||||
<gdolley@arpnetworks.com> <gdolley@ucla.edu>
 | 
					<gdolley@arpnetworks.com> <gdolley@ucla.edu>
 | 
				
			||||||
<gerhard.stenzel@de.ibm.com> <gstenzel@linux.vnet.ibm.com>
 | 
					<gerhard.stenzel@de.ibm.com> <gstenzel@linux.vnet.ibm.com>
 | 
				
			||||||
@@ -20,6 +17,7 @@
 | 
				
			|||||||
<jfehlig@suse.com> <jfehlig@novell.com>
 | 
					<jfehlig@suse.com> <jfehlig@novell.com>
 | 
				
			||||||
<jfehlig@suse.com> <jfehlig@linux-ypgk.site>
 | 
					<jfehlig@suse.com> <jfehlig@linux-ypgk.site>
 | 
				
			||||||
<jclift@redhat.com> <justin@salasaga.org>
 | 
					<jclift@redhat.com> <justin@salasaga.org>
 | 
				
			||||||
 | 
					<berrange@redhat.com> <dan@berrange.com>
 | 
				
			||||||
<soren@linux2go.dk> <soren@canonical.com>
 | 
					<soren@linux2go.dk> <soren@canonical.com>
 | 
				
			||||||
<cfergeau@redhat.com> <teuf@gnome.org>
 | 
					<cfergeau@redhat.com> <teuf@gnome.org>
 | 
				
			||||||
<wency@cn.fujitsu.com> <wency cn fujitsu com>
 | 
					<wency@cn.fujitsu.com> <wency cn fujitsu com>
 | 
				
			||||||
@@ -38,11 +36,6 @@
 | 
				
			|||||||
<zhlcindy@linux.vnet.ibm.com> <zhlcindy@gmail.com>
 | 
					<zhlcindy@linux.vnet.ibm.com> <zhlcindy@gmail.com>
 | 
				
			||||||
<serge.hallyn@canonical.com> <serue@us.ibm.com>
 | 
					<serge.hallyn@canonical.com> <serue@us.ibm.com>
 | 
				
			||||||
<pritesh.kothari@sun.com> <Pritesh.Kothari@Sun.COM>
 | 
					<pritesh.kothari@sun.com> <Pritesh.Kothari@Sun.COM>
 | 
				
			||||||
<cbosdonnat@suse.com> <cedric.bosdonnat@free.fr>
 | 
					 | 
				
			||||||
<mnestratov@virtuozzo.com> <mnestratov@parallels.com>
 | 
					 | 
				
			||||||
<nshirokovskiy@virtuozzo.com> <nshirokovskiy@parallels.com>
 | 
					 | 
				
			||||||
<jyang@redhat.com> <osier@yunify.com>
 | 
					 | 
				
			||||||
<kkoukiou@redhat.com> <k.koukiou@googlemail.com>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Name consolidation:
 | 
					# Name consolidation:
 | 
				
			||||||
# Preferred author spelling <preferred email>
 | 
					# Preferred author spelling <preferred email>
 | 
				
			||||||
@@ -60,16 +53,6 @@ Aurelien Rougemont <beorn@binaries.fr>
 | 
				
			|||||||
Serge E. Hallyn <serge.hallyn@canonical.com>
 | 
					Serge E. Hallyn <serge.hallyn@canonical.com>
 | 
				
			||||||
Henrik Persson E <henrik.e.persson@ericsson.com>
 | 
					Henrik Persson E <henrik.e.persson@ericsson.com>
 | 
				
			||||||
Philipp Hahn <hahn@univention.de>
 | 
					Philipp Hahn <hahn@univention.de>
 | 
				
			||||||
 | 
					Marco Bozzolan <bozzolan@gmail.com>
 | 
				
			||||||
 | 
					Marco Bozzolan <redshift@gmx.com>
 | 
				
			||||||
Pritesh Kothari <pritesh.kothari@sun.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>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										74
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,74 +0,0 @@
 | 
				
			|||||||
sudo: required
 | 
					 | 
				
			||||||
language: generic
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
branches:
 | 
					 | 
				
			||||||
  except:
 | 
					 | 
				
			||||||
    - /^.*-maint$/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
addons:
 | 
					 | 
				
			||||||
  homebrew:
 | 
					 | 
				
			||||||
    update: true
 | 
					 | 
				
			||||||
    packages:
 | 
					 | 
				
			||||||
      - ccache
 | 
					 | 
				
			||||||
      - rpcgen
 | 
					 | 
				
			||||||
      - xz
 | 
					 | 
				
			||||||
      - yajl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
matrix:
 | 
					 | 
				
			||||||
  include:
 | 
					 | 
				
			||||||
    - services:
 | 
					 | 
				
			||||||
        - docker
 | 
					 | 
				
			||||||
      env:
 | 
					 | 
				
			||||||
        - IMAGE="ubuntu-18"
 | 
					 | 
				
			||||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
					 | 
				
			||||||
      script:
 | 
					 | 
				
			||||||
        - make -f Makefile.ci ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
					 | 
				
			||||||
    - services:
 | 
					 | 
				
			||||||
        - docker
 | 
					 | 
				
			||||||
      env:
 | 
					 | 
				
			||||||
        - IMAGE="centos-7"
 | 
					 | 
				
			||||||
        - MAKE_ARGS="syntax-check distcheck"
 | 
					 | 
				
			||||||
      script:
 | 
					 | 
				
			||||||
        - make -f Makefile.ci ci-build@$IMAGE CI_MAKE_ARGS="$MAKE_ARGS"
 | 
					 | 
				
			||||||
    - services:
 | 
					 | 
				
			||||||
        - docker
 | 
					 | 
				
			||||||
      env:
 | 
					 | 
				
			||||||
        - IMAGE="fedora-rawhide"
 | 
					 | 
				
			||||||
        - MINGW="mingw32"
 | 
					 | 
				
			||||||
      script:
 | 
					 | 
				
			||||||
        - make -f Makefile.ci ci-build@$IMAGE CI_CONFIGURE="$MINGW-configure"
 | 
					 | 
				
			||||||
    - services:
 | 
					 | 
				
			||||||
        - docker
 | 
					 | 
				
			||||||
      env:
 | 
					 | 
				
			||||||
        - IMAGE="fedora-rawhide"
 | 
					 | 
				
			||||||
        - MINGW="mingw64"
 | 
					 | 
				
			||||||
      script:
 | 
					 | 
				
			||||||
        - make -f Makefile.ci ci-build@$IMAGE CI_CONFIGURE="$MINGW-configure"
 | 
					 | 
				
			||||||
    - compiler: clang
 | 
					 | 
				
			||||||
      language: c
 | 
					 | 
				
			||||||
      os: osx
 | 
					 | 
				
			||||||
      env:
 | 
					 | 
				
			||||||
        - PATH="/usr/local/opt/gettext/bin:/usr/local/opt/ccache/libexec:/usr/local/opt/rpcgen/bin:$PATH"
 | 
					 | 
				
			||||||
      script:
 | 
					 | 
				
			||||||
        # We can't run 'distcheck' or 'syntax-check' because they fail on
 | 
					 | 
				
			||||||
        # macOS, but doing 'install' and 'dist' gives us some useful coverage
 | 
					 | 
				
			||||||
        - ./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 }
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								AUTHORS.in
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								AUTHORS.in
									
									
									
									
									
								
							@@ -8,53 +8,38 @@ Daniel Veillard <veillard@redhat.com> or <daniel@veillard.com>
 | 
				
			|||||||
The primary maintainers and people with commit access rights:
 | 
					The primary maintainers and people with commit access rights:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Alex Jia <ajia@redhat.com>
 | 
					Alex Jia <ajia@redhat.com>
 | 
				
			||||||
Andrea Bolognani <abologna@redhat.com>
 | 
					Anthony Liguori <aliguori@us.ibm.com>
 | 
				
			||||||
Cédric Bosdonnat <cbosdonnat@suse.com>
 | 
					Chris Lalancette <clalance@redhat.com>
 | 
				
			||||||
Christian Ehrhardt <christian.ehrhardt@canonical.com>
 | 
					 | 
				
			||||||
Christophe Fergeau <cfergeau@redhat.com>
 | 
					Christophe Fergeau <cfergeau@redhat.com>
 | 
				
			||||||
Claudio Bley <claudio.bley@gmail.com>
 | 
					 | 
				
			||||||
Cole Robinson <crobinso@redhat.com>
 | 
					Cole Robinson <crobinso@redhat.com>
 | 
				
			||||||
Daniel P. Berrangé <berrange@redhat.com>
 | 
					Daniel Berrange <berrange@redhat.com>
 | 
				
			||||||
Daniel Veillard <veillard@redhat.com>
 | 
					Daniel Veillard <veillard@redhat.com>
 | 
				
			||||||
 | 
					Dave Allan <dallan@redhat.com>
 | 
				
			||||||
Doug Goldstein <cardoe@gentoo.org>
 | 
					Doug Goldstein <cardoe@gentoo.org>
 | 
				
			||||||
Eric Blake <eblake@redhat.com>
 | 
					Eric Blake <eblake@redhat.com>
 | 
				
			||||||
Erik Skultety <eskultet@redhat.com>
 | 
					 | 
				
			||||||
Gao Feng <gaofeng@cn.fujitsu.com>
 | 
					 | 
				
			||||||
Guido Günther <agx@sigxcpu.org>
 | 
					Guido Günther <agx@sigxcpu.org>
 | 
				
			||||||
Ján Tomko <jtomko@redhat.com>
 | 
					 | 
				
			||||||
Jim Fehlig <jfehlig@suse.com>
 | 
					Jim Fehlig <jfehlig@suse.com>
 | 
				
			||||||
 | 
					Jim Meyering <meyering@redhat.com>
 | 
				
			||||||
Jiří Denemark <jdenemar@redhat.com>
 | 
					Jiří Denemark <jdenemar@redhat.com>
 | 
				
			||||||
John Ferlan <jferlan@redhat.com>
 | 
					John Levon <john.levon@sun.com>
 | 
				
			||||||
Katerina Koukiou <kkoukiou@redhat.com>
 | 
					Justin Clift <jclift@redhat.com>
 | 
				
			||||||
Laine Stump <laine@redhat.com>
 | 
					Laine Stump <laine@redhat.com>
 | 
				
			||||||
Mark McLoughlin <markmc@redhat.com>
 | 
					Mark McLoughlin <markmc@redhat.com>
 | 
				
			||||||
Martin Kletzander <mkletzan@redhat.com>
 | 
					Martin Kletzander <mkletzan@redhat.com>
 | 
				
			||||||
Matthias Bolte <matthias.bolte@googlemail.com>
 | 
					Matthias Bolte <matthias.bolte@googlemail.com>
 | 
				
			||||||
Maxim Nestratov <mnestratov@virtuozzo.com>
 | 
					 | 
				
			||||||
Michal Prívozník <mprivozn@redhat.com>
 | 
					Michal Prívozník <mprivozn@redhat.com>
 | 
				
			||||||
Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
 | 
					Osier Yang <jyang@redhat.com>
 | 
				
			||||||
Pavel Hrdina <phrdina@redhat.com>
 | 
					 | 
				
			||||||
Peter Krempa <pkrempa@redhat.com>
 | 
					Peter Krempa <pkrempa@redhat.com>
 | 
				
			||||||
Richard W.M. Jones <rjones@redhat.com>
 | 
					Richard W.M. Jones <rjones@redhat.com>
 | 
				
			||||||
Roman Bogorodskiy <bogorodskiy@gmail.com>
 | 
					 | 
				
			||||||
Stefan Berger <stefanb@us.ibm.com>
 | 
					Stefan Berger <stefanb@us.ibm.com>
 | 
				
			||||||
Wen Congyang <wency@cn.fujitsu.com>
 | 
					Wen Congyang <wency@cn.fujitsu.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Previous maintainers:
 | 
					Previous maintainers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Anthony Liguori <aliguori@us.ibm.com>
 | 
					 | 
				
			||||||
Atsushi SAKAI <sakaia@jp.fujitsu.com>
 | 
					Atsushi SAKAI <sakaia@jp.fujitsu.com>
 | 
				
			||||||
Chris Lalancette <clalance@redhat.com>
 | 
					 | 
				
			||||||
Dan Smith <danms@us.ibm.com>
 | 
					Dan Smith <danms@us.ibm.com>
 | 
				
			||||||
Dave Allan <dallan@redhat.com>
 | 
					 | 
				
			||||||
Dave Leskovec <dlesko@linux.vnet.ibm.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>
 | 
					 | 
				
			||||||
Justin Clift <jclift@redhat.com>
 | 
					 | 
				
			||||||
Karel Zak <kzak@redhat.com>
 | 
					Karel Zak <kzak@redhat.com>
 | 
				
			||||||
Osier Yang <jyang@redhat.com>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Patches have also been contributed by:
 | 
					Patches have also been contributed by:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,6 +48,7 @@ Amit Shah <amit.shah@redhat.com>
 | 
				
			|||||||
Andrew Puch <apuch@redhat.com>
 | 
					Andrew Puch <apuch@redhat.com>
 | 
				
			||||||
Anton Protopopov <aspsk2@gmail.com>
 | 
					Anton Protopopov <aspsk2@gmail.com>
 | 
				
			||||||
Ben Guthro <ben.guthro@gmail.com>
 | 
					Ben Guthro <ben.guthro@gmail.com>
 | 
				
			||||||
 | 
					Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
 | 
				
			||||||
Daniel Hokka Zakrisson <daniel@hozac.com>
 | 
					Daniel Hokka Zakrisson <daniel@hozac.com>
 | 
				
			||||||
Dan Wendlandt <dan@nicira.com>
 | 
					Dan Wendlandt <dan@nicira.com>
 | 
				
			||||||
David Lively <dlively@virtualiron.com>
 | 
					David Lively <dlively@virtualiron.com>
 | 
				
			||||||
@@ -91,7 +77,9 @@ Stefan de Konink <dekonink@kinkrsoftware.nl>
 | 
				
			|||||||
Takahashi Tomohiro <takatom@jp.fujitsu.com>
 | 
					Takahashi Tomohiro <takatom@jp.fujitsu.com>
 | 
				
			||||||
Tatsuro Enokura <fj7716hz@aa.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
 | 
					The libvirt logo was designed by Diana Fong
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										339
									
								
								COPYING
									
									
									
									
									
								
							
							
						
						
									
										339
									
								
								COPYING
									
									
									
									
									
								
							@@ -1,339 +0,0 @@
 | 
				
			|||||||
                    GNU GENERAL PUBLIC LICENSE
 | 
					 | 
				
			||||||
                       Version 2, June 1991
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
					 | 
				
			||||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
					 | 
				
			||||||
 of this license document, but changing it is not allowed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            Preamble
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  The licenses for most software are designed to take away your
 | 
					 | 
				
			||||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
					 | 
				
			||||||
License is intended to guarantee your freedom to share and change free
 | 
					 | 
				
			||||||
software--to make sure the software is free for all its users.  This
 | 
					 | 
				
			||||||
General Public License applies to most of the Free Software
 | 
					 | 
				
			||||||
Foundation's software and to any other program whose authors commit to
 | 
					 | 
				
			||||||
using it.  (Some other Free Software Foundation software is covered by
 | 
					 | 
				
			||||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
					 | 
				
			||||||
your programs, too.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  When we speak of free software, we are referring to freedom, not
 | 
					 | 
				
			||||||
price.  Our General Public Licenses are designed to make sure that you
 | 
					 | 
				
			||||||
have the freedom to distribute copies of free software (and charge for
 | 
					 | 
				
			||||||
this service if you wish), that you receive source code or can get it
 | 
					 | 
				
			||||||
if you want it, that you can change the software or use pieces of it
 | 
					 | 
				
			||||||
in new free programs; and that you know you can do these things.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  To protect your rights, we need to make restrictions that forbid
 | 
					 | 
				
			||||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
					 | 
				
			||||||
These restrictions translate to certain responsibilities for you if you
 | 
					 | 
				
			||||||
distribute copies of the software, or if you modify it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  For example, if you distribute copies of such a program, whether
 | 
					 | 
				
			||||||
gratis or for a fee, you must give the recipients all the rights that
 | 
					 | 
				
			||||||
you have.  You must make sure that they, too, receive or can get the
 | 
					 | 
				
			||||||
source code.  And you must show them these terms so they know their
 | 
					 | 
				
			||||||
rights.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
					 | 
				
			||||||
(2) offer you this license which gives you legal permission to copy,
 | 
					 | 
				
			||||||
distribute and/or modify the software.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Also, for each author's protection and ours, we want to make certain
 | 
					 | 
				
			||||||
that everyone understands that there is no warranty for this free
 | 
					 | 
				
			||||||
software.  If the software is modified by someone else and passed on, we
 | 
					 | 
				
			||||||
want its recipients to know that what they have is not the original, so
 | 
					 | 
				
			||||||
that any problems introduced by others will not reflect on the original
 | 
					 | 
				
			||||||
authors' reputations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Finally, any free program is threatened constantly by software
 | 
					 | 
				
			||||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
					 | 
				
			||||||
program will individually obtain patent licenses, in effect making the
 | 
					 | 
				
			||||||
program proprietary.  To prevent this, we have made it clear that any
 | 
					 | 
				
			||||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  The precise terms and conditions for copying, distribution and
 | 
					 | 
				
			||||||
modification follow.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    GNU GENERAL PUBLIC LICENSE
 | 
					 | 
				
			||||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  0. This License applies to any program or other work which contains
 | 
					 | 
				
			||||||
a notice placed by the copyright holder saying it may be distributed
 | 
					 | 
				
			||||||
under the terms of this General Public License.  The "Program", below,
 | 
					 | 
				
			||||||
refers to any such program or work, and a "work based on the Program"
 | 
					 | 
				
			||||||
means either the Program or any derivative work under copyright law:
 | 
					 | 
				
			||||||
that is to say, a work containing the Program or a portion of it,
 | 
					 | 
				
			||||||
either verbatim or with modifications and/or translated into another
 | 
					 | 
				
			||||||
language.  (Hereinafter, translation is included without limitation in
 | 
					 | 
				
			||||||
the term "modification".)  Each licensee is addressed as "you".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Activities other than copying, distribution and modification are not
 | 
					 | 
				
			||||||
covered by this License; they are outside its scope.  The act of
 | 
					 | 
				
			||||||
running the Program is not restricted, and the output from the Program
 | 
					 | 
				
			||||||
is covered only if its contents constitute a work based on the
 | 
					 | 
				
			||||||
Program (independent of having been made by running the Program).
 | 
					 | 
				
			||||||
Whether that is true depends on what the Program does.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
					 | 
				
			||||||
source code as you receive it, in any medium, provided that you
 | 
					 | 
				
			||||||
conspicuously and appropriately publish on each copy an appropriate
 | 
					 | 
				
			||||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
					 | 
				
			||||||
notices that refer to this License and to the absence of any warranty;
 | 
					 | 
				
			||||||
and give any other recipients of the Program a copy of this License
 | 
					 | 
				
			||||||
along with the Program.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You may charge a fee for the physical act of transferring a copy, and
 | 
					 | 
				
			||||||
you may at your option offer warranty protection in exchange for a fee.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  2. You may modify your copy or copies of the Program or any portion
 | 
					 | 
				
			||||||
of it, thus forming a work based on the Program, and copy and
 | 
					 | 
				
			||||||
distribute such modifications or work under the terms of Section 1
 | 
					 | 
				
			||||||
above, provided that you also meet all of these conditions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a) You must cause the modified files to carry prominent notices
 | 
					 | 
				
			||||||
    stating that you changed the files and the date of any change.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    b) You must cause any work that you distribute or publish, that in
 | 
					 | 
				
			||||||
    whole or in part contains or is derived from the Program or any
 | 
					 | 
				
			||||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
					 | 
				
			||||||
    parties under the terms of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c) If the modified program normally reads commands interactively
 | 
					 | 
				
			||||||
    when run, you must cause it, when started running for such
 | 
					 | 
				
			||||||
    interactive use in the most ordinary way, to print or display an
 | 
					 | 
				
			||||||
    announcement including an appropriate copyright notice and a
 | 
					 | 
				
			||||||
    notice that there is no warranty (or else, saying that you provide
 | 
					 | 
				
			||||||
    a warranty) and that users may redistribute the program under
 | 
					 | 
				
			||||||
    these conditions, and telling the user how to view a copy of this
 | 
					 | 
				
			||||||
    License.  (Exception: if the Program itself is interactive but
 | 
					 | 
				
			||||||
    does not normally print such an announcement, your work based on
 | 
					 | 
				
			||||||
    the Program is not required to print an announcement.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These requirements apply to the modified work as a whole.  If
 | 
					 | 
				
			||||||
identifiable sections of that work are not derived from the Program,
 | 
					 | 
				
			||||||
and can be reasonably considered independent and separate works in
 | 
					 | 
				
			||||||
themselves, then this License, and its terms, do not apply to those
 | 
					 | 
				
			||||||
sections when you distribute them as separate works.  But when you
 | 
					 | 
				
			||||||
distribute the same sections as part of a whole which is a work based
 | 
					 | 
				
			||||||
on the Program, the distribution of the whole must be on the terms of
 | 
					 | 
				
			||||||
this License, whose permissions for other licensees extend to the
 | 
					 | 
				
			||||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Thus, it is not the intent of this section to claim rights or contest
 | 
					 | 
				
			||||||
your rights to work written entirely by you; rather, the intent is to
 | 
					 | 
				
			||||||
exercise the right to control the distribution of derivative or
 | 
					 | 
				
			||||||
collective works based on the Program.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In addition, mere aggregation of another work not based on the Program
 | 
					 | 
				
			||||||
with the Program (or with a work based on the Program) on a volume of
 | 
					 | 
				
			||||||
a storage or distribution medium does not bring the other work under
 | 
					 | 
				
			||||||
the scope of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
					 | 
				
			||||||
under Section 2) in object code or executable form under the terms of
 | 
					 | 
				
			||||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a) Accompany it with the complete corresponding machine-readable
 | 
					 | 
				
			||||||
    source code, which must be distributed under the terms of Sections
 | 
					 | 
				
			||||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    b) Accompany it with a written offer, valid for at least three
 | 
					 | 
				
			||||||
    years, to give any third party, for a charge no more than your
 | 
					 | 
				
			||||||
    cost of physically performing source distribution, a complete
 | 
					 | 
				
			||||||
    machine-readable copy of the corresponding source code, to be
 | 
					 | 
				
			||||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
					 | 
				
			||||||
    customarily used for software interchange; or,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c) Accompany it with the information you received as to the offer
 | 
					 | 
				
			||||||
    to distribute corresponding source code.  (This alternative is
 | 
					 | 
				
			||||||
    allowed only for noncommercial distribution and only if you
 | 
					 | 
				
			||||||
    received the program in object code or executable form with such
 | 
					 | 
				
			||||||
    an offer, in accord with Subsection b above.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The source code for a work means the preferred form of the work for
 | 
					 | 
				
			||||||
making modifications to it.  For an executable work, complete source
 | 
					 | 
				
			||||||
code means all the source code for all modules it contains, plus any
 | 
					 | 
				
			||||||
associated interface definition files, plus the scripts used to
 | 
					 | 
				
			||||||
control compilation and installation of the executable.  However, as a
 | 
					 | 
				
			||||||
special exception, the source code distributed need not include
 | 
					 | 
				
			||||||
anything that is normally distributed (in either source or binary
 | 
					 | 
				
			||||||
form) with the major components (compiler, kernel, and so on) of the
 | 
					 | 
				
			||||||
operating system on which the executable runs, unless that component
 | 
					 | 
				
			||||||
itself accompanies the executable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If distribution of executable or object code is made by offering
 | 
					 | 
				
			||||||
access to copy from a designated place, then offering equivalent
 | 
					 | 
				
			||||||
access to copy the source code from the same place counts as
 | 
					 | 
				
			||||||
distribution of the source code, even though third parties are not
 | 
					 | 
				
			||||||
compelled to copy the source along with the object code.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
					 | 
				
			||||||
except as expressly provided under this License.  Any attempt
 | 
					 | 
				
			||||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
					 | 
				
			||||||
void, and will automatically terminate your rights under this License.
 | 
					 | 
				
			||||||
However, parties who have received copies, or rights, from you under
 | 
					 | 
				
			||||||
this License will not have their licenses terminated so long as such
 | 
					 | 
				
			||||||
parties remain in full compliance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  5. You are not required to accept this License, since you have not
 | 
					 | 
				
			||||||
signed it.  However, nothing else grants you permission to modify or
 | 
					 | 
				
			||||||
distribute the Program or its derivative works.  These actions are
 | 
					 | 
				
			||||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
					 | 
				
			||||||
modifying or distributing the Program (or any work based on the
 | 
					 | 
				
			||||||
Program), you indicate your acceptance of this License to do so, and
 | 
					 | 
				
			||||||
all its terms and conditions for copying, distributing or modifying
 | 
					 | 
				
			||||||
the Program or works based on it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  6. Each time you redistribute the Program (or any work based on the
 | 
					 | 
				
			||||||
Program), the recipient automatically receives a license from the
 | 
					 | 
				
			||||||
original licensor to copy, distribute or modify the Program subject to
 | 
					 | 
				
			||||||
these terms and conditions.  You may not impose any further
 | 
					 | 
				
			||||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
					 | 
				
			||||||
You are not responsible for enforcing compliance by third parties to
 | 
					 | 
				
			||||||
this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
					 | 
				
			||||||
infringement or for any other reason (not limited to patent issues),
 | 
					 | 
				
			||||||
conditions are imposed on you (whether by court order, agreement or
 | 
					 | 
				
			||||||
otherwise) that contradict the conditions of this License, they do not
 | 
					 | 
				
			||||||
excuse you from the conditions of this License.  If you cannot
 | 
					 | 
				
			||||||
distribute so as to satisfy simultaneously your obligations under this
 | 
					 | 
				
			||||||
License and any other pertinent obligations, then as a consequence you
 | 
					 | 
				
			||||||
may not distribute the Program at all.  For example, if a patent
 | 
					 | 
				
			||||||
license would not permit royalty-free redistribution of the Program by
 | 
					 | 
				
			||||||
all those who receive copies directly or indirectly through you, then
 | 
					 | 
				
			||||||
the only way you could satisfy both it and this License would be to
 | 
					 | 
				
			||||||
refrain entirely from distribution of the Program.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If any portion of this section is held invalid or unenforceable under
 | 
					 | 
				
			||||||
any particular circumstance, the balance of the section is intended to
 | 
					 | 
				
			||||||
apply and the section as a whole is intended to apply in other
 | 
					 | 
				
			||||||
circumstances.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It is not the purpose of this section to induce you to infringe any
 | 
					 | 
				
			||||||
patents or other property right claims or to contest validity of any
 | 
					 | 
				
			||||||
such claims; this section has the sole purpose of protecting the
 | 
					 | 
				
			||||||
integrity of the free software distribution system, which is
 | 
					 | 
				
			||||||
implemented by public license practices.  Many people have made
 | 
					 | 
				
			||||||
generous contributions to the wide range of software distributed
 | 
					 | 
				
			||||||
through that system in reliance on consistent application of that
 | 
					 | 
				
			||||||
system; it is up to the author/donor to decide if he or she is willing
 | 
					 | 
				
			||||||
to distribute software through any other system and a licensee cannot
 | 
					 | 
				
			||||||
impose that choice.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This section is intended to make thoroughly clear what is believed to
 | 
					 | 
				
			||||||
be a consequence of the rest of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  8. If the distribution and/or use of the Program is restricted in
 | 
					 | 
				
			||||||
certain countries either by patents or by copyrighted interfaces, the
 | 
					 | 
				
			||||||
original copyright holder who places the Program under this License
 | 
					 | 
				
			||||||
may add an explicit geographical distribution limitation excluding
 | 
					 | 
				
			||||||
those countries, so that distribution is permitted only in or among
 | 
					 | 
				
			||||||
countries not thus excluded.  In such case, this License incorporates
 | 
					 | 
				
			||||||
the limitation as if written in the body of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
					 | 
				
			||||||
of the General Public License from time to time.  Such new versions will
 | 
					 | 
				
			||||||
be similar in spirit to the present version, but may differ in detail to
 | 
					 | 
				
			||||||
address new problems or concerns.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Each version is given a distinguishing version number.  If the Program
 | 
					 | 
				
			||||||
specifies a version number of this License which applies to it and "any
 | 
					 | 
				
			||||||
later version", you have the option of following the terms and conditions
 | 
					 | 
				
			||||||
either of that version or of any later version published by the Free
 | 
					 | 
				
			||||||
Software Foundation.  If the Program does not specify a version number of
 | 
					 | 
				
			||||||
this License, you may choose any version ever published by the Free Software
 | 
					 | 
				
			||||||
Foundation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  10. If you wish to incorporate parts of the Program into other free
 | 
					 | 
				
			||||||
programs whose distribution conditions are different, write to the author
 | 
					 | 
				
			||||||
to ask for permission.  For software which is copyrighted by the Free
 | 
					 | 
				
			||||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
					 | 
				
			||||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
					 | 
				
			||||||
of preserving the free status of all derivatives of our free software and
 | 
					 | 
				
			||||||
of promoting the sharing and reuse of software generally.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            NO WARRANTY
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
					 | 
				
			||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
					 | 
				
			||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
					 | 
				
			||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
					 | 
				
			||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
					 | 
				
			||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
					 | 
				
			||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
					 | 
				
			||||||
REPAIR OR CORRECTION.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
					 | 
				
			||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
					 | 
				
			||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
					 | 
				
			||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
					 | 
				
			||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
					 | 
				
			||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
					 | 
				
			||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
					 | 
				
			||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
					 | 
				
			||||||
POSSIBILITY OF SUCH DAMAGES.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                     END OF TERMS AND CONDITIONS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            How to Apply These Terms to Your New Programs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  If you develop a new program, and you want it to be of the greatest
 | 
					 | 
				
			||||||
possible use to the public, the best way to achieve this is to make it
 | 
					 | 
				
			||||||
free software which everyone can redistribute and change under these terms.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  To do so, attach the following notices to the program.  It is safest
 | 
					 | 
				
			||||||
to attach them to the start of each source file to most effectively
 | 
					 | 
				
			||||||
convey the exclusion of warranty; and each file should have at least
 | 
					 | 
				
			||||||
the "copyright" line and a pointer to where the full notice is found.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
					 | 
				
			||||||
    Copyright (C) <year>  <name of author>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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 2 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, write to the Free Software Foundation, Inc.,
 | 
					 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Also add information on how to contact you by electronic and paper mail.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If the program is interactive, make it output a short notice like this
 | 
					 | 
				
			||||||
when it starts in an interactive mode:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
					 | 
				
			||||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
					 | 
				
			||||||
    This is free software, and you are welcome to redistribute it
 | 
					 | 
				
			||||||
    under certain conditions; type `show c' for details.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
					 | 
				
			||||||
parts of the General Public License.  Of course, the commands you use may
 | 
					 | 
				
			||||||
be called something other than `show w' and `show c'; they could even be
 | 
					 | 
				
			||||||
mouse-clicks or menu items--whatever suits your program.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You should also get your employer (if you work as a programmer) or your
 | 
					 | 
				
			||||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
					 | 
				
			||||||
necessary.  Here is a sample; alter the names:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
					 | 
				
			||||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <signature of Ty Coon>, 1 April 1989
 | 
					 | 
				
			||||||
  Ty Coon, President of Vice
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This General Public License does not permit incorporating your program into
 | 
					 | 
				
			||||||
proprietary programs.  If your program is a subroutine library, you may
 | 
					 | 
				
			||||||
consider it more useful to permit linking proprietary applications with the
 | 
					 | 
				
			||||||
library.  If this is what you want to do, use the GNU Lesser General
 | 
					 | 
				
			||||||
Public License instead of this License.
 | 
					 | 
				
			||||||
							
								
								
									
										502
									
								
								COPYING.LESSER
									
									
									
									
									
								
							
							
						
						
									
										502
									
								
								COPYING.LESSER
									
									
									
									
									
								
							@@ -1,502 +0,0 @@
 | 
				
			|||||||
                  GNU LESSER GENERAL PUBLIC LICENSE
 | 
					 | 
				
			||||||
                       Version 2.1, February 1999
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
 | 
					 | 
				
			||||||
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
					 | 
				
			||||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
					 | 
				
			||||||
 of this license document, but changing it is not allowed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[This is the first released version of the Lesser GPL.  It also counts
 | 
					 | 
				
			||||||
 as the successor of the GNU Library Public License, version 2, hence
 | 
					 | 
				
			||||||
 the version number 2.1.]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            Preamble
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  The licenses for most software are designed to take away your
 | 
					 | 
				
			||||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
					 | 
				
			||||||
Licenses are intended to guarantee your freedom to share and change
 | 
					 | 
				
			||||||
free software--to make sure the software is free for all its users.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  This license, the Lesser General Public License, applies to some
 | 
					 | 
				
			||||||
specially designated software packages--typically libraries--of the
 | 
					 | 
				
			||||||
Free Software Foundation and other authors who decide to use it.  You
 | 
					 | 
				
			||||||
can use it too, but we suggest you first think carefully about whether
 | 
					 | 
				
			||||||
this license or the ordinary General Public License is the better
 | 
					 | 
				
			||||||
strategy to use in any particular case, based on the explanations below.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  When we speak of free software, we are referring to freedom of use,
 | 
					 | 
				
			||||||
not price.  Our General Public Licenses are designed to make sure that
 | 
					 | 
				
			||||||
you have the freedom to distribute copies of free software (and charge
 | 
					 | 
				
			||||||
for this service if you wish); that you receive source code or can get
 | 
					 | 
				
			||||||
it if you want it; that you can change the software and use pieces of
 | 
					 | 
				
			||||||
it in new free programs; and that you are informed that you can do
 | 
					 | 
				
			||||||
these things.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  To protect your rights, we need to make restrictions that forbid
 | 
					 | 
				
			||||||
distributors to deny you these rights or to ask you to surrender these
 | 
					 | 
				
			||||||
rights.  These restrictions translate to certain responsibilities for
 | 
					 | 
				
			||||||
you if you distribute copies of the library or if you modify it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  For example, if you distribute copies of the library, whether gratis
 | 
					 | 
				
			||||||
or for a fee, you must give the recipients all the rights that we gave
 | 
					 | 
				
			||||||
you.  You must make sure that they, too, receive or can get the source
 | 
					 | 
				
			||||||
code.  If you link other code with the library, you must provide
 | 
					 | 
				
			||||||
complete object files to the recipients, so that they can relink them
 | 
					 | 
				
			||||||
with the library after making changes to the library and recompiling
 | 
					 | 
				
			||||||
it.  And you must show them these terms so they know their rights.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  We protect your rights with a two-step method: (1) we copyright the
 | 
					 | 
				
			||||||
library, and (2) we offer you this license, which gives you legal
 | 
					 | 
				
			||||||
permission to copy, distribute and/or modify the library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  To protect each distributor, we want to make it very clear that
 | 
					 | 
				
			||||||
there is no warranty for the free library.  Also, if the library is
 | 
					 | 
				
			||||||
modified by someone else and passed on, the recipients should know
 | 
					 | 
				
			||||||
that what they have is not the original version, so that the original
 | 
					 | 
				
			||||||
author's reputation will not be affected by problems that might be
 | 
					 | 
				
			||||||
introduced by others.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Finally, software patents pose a constant threat to the existence of
 | 
					 | 
				
			||||||
any free program.  We wish to make sure that a company cannot
 | 
					 | 
				
			||||||
effectively restrict the users of a free program by obtaining a
 | 
					 | 
				
			||||||
restrictive license from a patent holder.  Therefore, we insist that
 | 
					 | 
				
			||||||
any patent license obtained for a version of the library must be
 | 
					 | 
				
			||||||
consistent with the full freedom of use specified in this license.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Most GNU software, including some libraries, is covered by the
 | 
					 | 
				
			||||||
ordinary GNU General Public License.  This license, the GNU Lesser
 | 
					 | 
				
			||||||
General Public License, applies to certain designated libraries, and
 | 
					 | 
				
			||||||
is quite different from the ordinary General Public License.  We use
 | 
					 | 
				
			||||||
this license for certain libraries in order to permit linking those
 | 
					 | 
				
			||||||
libraries into non-free programs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  When a program is linked with a library, whether statically or using
 | 
					 | 
				
			||||||
a shared library, the combination of the two is legally speaking a
 | 
					 | 
				
			||||||
combined work, a derivative of the original library.  The ordinary
 | 
					 | 
				
			||||||
General Public License therefore permits such linking only if the
 | 
					 | 
				
			||||||
entire combination fits its criteria of freedom.  The Lesser General
 | 
					 | 
				
			||||||
Public License permits more lax criteria for linking other code with
 | 
					 | 
				
			||||||
the library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  We call this license the "Lesser" General Public License because it
 | 
					 | 
				
			||||||
does Less to protect the user's freedom than the ordinary General
 | 
					 | 
				
			||||||
Public License.  It also provides other free software developers Less
 | 
					 | 
				
			||||||
of an advantage over competing non-free programs.  These disadvantages
 | 
					 | 
				
			||||||
are the reason we use the ordinary General Public License for many
 | 
					 | 
				
			||||||
libraries.  However, the Lesser license provides advantages in certain
 | 
					 | 
				
			||||||
special circumstances.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  For example, on rare occasions, there may be a special need to
 | 
					 | 
				
			||||||
encourage the widest possible use of a certain library, so that it becomes
 | 
					 | 
				
			||||||
a de-facto standard.  To achieve this, non-free programs must be
 | 
					 | 
				
			||||||
allowed to use the library.  A more frequent case is that a free
 | 
					 | 
				
			||||||
library does the same job as widely used non-free libraries.  In this
 | 
					 | 
				
			||||||
case, there is little to gain by limiting the free library to free
 | 
					 | 
				
			||||||
software only, so we use the Lesser General Public License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  In other cases, permission to use a particular library in non-free
 | 
					 | 
				
			||||||
programs enables a greater number of people to use a large body of
 | 
					 | 
				
			||||||
free software.  For example, permission to use the GNU C Library in
 | 
					 | 
				
			||||||
non-free programs enables many more people to use the whole GNU
 | 
					 | 
				
			||||||
operating system, as well as its variant, the GNU/Linux operating
 | 
					 | 
				
			||||||
system.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Although the Lesser General Public License is Less protective of the
 | 
					 | 
				
			||||||
users' freedom, it does ensure that the user of a program that is
 | 
					 | 
				
			||||||
linked with the Library has the freedom and the wherewithal to run
 | 
					 | 
				
			||||||
that program using a modified version of the Library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  The precise terms and conditions for copying, distribution and
 | 
					 | 
				
			||||||
modification follow.  Pay close attention to the difference between a
 | 
					 | 
				
			||||||
"work based on the library" and a "work that uses the library".  The
 | 
					 | 
				
			||||||
former contains code derived from the library, whereas the latter must
 | 
					 | 
				
			||||||
be combined with the library in order to run.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  GNU LESSER GENERAL PUBLIC LICENSE
 | 
					 | 
				
			||||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  0. This License Agreement applies to any software library or other
 | 
					 | 
				
			||||||
program which contains a notice placed by the copyright holder or
 | 
					 | 
				
			||||||
other authorized party saying it may be distributed under the terms of
 | 
					 | 
				
			||||||
this Lesser General Public License (also called "this License").
 | 
					 | 
				
			||||||
Each licensee is addressed as "you".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  A "library" means a collection of software functions and/or data
 | 
					 | 
				
			||||||
prepared so as to be conveniently linked with application programs
 | 
					 | 
				
			||||||
(which use some of those functions and data) to form executables.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  The "Library", below, refers to any such software library or work
 | 
					 | 
				
			||||||
which has been distributed under these terms.  A "work based on the
 | 
					 | 
				
			||||||
Library" means either the Library or any derivative work under
 | 
					 | 
				
			||||||
copyright law: that is to say, a work containing the Library or a
 | 
					 | 
				
			||||||
portion of it, either verbatim or with modifications and/or translated
 | 
					 | 
				
			||||||
straightforwardly into another language.  (Hereinafter, translation is
 | 
					 | 
				
			||||||
included without limitation in the term "modification".)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  "Source code" for a work means the preferred form of the work for
 | 
					 | 
				
			||||||
making modifications to it.  For a library, complete source code means
 | 
					 | 
				
			||||||
all the source code for all modules it contains, plus any associated
 | 
					 | 
				
			||||||
interface definition files, plus the scripts used to control compilation
 | 
					 | 
				
			||||||
and installation of the library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Activities other than copying, distribution and modification are not
 | 
					 | 
				
			||||||
covered by this License; they are outside its scope.  The act of
 | 
					 | 
				
			||||||
running a program using the Library is not restricted, and output from
 | 
					 | 
				
			||||||
such a program is covered only if its contents constitute a work based
 | 
					 | 
				
			||||||
on the Library (independent of the use of the Library in a tool for
 | 
					 | 
				
			||||||
writing it).  Whether that is true depends on what the Library does
 | 
					 | 
				
			||||||
and what the program that uses the Library does.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  1. You may copy and distribute verbatim copies of the Library's
 | 
					 | 
				
			||||||
complete source code as you receive it, in any medium, provided that
 | 
					 | 
				
			||||||
you conspicuously and appropriately publish on each copy an
 | 
					 | 
				
			||||||
appropriate copyright notice and disclaimer of warranty; keep intact
 | 
					 | 
				
			||||||
all the notices that refer to this License and to the absence of any
 | 
					 | 
				
			||||||
warranty; and distribute a copy of this License along with the
 | 
					 | 
				
			||||||
Library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  You may charge a fee for the physical act of transferring a copy,
 | 
					 | 
				
			||||||
and you may at your option offer warranty protection in exchange for a
 | 
					 | 
				
			||||||
fee.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  2. You may modify your copy or copies of the Library or any portion
 | 
					 | 
				
			||||||
of it, thus forming a work based on the Library, and copy and
 | 
					 | 
				
			||||||
distribute such modifications or work under the terms of Section 1
 | 
					 | 
				
			||||||
above, provided that you also meet all of these conditions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a) The modified work must itself be a software library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    b) You must cause the files modified to carry prominent notices
 | 
					 | 
				
			||||||
    stating that you changed the files and the date of any change.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c) You must cause the whole of the work to be licensed at no
 | 
					 | 
				
			||||||
    charge to all third parties under the terms of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d) If a facility in the modified Library refers to a function or a
 | 
					 | 
				
			||||||
    table of data to be supplied by an application program that uses
 | 
					 | 
				
			||||||
    the facility, other than as an argument passed when the facility
 | 
					 | 
				
			||||||
    is invoked, then you must make a good faith effort to ensure that,
 | 
					 | 
				
			||||||
    in the event an application does not supply such function or
 | 
					 | 
				
			||||||
    table, the facility still operates, and performs whatever part of
 | 
					 | 
				
			||||||
    its purpose remains meaningful.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (For example, a function in a library to compute square roots has
 | 
					 | 
				
			||||||
    a purpose that is entirely well-defined independent of the
 | 
					 | 
				
			||||||
    application.  Therefore, Subsection 2d requires that any
 | 
					 | 
				
			||||||
    application-supplied function or table used by this function must
 | 
					 | 
				
			||||||
    be optional: if the application does not supply it, the square
 | 
					 | 
				
			||||||
    root function must still compute square roots.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These requirements apply to the modified work as a whole.  If
 | 
					 | 
				
			||||||
identifiable sections of that work are not derived from the Library,
 | 
					 | 
				
			||||||
and can be reasonably considered independent and separate works in
 | 
					 | 
				
			||||||
themselves, then this License, and its terms, do not apply to those
 | 
					 | 
				
			||||||
sections when you distribute them as separate works.  But when you
 | 
					 | 
				
			||||||
distribute the same sections as part of a whole which is a work based
 | 
					 | 
				
			||||||
on the Library, the distribution of the whole must be on the terms of
 | 
					 | 
				
			||||||
this License, whose permissions for other licensees extend to the
 | 
					 | 
				
			||||||
entire whole, and thus to each and every part regardless of who wrote
 | 
					 | 
				
			||||||
it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Thus, it is not the intent of this section to claim rights or contest
 | 
					 | 
				
			||||||
your rights to work written entirely by you; rather, the intent is to
 | 
					 | 
				
			||||||
exercise the right to control the distribution of derivative or
 | 
					 | 
				
			||||||
collective works based on the Library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In addition, mere aggregation of another work not based on the Library
 | 
					 | 
				
			||||||
with the Library (or with a work based on the Library) on a volume of
 | 
					 | 
				
			||||||
a storage or distribution medium does not bring the other work under
 | 
					 | 
				
			||||||
the scope of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  3. You may opt to apply the terms of the ordinary GNU General Public
 | 
					 | 
				
			||||||
License instead of this License to a given copy of the Library.  To do
 | 
					 | 
				
			||||||
this, you must alter all the notices that refer to this License, so
 | 
					 | 
				
			||||||
that they refer to the ordinary GNU General Public License, version 2,
 | 
					 | 
				
			||||||
instead of to this License.  (If a newer version than version 2 of the
 | 
					 | 
				
			||||||
ordinary GNU General Public License has appeared, then you can specify
 | 
					 | 
				
			||||||
that version instead if you wish.)  Do not make any other change in
 | 
					 | 
				
			||||||
these notices.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Once this change is made in a given copy, it is irreversible for
 | 
					 | 
				
			||||||
that copy, so the ordinary GNU General Public License applies to all
 | 
					 | 
				
			||||||
subsequent copies and derivative works made from that copy.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  This option is useful when you wish to copy part of the code of
 | 
					 | 
				
			||||||
the Library into a program that is not a library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  4. You may copy and distribute the Library (or a portion or
 | 
					 | 
				
			||||||
derivative of it, under Section 2) in object code or executable form
 | 
					 | 
				
			||||||
under the terms of Sections 1 and 2 above provided that you accompany
 | 
					 | 
				
			||||||
it with the complete corresponding machine-readable source code, which
 | 
					 | 
				
			||||||
must be distributed under the terms of Sections 1 and 2 above on a
 | 
					 | 
				
			||||||
medium customarily used for software interchange.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  If distribution of object code is made by offering access to copy
 | 
					 | 
				
			||||||
from a designated place, then offering equivalent access to copy the
 | 
					 | 
				
			||||||
source code from the same place satisfies the requirement to
 | 
					 | 
				
			||||||
distribute the source code, even though third parties are not
 | 
					 | 
				
			||||||
compelled to copy the source along with the object code.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  5. A program that contains no derivative of any portion of the
 | 
					 | 
				
			||||||
Library, but is designed to work with the Library by being compiled or
 | 
					 | 
				
			||||||
linked with it, is called a "work that uses the Library".  Such a
 | 
					 | 
				
			||||||
work, in isolation, is not a derivative work of the Library, and
 | 
					 | 
				
			||||||
therefore falls outside the scope of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  However, linking a "work that uses the Library" with the Library
 | 
					 | 
				
			||||||
creates an executable that is a derivative of the Library (because it
 | 
					 | 
				
			||||||
contains portions of the Library), rather than a "work that uses the
 | 
					 | 
				
			||||||
library".  The executable is therefore covered by this License.
 | 
					 | 
				
			||||||
Section 6 states terms for distribution of such executables.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  When a "work that uses the Library" uses material from a header file
 | 
					 | 
				
			||||||
that is part of the Library, the object code for the work may be a
 | 
					 | 
				
			||||||
derivative work of the Library even though the source code is not.
 | 
					 | 
				
			||||||
Whether this is true is especially significant if the work can be
 | 
					 | 
				
			||||||
linked without the Library, or if the work is itself a library.  The
 | 
					 | 
				
			||||||
threshold for this to be true is not precisely defined by law.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  If such an object file uses only numerical parameters, data
 | 
					 | 
				
			||||||
structure layouts and accessors, and small macros and small inline
 | 
					 | 
				
			||||||
functions (ten lines or less in length), then the use of the object
 | 
					 | 
				
			||||||
file is unrestricted, regardless of whether it is legally a derivative
 | 
					 | 
				
			||||||
work.  (Executables containing this object code plus portions of the
 | 
					 | 
				
			||||||
Library will still fall under Section 6.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Otherwise, if the work is a derivative of the Library, you may
 | 
					 | 
				
			||||||
distribute the object code for the work under the terms of Section 6.
 | 
					 | 
				
			||||||
Any executables containing that work also fall under Section 6,
 | 
					 | 
				
			||||||
whether or not they are linked directly with the Library itself.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  6. As an exception to the Sections above, you may also combine or
 | 
					 | 
				
			||||||
link a "work that uses the Library" with the Library to produce a
 | 
					 | 
				
			||||||
work containing portions of the Library, and distribute that work
 | 
					 | 
				
			||||||
under terms of your choice, provided that the terms permit
 | 
					 | 
				
			||||||
modification of the work for the customer's own use and reverse
 | 
					 | 
				
			||||||
engineering for debugging such modifications.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  You must give prominent notice with each copy of the work that the
 | 
					 | 
				
			||||||
Library is used in it and that the Library and its use are covered by
 | 
					 | 
				
			||||||
this License.  You must supply a copy of this License.  If the work
 | 
					 | 
				
			||||||
during execution displays copyright notices, you must include the
 | 
					 | 
				
			||||||
copyright notice for the Library among them, as well as a reference
 | 
					 | 
				
			||||||
directing the user to the copy of this License.  Also, you must do one
 | 
					 | 
				
			||||||
of these things:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a) Accompany the work with the complete corresponding
 | 
					 | 
				
			||||||
    machine-readable source code for the Library including whatever
 | 
					 | 
				
			||||||
    changes were used in the work (which must be distributed under
 | 
					 | 
				
			||||||
    Sections 1 and 2 above); and, if the work is an executable linked
 | 
					 | 
				
			||||||
    with the Library, with the complete machine-readable "work that
 | 
					 | 
				
			||||||
    uses the Library", as object code and/or source code, so that the
 | 
					 | 
				
			||||||
    user can modify the Library and then relink to produce a modified
 | 
					 | 
				
			||||||
    executable containing the modified Library.  (It is understood
 | 
					 | 
				
			||||||
    that the user who changes the contents of definitions files in the
 | 
					 | 
				
			||||||
    Library will not necessarily be able to recompile the application
 | 
					 | 
				
			||||||
    to use the modified definitions.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    b) Use a suitable shared library mechanism for linking with the
 | 
					 | 
				
			||||||
    Library.  A suitable mechanism is one that (1) uses at run time a
 | 
					 | 
				
			||||||
    copy of the library already present on the user's computer system,
 | 
					 | 
				
			||||||
    rather than copying library functions into the executable, and (2)
 | 
					 | 
				
			||||||
    will operate properly with a modified version of the library, if
 | 
					 | 
				
			||||||
    the user installs one, as long as the modified version is
 | 
					 | 
				
			||||||
    interface-compatible with the version that the work was made with.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    c) Accompany the work with a written offer, valid for at
 | 
					 | 
				
			||||||
    least three years, to give the same user the materials
 | 
					 | 
				
			||||||
    specified in Subsection 6a, above, for a charge no more
 | 
					 | 
				
			||||||
    than the cost of performing this distribution.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d) If distribution of the work is made by offering access to copy
 | 
					 | 
				
			||||||
    from a designated place, offer equivalent access to copy the above
 | 
					 | 
				
			||||||
    specified materials from the same place.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    e) Verify that the user has already received a copy of these
 | 
					 | 
				
			||||||
    materials or that you have already sent this user a copy.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  For an executable, the required form of the "work that uses the
 | 
					 | 
				
			||||||
Library" must include any data and utility programs needed for
 | 
					 | 
				
			||||||
reproducing the executable from it.  However, as a special exception,
 | 
					 | 
				
			||||||
the materials to be distributed need not include anything that is
 | 
					 | 
				
			||||||
normally distributed (in either source or binary form) with the major
 | 
					 | 
				
			||||||
components (compiler, kernel, and so on) of the operating system on
 | 
					 | 
				
			||||||
which the executable runs, unless that component itself accompanies
 | 
					 | 
				
			||||||
the executable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  It may happen that this requirement contradicts the license
 | 
					 | 
				
			||||||
restrictions of other proprietary libraries that do not normally
 | 
					 | 
				
			||||||
accompany the operating system.  Such a contradiction means you cannot
 | 
					 | 
				
			||||||
use both them and the Library together in an executable that you
 | 
					 | 
				
			||||||
distribute.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  7. You may place library facilities that are a work based on the
 | 
					 | 
				
			||||||
Library side-by-side in a single library together with other library
 | 
					 | 
				
			||||||
facilities not covered by this License, and distribute such a combined
 | 
					 | 
				
			||||||
library, provided that the separate distribution of the work based on
 | 
					 | 
				
			||||||
the Library and of the other library facilities is otherwise
 | 
					 | 
				
			||||||
permitted, and provided that you do these two things:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    a) Accompany the combined library with a copy of the same work
 | 
					 | 
				
			||||||
    based on the Library, uncombined with any other library
 | 
					 | 
				
			||||||
    facilities.  This must be distributed under the terms of the
 | 
					 | 
				
			||||||
    Sections above.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    b) Give prominent notice with the combined library of the fact
 | 
					 | 
				
			||||||
    that part of it is a work based on the Library, and explaining
 | 
					 | 
				
			||||||
    where to find the accompanying uncombined form of the same work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  8. You may not copy, modify, sublicense, link with, or distribute
 | 
					 | 
				
			||||||
the Library except as expressly provided under this License.  Any
 | 
					 | 
				
			||||||
attempt otherwise to copy, modify, sublicense, link with, or
 | 
					 | 
				
			||||||
distribute the Library is void, and will automatically terminate your
 | 
					 | 
				
			||||||
rights under this License.  However, parties who have received copies,
 | 
					 | 
				
			||||||
or rights, from you under this License will not have their licenses
 | 
					 | 
				
			||||||
terminated so long as such parties remain in full compliance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  9. You are not required to accept this License, since you have not
 | 
					 | 
				
			||||||
signed it.  However, nothing else grants you permission to modify or
 | 
					 | 
				
			||||||
distribute the Library or its derivative works.  These actions are
 | 
					 | 
				
			||||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
					 | 
				
			||||||
modifying or distributing the Library (or any work based on the
 | 
					 | 
				
			||||||
Library), you indicate your acceptance of this License to do so, and
 | 
					 | 
				
			||||||
all its terms and conditions for copying, distributing or modifying
 | 
					 | 
				
			||||||
the Library or works based on it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  10. Each time you redistribute the Library (or any work based on the
 | 
					 | 
				
			||||||
Library), the recipient automatically receives a license from the
 | 
					 | 
				
			||||||
original licensor to copy, distribute, link with or modify the Library
 | 
					 | 
				
			||||||
subject to these terms and conditions.  You may not impose any further
 | 
					 | 
				
			||||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
					 | 
				
			||||||
You are not responsible for enforcing compliance by third parties with
 | 
					 | 
				
			||||||
this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  11. If, as a consequence of a court judgment or allegation of patent
 | 
					 | 
				
			||||||
infringement or for any other reason (not limited to patent issues),
 | 
					 | 
				
			||||||
conditions are imposed on you (whether by court order, agreement or
 | 
					 | 
				
			||||||
otherwise) that contradict the conditions of this License, they do not
 | 
					 | 
				
			||||||
excuse you from the conditions of this License.  If you cannot
 | 
					 | 
				
			||||||
distribute so as to satisfy simultaneously your obligations under this
 | 
					 | 
				
			||||||
License and any other pertinent obligations, then as a consequence you
 | 
					 | 
				
			||||||
may not distribute the Library at all.  For example, if a patent
 | 
					 | 
				
			||||||
license would not permit royalty-free redistribution of the Library by
 | 
					 | 
				
			||||||
all those who receive copies directly or indirectly through you, then
 | 
					 | 
				
			||||||
the only way you could satisfy both it and this License would be to
 | 
					 | 
				
			||||||
refrain entirely from distribution of the Library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If any portion of this section is held invalid or unenforceable under any
 | 
					 | 
				
			||||||
particular circumstance, the balance of the section is intended to apply,
 | 
					 | 
				
			||||||
and the section as a whole is intended to apply in other circumstances.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It is not the purpose of this section to induce you to infringe any
 | 
					 | 
				
			||||||
patents or other property right claims or to contest validity of any
 | 
					 | 
				
			||||||
such claims; this section has the sole purpose of protecting the
 | 
					 | 
				
			||||||
integrity of the free software distribution system which is
 | 
					 | 
				
			||||||
implemented by public license practices.  Many people have made
 | 
					 | 
				
			||||||
generous contributions to the wide range of software distributed
 | 
					 | 
				
			||||||
through that system in reliance on consistent application of that
 | 
					 | 
				
			||||||
system; it is up to the author/donor to decide if he or she is willing
 | 
					 | 
				
			||||||
to distribute software through any other system and a licensee cannot
 | 
					 | 
				
			||||||
impose that choice.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This section is intended to make thoroughly clear what is believed to
 | 
					 | 
				
			||||||
be a consequence of the rest of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  12. If the distribution and/or use of the Library is restricted in
 | 
					 | 
				
			||||||
certain countries either by patents or by copyrighted interfaces, the
 | 
					 | 
				
			||||||
original copyright holder who places the Library under this License may add
 | 
					 | 
				
			||||||
an explicit geographical distribution limitation excluding those countries,
 | 
					 | 
				
			||||||
so that distribution is permitted only in or among countries not thus
 | 
					 | 
				
			||||||
excluded.  In such case, this License incorporates the limitation as if
 | 
					 | 
				
			||||||
written in the body of this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  13. The Free Software Foundation may publish revised and/or new
 | 
					 | 
				
			||||||
versions of the Lesser General Public License from time to time.
 | 
					 | 
				
			||||||
Such new versions will be similar in spirit to the present version,
 | 
					 | 
				
			||||||
but may differ in detail to address new problems or concerns.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Each version is given a distinguishing version number.  If the Library
 | 
					 | 
				
			||||||
specifies a version number of this License which applies to it and
 | 
					 | 
				
			||||||
"any later version", you have the option of following the terms and
 | 
					 | 
				
			||||||
conditions either of that version or of any later version published by
 | 
					 | 
				
			||||||
the Free Software Foundation.  If the Library does not specify a
 | 
					 | 
				
			||||||
license version number, you may choose any version ever published by
 | 
					 | 
				
			||||||
the Free Software Foundation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  14. If you wish to incorporate parts of the Library into other free
 | 
					 | 
				
			||||||
programs whose distribution conditions are incompatible with these,
 | 
					 | 
				
			||||||
write to the author to ask for permission.  For software which is
 | 
					 | 
				
			||||||
copyrighted by the Free Software Foundation, write to the Free
 | 
					 | 
				
			||||||
Software Foundation; we sometimes make exceptions for this.  Our
 | 
					 | 
				
			||||||
decision will be guided by the two goals of preserving the free status
 | 
					 | 
				
			||||||
of all derivatives of our free software and of promoting the sharing
 | 
					 | 
				
			||||||
and reuse of software generally.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            NO WARRANTY
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
 | 
					 | 
				
			||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
 | 
					 | 
				
			||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
 | 
					 | 
				
			||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
 | 
					 | 
				
			||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
 | 
					 | 
				
			||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
					 | 
				
			||||||
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
 | 
					 | 
				
			||||||
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
 | 
					 | 
				
			||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
 | 
					 | 
				
			||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
 | 
					 | 
				
			||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
 | 
					 | 
				
			||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
 | 
					 | 
				
			||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
 | 
					 | 
				
			||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
 | 
					 | 
				
			||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
 | 
					 | 
				
			||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
 | 
					 | 
				
			||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 | 
					 | 
				
			||||||
DAMAGES.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                     END OF TERMS AND CONDITIONS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
           How to Apply These Terms to Your New Libraries
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  If you develop a new library, and you want it to be of the greatest
 | 
					 | 
				
			||||||
possible use to the public, we recommend making it free software that
 | 
					 | 
				
			||||||
everyone can redistribute and change.  You can do so by permitting
 | 
					 | 
				
			||||||
redistribution under these terms (or, alternatively, under the terms of the
 | 
					 | 
				
			||||||
ordinary General Public License).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  To apply these terms, attach the following notices to the library.  It is
 | 
					 | 
				
			||||||
safest to attach them to the start of each source file to most effectively
 | 
					 | 
				
			||||||
convey the exclusion of warranty; and each file should have at least the
 | 
					 | 
				
			||||||
"copyright" line and a pointer to where the full notice is found.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <one line to give the library's name and a brief idea of what it does.>
 | 
					 | 
				
			||||||
    Copyright (C) <year>  <name of author>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
    modify it under the terms of the GNU Lesser General Public
 | 
					 | 
				
			||||||
    License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
    version 2.1 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
    Lesser General Public License for more details.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    You should have received a copy of the GNU Lesser General Public
 | 
					 | 
				
			||||||
    License along with this library; if not, write to the Free Software
 | 
					 | 
				
			||||||
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Also add information on how to contact you by electronic and paper mail.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You should also get your employer (if you work as a programmer) or your
 | 
					 | 
				
			||||||
school, if any, to sign a "copyright disclaimer" for the library, if
 | 
					 | 
				
			||||||
necessary.  Here is a sample; alter the names:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the
 | 
					 | 
				
			||||||
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <signature of Ty Coon>, 1 April 1990
 | 
					 | 
				
			||||||
  Ty Coon, President of Vice
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
That's all there is to it!
 | 
					 | 
				
			||||||
							
								
								
									
										508
									
								
								COPYING.LIB
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										508
									
								
								COPYING.LIB
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,508 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					                  GNU LESSER GENERAL PUBLIC LICENSE
 | 
				
			||||||
 | 
					                       Version 2.1, February 1999
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
 | 
				
			||||||
 | 
					     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
				
			||||||
 | 
					 Everyone is permitted to copy and distribute verbatim copies
 | 
				
			||||||
 | 
					 of this license document, but changing it is not allowed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[This is the first released version of the Lesser GPL.  It also counts
 | 
				
			||||||
 | 
					 as the successor of the GNU Library Public License, version 2, hence
 | 
				
			||||||
 | 
					 the version number 2.1.]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            Preamble
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The licenses for most software are designed to take away your
 | 
				
			||||||
 | 
					freedom to share and change it.  By contrast, the GNU General Public
 | 
				
			||||||
 | 
					Licenses are intended to guarantee your freedom to share and change
 | 
				
			||||||
 | 
					free software--to make sure the software is free for all its users.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  This license, the Lesser General Public License, applies to some
 | 
				
			||||||
 | 
					specially designated software packages--typically libraries--of the
 | 
				
			||||||
 | 
					Free Software Foundation and other authors who decide to use it.  You
 | 
				
			||||||
 | 
					can use it too, but we suggest you first think carefully about whether
 | 
				
			||||||
 | 
					this license or the ordinary General Public License is the better
 | 
				
			||||||
 | 
					strategy to use in any particular case, based on the explanations
 | 
				
			||||||
 | 
					below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  When we speak of free software, we are referring to freedom of use,
 | 
				
			||||||
 | 
					not price.  Our General Public Licenses are designed to make sure that
 | 
				
			||||||
 | 
					you have the freedom to distribute copies of free software (and charge
 | 
				
			||||||
 | 
					for this service if you wish); that you receive source code or can get
 | 
				
			||||||
 | 
					it if you want it; that you can change the software and use pieces of
 | 
				
			||||||
 | 
					it in new free programs; and that you are informed that you can do
 | 
				
			||||||
 | 
					these things.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  To protect your rights, we need to make restrictions that forbid
 | 
				
			||||||
 | 
					distributors to deny you these rights or to ask you to surrender these
 | 
				
			||||||
 | 
					rights.  These restrictions translate to certain responsibilities for
 | 
				
			||||||
 | 
					you if you distribute copies of the library or if you modify it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  For example, if you distribute copies of the library, whether gratis
 | 
				
			||||||
 | 
					or for a fee, you must give the recipients all the rights that we gave
 | 
				
			||||||
 | 
					you.  You must make sure that they, too, receive or can get the source
 | 
				
			||||||
 | 
					code.  If you link other code with the library, you must provide
 | 
				
			||||||
 | 
					complete object files to the recipients, so that they can relink them
 | 
				
			||||||
 | 
					with the library after making changes to the library and recompiling
 | 
				
			||||||
 | 
					it.  And you must show them these terms so they know their rights.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  We protect your rights with a two-step method: (1) we copyright the
 | 
				
			||||||
 | 
					library, and (2) we offer you this license, which gives you legal
 | 
				
			||||||
 | 
					permission to copy, distribute and/or modify the library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  To protect each distributor, we want to make it very clear that
 | 
				
			||||||
 | 
					there is no warranty for the free library.  Also, if the library is
 | 
				
			||||||
 | 
					modified by someone else and passed on, the recipients should know
 | 
				
			||||||
 | 
					that what they have is not the original version, so that the original
 | 
				
			||||||
 | 
					author's reputation will not be affected by problems that might be
 | 
				
			||||||
 | 
					introduced by others.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					  Finally, software patents pose a constant threat to the existence of
 | 
				
			||||||
 | 
					any free program.  We wish to make sure that a company cannot
 | 
				
			||||||
 | 
					effectively restrict the users of a free program by obtaining a
 | 
				
			||||||
 | 
					restrictive license from a patent holder.  Therefore, we insist that
 | 
				
			||||||
 | 
					any patent license obtained for a version of the library must be
 | 
				
			||||||
 | 
					consistent with the full freedom of use specified in this license.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Most GNU software, including some libraries, is covered by the
 | 
				
			||||||
 | 
					ordinary GNU General Public License.  This license, the GNU Lesser
 | 
				
			||||||
 | 
					General Public License, applies to certain designated libraries, and
 | 
				
			||||||
 | 
					is quite different from the ordinary General Public License.  We use
 | 
				
			||||||
 | 
					this license for certain libraries in order to permit linking those
 | 
				
			||||||
 | 
					libraries into non-free programs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  When a program is linked with a library, whether statically or using
 | 
				
			||||||
 | 
					a shared library, the combination of the two is legally speaking a
 | 
				
			||||||
 | 
					combined work, a derivative of the original library.  The ordinary
 | 
				
			||||||
 | 
					General Public License therefore permits such linking only if the
 | 
				
			||||||
 | 
					entire combination fits its criteria of freedom.  The Lesser General
 | 
				
			||||||
 | 
					Public License permits more lax criteria for linking other code with
 | 
				
			||||||
 | 
					the library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  We call this license the "Lesser" General Public License because it
 | 
				
			||||||
 | 
					does Less to protect the user's freedom than the ordinary General
 | 
				
			||||||
 | 
					Public License.  It also provides other free software developers Less
 | 
				
			||||||
 | 
					of an advantage over competing non-free programs.  These disadvantages
 | 
				
			||||||
 | 
					are the reason we use the ordinary General Public License for many
 | 
				
			||||||
 | 
					libraries.  However, the Lesser license provides advantages in certain
 | 
				
			||||||
 | 
					special circumstances.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  For example, on rare occasions, there may be a special need to
 | 
				
			||||||
 | 
					encourage the widest possible use of a certain library, so that it
 | 
				
			||||||
 | 
					becomes a de-facto standard.  To achieve this, non-free programs must
 | 
				
			||||||
 | 
					be allowed to use the library.  A more frequent case is that a free
 | 
				
			||||||
 | 
					library does the same job as widely used non-free libraries.  In this
 | 
				
			||||||
 | 
					case, there is little to gain by limiting the free library to free
 | 
				
			||||||
 | 
					software only, so we use the Lesser General Public License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  In other cases, permission to use a particular library in non-free
 | 
				
			||||||
 | 
					programs enables a greater number of people to use a large body of
 | 
				
			||||||
 | 
					free software.  For example, permission to use the GNU C Library in
 | 
				
			||||||
 | 
					non-free programs enables many more people to use the whole GNU
 | 
				
			||||||
 | 
					operating system, as well as its variant, the GNU/Linux operating
 | 
				
			||||||
 | 
					system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Although the Lesser General Public License is Less protective of the
 | 
				
			||||||
 | 
					users' freedom, it does ensure that the user of a program that is
 | 
				
			||||||
 | 
					linked with the Library has the freedom and the wherewithal to run
 | 
				
			||||||
 | 
					that program using a modified version of the Library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The precise terms and conditions for copying, distribution and
 | 
				
			||||||
 | 
					modification follow.  Pay close attention to the difference between a
 | 
				
			||||||
 | 
					"work based on the library" and a "work that uses the library".  The
 | 
				
			||||||
 | 
					former contains code derived from the library, whereas the latter must
 | 
				
			||||||
 | 
					be combined with the library in order to run.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					                  GNU LESSER GENERAL PUBLIC LICENSE
 | 
				
			||||||
 | 
					   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  0. This License Agreement applies to any software library or other
 | 
				
			||||||
 | 
					program which contains a notice placed by the copyright holder or
 | 
				
			||||||
 | 
					other authorized party saying it may be distributed under the terms of
 | 
				
			||||||
 | 
					this Lesser General Public License (also called "this License").
 | 
				
			||||||
 | 
					Each licensee is addressed as "you".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  A "library" means a collection of software functions and/or data
 | 
				
			||||||
 | 
					prepared so as to be conveniently linked with application programs
 | 
				
			||||||
 | 
					(which use some of those functions and data) to form executables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The "Library", below, refers to any such software library or work
 | 
				
			||||||
 | 
					which has been distributed under these terms.  A "work based on the
 | 
				
			||||||
 | 
					Library" means either the Library or any derivative work under
 | 
				
			||||||
 | 
					copyright law: that is to say, a work containing the Library or a
 | 
				
			||||||
 | 
					portion of it, either verbatim or with modifications and/or translated
 | 
				
			||||||
 | 
					straightforwardly into another language.  (Hereinafter, translation is
 | 
				
			||||||
 | 
					included without limitation in the term "modification".)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "Source code" for a work means the preferred form of the work for
 | 
				
			||||||
 | 
					making modifications to it.  For a library, complete source code means
 | 
				
			||||||
 | 
					all the source code for all modules it contains, plus any associated
 | 
				
			||||||
 | 
					interface definition files, plus the scripts used to control
 | 
				
			||||||
 | 
					compilation and installation of the library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Activities other than copying, distribution and modification are not
 | 
				
			||||||
 | 
					covered by this License; they are outside its scope.  The act of
 | 
				
			||||||
 | 
					running a program using the Library is not restricted, and output from
 | 
				
			||||||
 | 
					such a program is covered only if its contents constitute a work based
 | 
				
			||||||
 | 
					on the Library (independent of the use of the Library in a tool for
 | 
				
			||||||
 | 
					writing it).  Whether that is true depends on what the Library does
 | 
				
			||||||
 | 
					and what the program that uses the Library does.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  1. You may copy and distribute verbatim copies of the Library's
 | 
				
			||||||
 | 
					complete source code as you receive it, in any medium, provided that
 | 
				
			||||||
 | 
					you conspicuously and appropriately publish on each copy an
 | 
				
			||||||
 | 
					appropriate copyright notice and disclaimer of warranty; keep intact
 | 
				
			||||||
 | 
					all the notices that refer to this License and to the absence of any
 | 
				
			||||||
 | 
					warranty; and distribute a copy of this License along with the
 | 
				
			||||||
 | 
					Library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  You may charge a fee for the physical act of transferring a copy,
 | 
				
			||||||
 | 
					and you may at your option offer warranty protection in exchange for a
 | 
				
			||||||
 | 
					fee.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  2. You may modify your copy or copies of the Library or any portion
 | 
				
			||||||
 | 
					of it, thus forming a work based on the Library, and copy and
 | 
				
			||||||
 | 
					distribute such modifications or work under the terms of Section 1
 | 
				
			||||||
 | 
					above, provided that you also meet all of these conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a) The modified work must itself be a software library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    b) You must cause the files modified to carry prominent notices
 | 
				
			||||||
 | 
					    stating that you changed the files and the date of any change.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c) You must cause the whole of the work to be licensed at no
 | 
				
			||||||
 | 
					    charge to all third parties under the terms of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    d) If a facility in the modified Library refers to a function or a
 | 
				
			||||||
 | 
					    table of data to be supplied by an application program that uses
 | 
				
			||||||
 | 
					    the facility, other than as an argument passed when the facility
 | 
				
			||||||
 | 
					    is invoked, then you must make a good faith effort to ensure that,
 | 
				
			||||||
 | 
					    in the event an application does not supply such function or
 | 
				
			||||||
 | 
					    table, the facility still operates, and performs whatever part of
 | 
				
			||||||
 | 
					    its purpose remains meaningful.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (For example, a function in a library to compute square roots has
 | 
				
			||||||
 | 
					    a purpose that is entirely well-defined independent of the
 | 
				
			||||||
 | 
					    application.  Therefore, Subsection 2d requires that any
 | 
				
			||||||
 | 
					    application-supplied function or table used by this function must
 | 
				
			||||||
 | 
					    be optional: if the application does not supply it, the square
 | 
				
			||||||
 | 
					    root function must still compute square roots.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These requirements apply to the modified work as a whole.  If
 | 
				
			||||||
 | 
					identifiable sections of that work are not derived from the Library,
 | 
				
			||||||
 | 
					and can be reasonably considered independent and separate works in
 | 
				
			||||||
 | 
					themselves, then this License, and its terms, do not apply to those
 | 
				
			||||||
 | 
					sections when you distribute them as separate works.  But when you
 | 
				
			||||||
 | 
					distribute the same sections as part of a whole which is a work based
 | 
				
			||||||
 | 
					on the Library, the distribution of the whole must be on the terms of
 | 
				
			||||||
 | 
					this License, whose permissions for other licensees extend to the
 | 
				
			||||||
 | 
					entire whole, and thus to each and every part regardless of who wrote
 | 
				
			||||||
 | 
					it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Thus, it is not the intent of this section to claim rights or contest
 | 
				
			||||||
 | 
					your rights to work written entirely by you; rather, the intent is to
 | 
				
			||||||
 | 
					exercise the right to control the distribution of derivative or
 | 
				
			||||||
 | 
					collective works based on the Library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In addition, mere aggregation of another work not based on the Library
 | 
				
			||||||
 | 
					with the Library (or with a work based on the Library) on a volume of
 | 
				
			||||||
 | 
					a storage or distribution medium does not bring the other work under
 | 
				
			||||||
 | 
					the scope of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  3. You may opt to apply the terms of the ordinary GNU General Public
 | 
				
			||||||
 | 
					License instead of this License to a given copy of the Library.  To do
 | 
				
			||||||
 | 
					this, you must alter all the notices that refer to this License, so
 | 
				
			||||||
 | 
					that they refer to the ordinary GNU General Public License, version 2,
 | 
				
			||||||
 | 
					instead of to this License.  (If a newer version than version 2 of the
 | 
				
			||||||
 | 
					ordinary GNU General Public License has appeared, then you can specify
 | 
				
			||||||
 | 
					that version instead if you wish.)  Do not make any other change in
 | 
				
			||||||
 | 
					these notices.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					  Once this change is made in a given copy, it is irreversible for
 | 
				
			||||||
 | 
					that copy, so the ordinary GNU General Public License applies to all
 | 
				
			||||||
 | 
					subsequent copies and derivative works made from that copy.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  This option is useful when you wish to copy part of the code of
 | 
				
			||||||
 | 
					the Library into a program that is not a library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  4. You may copy and distribute the Library (or a portion or
 | 
				
			||||||
 | 
					derivative of it, under Section 2) in object code or executable form
 | 
				
			||||||
 | 
					under the terms of Sections 1 and 2 above provided that you accompany
 | 
				
			||||||
 | 
					it with the complete corresponding machine-readable source code, which
 | 
				
			||||||
 | 
					must be distributed under the terms of Sections 1 and 2 above on a
 | 
				
			||||||
 | 
					medium customarily used for software interchange.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  If distribution of object code is made by offering access to copy
 | 
				
			||||||
 | 
					from a designated place, then offering equivalent access to copy the
 | 
				
			||||||
 | 
					source code from the same place satisfies the requirement to
 | 
				
			||||||
 | 
					distribute the source code, even though third parties are not
 | 
				
			||||||
 | 
					compelled to copy the source along with the object code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  5. A program that contains no derivative of any portion of the
 | 
				
			||||||
 | 
					Library, but is designed to work with the Library by being compiled or
 | 
				
			||||||
 | 
					linked with it, is called a "work that uses the Library".  Such a
 | 
				
			||||||
 | 
					work, in isolation, is not a derivative work of the Library, and
 | 
				
			||||||
 | 
					therefore falls outside the scope of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  However, linking a "work that uses the Library" with the Library
 | 
				
			||||||
 | 
					creates an executable that is a derivative of the Library (because it
 | 
				
			||||||
 | 
					contains portions of the Library), rather than a "work that uses the
 | 
				
			||||||
 | 
					library".  The executable is therefore covered by this License.
 | 
				
			||||||
 | 
					Section 6 states terms for distribution of such executables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  When a "work that uses the Library" uses material from a header file
 | 
				
			||||||
 | 
					that is part of the Library, the object code for the work may be a
 | 
				
			||||||
 | 
					derivative work of the Library even though the source code is not.
 | 
				
			||||||
 | 
					Whether this is true is especially significant if the work can be
 | 
				
			||||||
 | 
					linked without the Library, or if the work is itself a library.  The
 | 
				
			||||||
 | 
					threshold for this to be true is not precisely defined by law.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  If such an object file uses only numerical parameters, data
 | 
				
			||||||
 | 
					structure layouts and accessors, and small macros and small inline
 | 
				
			||||||
 | 
					functions (ten lines or less in length), then the use of the object
 | 
				
			||||||
 | 
					file is unrestricted, regardless of whether it is legally a derivative
 | 
				
			||||||
 | 
					work.  (Executables containing this object code plus portions of the
 | 
				
			||||||
 | 
					Library will still fall under Section 6.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Otherwise, if the work is a derivative of the Library, you may
 | 
				
			||||||
 | 
					distribute the object code for the work under the terms of Section 6.
 | 
				
			||||||
 | 
					Any executables containing that work also fall under Section 6,
 | 
				
			||||||
 | 
					whether or not they are linked directly with the Library itself.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					  6. As an exception to the Sections above, you may also combine or
 | 
				
			||||||
 | 
					link a "work that uses the Library" with the Library to produce a
 | 
				
			||||||
 | 
					work containing portions of the Library, and distribute that work
 | 
				
			||||||
 | 
					under terms of your choice, provided that the terms permit
 | 
				
			||||||
 | 
					modification of the work for the customer's own use and reverse
 | 
				
			||||||
 | 
					engineering for debugging such modifications.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  You must give prominent notice with each copy of the work that the
 | 
				
			||||||
 | 
					Library is used in it and that the Library and its use are covered by
 | 
				
			||||||
 | 
					this License.  You must supply a copy of this License.  If the work
 | 
				
			||||||
 | 
					during execution displays copyright notices, you must include the
 | 
				
			||||||
 | 
					copyright notice for the Library among them, as well as a reference
 | 
				
			||||||
 | 
					directing the user to the copy of this License.  Also, you must do one
 | 
				
			||||||
 | 
					of these things:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a) Accompany the work with the complete corresponding
 | 
				
			||||||
 | 
					    machine-readable source code for the Library including whatever
 | 
				
			||||||
 | 
					    changes were used in the work (which must be distributed under
 | 
				
			||||||
 | 
					    Sections 1 and 2 above); and, if the work is an executable linked
 | 
				
			||||||
 | 
					    with the Library, with the complete machine-readable "work that
 | 
				
			||||||
 | 
					    uses the Library", as object code and/or source code, so that the
 | 
				
			||||||
 | 
					    user can modify the Library and then relink to produce a modified
 | 
				
			||||||
 | 
					    executable containing the modified Library.  (It is understood
 | 
				
			||||||
 | 
					    that the user who changes the contents of definitions files in the
 | 
				
			||||||
 | 
					    Library will not necessarily be able to recompile the application
 | 
				
			||||||
 | 
					    to use the modified definitions.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    b) Use a suitable shared library mechanism for linking with the
 | 
				
			||||||
 | 
					    Library.  A suitable mechanism is one that (1) uses at run time a
 | 
				
			||||||
 | 
					    copy of the library already present on the user's computer system,
 | 
				
			||||||
 | 
					    rather than copying library functions into the executable, and (2)
 | 
				
			||||||
 | 
					    will operate properly with a modified version of the library, if
 | 
				
			||||||
 | 
					    the user installs one, as long as the modified version is
 | 
				
			||||||
 | 
					    interface-compatible with the version that the work was made with.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c) Accompany the work with a written offer, valid for at least
 | 
				
			||||||
 | 
					    three years, to give the same user the materials specified in
 | 
				
			||||||
 | 
					    Subsection 6a, above, for a charge no more than the cost of
 | 
				
			||||||
 | 
					    performing this distribution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    d) If distribution of the work is made by offering access to copy
 | 
				
			||||||
 | 
					    from a designated place, offer equivalent access to copy the above
 | 
				
			||||||
 | 
					    specified materials from the same place.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    e) Verify that the user has already received a copy of these
 | 
				
			||||||
 | 
					    materials or that you have already sent this user a copy.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  For an executable, the required form of the "work that uses the
 | 
				
			||||||
 | 
					Library" must include any data and utility programs needed for
 | 
				
			||||||
 | 
					reproducing the executable from it.  However, as a special exception,
 | 
				
			||||||
 | 
					the materials to be distributed need not include anything that is
 | 
				
			||||||
 | 
					normally distributed (in either source or binary form) with the major
 | 
				
			||||||
 | 
					components (compiler, kernel, and so on) of the operating system on
 | 
				
			||||||
 | 
					which the executable runs, unless that component itself accompanies
 | 
				
			||||||
 | 
					the executable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It may happen that this requirement contradicts the license
 | 
				
			||||||
 | 
					restrictions of other proprietary libraries that do not normally
 | 
				
			||||||
 | 
					accompany the operating system.  Such a contradiction means you cannot
 | 
				
			||||||
 | 
					use both them and the Library together in an executable that you
 | 
				
			||||||
 | 
					distribute.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					  7. You may place library facilities that are a work based on the
 | 
				
			||||||
 | 
					Library side-by-side in a single library together with other library
 | 
				
			||||||
 | 
					facilities not covered by this License, and distribute such a combined
 | 
				
			||||||
 | 
					library, provided that the separate distribution of the work based on
 | 
				
			||||||
 | 
					the Library and of the other library facilities is otherwise
 | 
				
			||||||
 | 
					permitted, and provided that you do these two things:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a) Accompany the combined library with a copy of the same work
 | 
				
			||||||
 | 
					    based on the Library, uncombined with any other library
 | 
				
			||||||
 | 
					    facilities.  This must be distributed under the terms of the
 | 
				
			||||||
 | 
					    Sections above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    b) Give prominent notice with the combined library of the fact
 | 
				
			||||||
 | 
					    that part of it is a work based on the Library, and explaining
 | 
				
			||||||
 | 
					    where to find the accompanying uncombined form of the same work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  8. You may not copy, modify, sublicense, link with, or distribute
 | 
				
			||||||
 | 
					the Library except as expressly provided under this License.  Any
 | 
				
			||||||
 | 
					attempt otherwise to copy, modify, sublicense, link with, or
 | 
				
			||||||
 | 
					distribute the Library is void, and will automatically terminate your
 | 
				
			||||||
 | 
					rights under this License.  However, parties who have received copies,
 | 
				
			||||||
 | 
					or rights, from you under this License will not have their licenses
 | 
				
			||||||
 | 
					terminated so long as such parties remain in full compliance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  9. You are not required to accept this License, since you have not
 | 
				
			||||||
 | 
					signed it.  However, nothing else grants you permission to modify or
 | 
				
			||||||
 | 
					distribute the Library or its derivative works.  These actions are
 | 
				
			||||||
 | 
					prohibited by law if you do not accept this License.  Therefore, by
 | 
				
			||||||
 | 
					modifying or distributing the Library (or any work based on the
 | 
				
			||||||
 | 
					Library), you indicate your acceptance of this License to do so, and
 | 
				
			||||||
 | 
					all its terms and conditions for copying, distributing or modifying
 | 
				
			||||||
 | 
					the Library or works based on it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  10. Each time you redistribute the Library (or any work based on the
 | 
				
			||||||
 | 
					Library), the recipient automatically receives a license from the
 | 
				
			||||||
 | 
					original licensor to copy, distribute, link with or modify the Library
 | 
				
			||||||
 | 
					subject to these terms and conditions.  You may not impose any further
 | 
				
			||||||
 | 
					restrictions on the recipients' exercise of the rights granted herein.
 | 
				
			||||||
 | 
					You are not responsible for enforcing compliance by third parties with
 | 
				
			||||||
 | 
					this License.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					  11. If, as a consequence of a court judgment or allegation of patent
 | 
				
			||||||
 | 
					infringement or for any other reason (not limited to patent issues),
 | 
				
			||||||
 | 
					conditions are imposed on you (whether by court order, agreement or
 | 
				
			||||||
 | 
					otherwise) that contradict the conditions of this License, they do not
 | 
				
			||||||
 | 
					excuse you from the conditions of this License.  If you cannot
 | 
				
			||||||
 | 
					distribute so as to satisfy simultaneously your obligations under this
 | 
				
			||||||
 | 
					License and any other pertinent obligations, then as a consequence you
 | 
				
			||||||
 | 
					may not distribute the Library at all.  For example, if a patent
 | 
				
			||||||
 | 
					license would not permit royalty-free redistribution of the Library by
 | 
				
			||||||
 | 
					all those who receive copies directly or indirectly through you, then
 | 
				
			||||||
 | 
					the only way you could satisfy both it and this License would be to
 | 
				
			||||||
 | 
					refrain entirely from distribution of the Library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If any portion of this section is held invalid or unenforceable under
 | 
				
			||||||
 | 
					any particular circumstance, the balance of the section is intended to
 | 
				
			||||||
 | 
					apply, and the section as a whole is intended to apply in other
 | 
				
			||||||
 | 
					circumstances.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is not the purpose of this section to induce you to infringe any
 | 
				
			||||||
 | 
					patents or other property right claims or to contest validity of any
 | 
				
			||||||
 | 
					such claims; this section has the sole purpose of protecting the
 | 
				
			||||||
 | 
					integrity of the free software distribution system which is
 | 
				
			||||||
 | 
					implemented by public license practices.  Many people have made
 | 
				
			||||||
 | 
					generous contributions to the wide range of software distributed
 | 
				
			||||||
 | 
					through that system in reliance on consistent application of that
 | 
				
			||||||
 | 
					system; it is up to the author/donor to decide if he or she is willing
 | 
				
			||||||
 | 
					to distribute software through any other system and a licensee cannot
 | 
				
			||||||
 | 
					impose that choice.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This section is intended to make thoroughly clear what is believed to
 | 
				
			||||||
 | 
					be a consequence of the rest of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  12. If the distribution and/or use of the Library is restricted in
 | 
				
			||||||
 | 
					certain countries either by patents or by copyrighted interfaces, the
 | 
				
			||||||
 | 
					original copyright holder who places the Library under this License
 | 
				
			||||||
 | 
					may add an explicit geographical distribution limitation excluding those
 | 
				
			||||||
 | 
					countries, so that distribution is permitted only in or among
 | 
				
			||||||
 | 
					countries not thus excluded.  In such case, this License incorporates
 | 
				
			||||||
 | 
					the limitation as if written in the body of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  13. The Free Software Foundation may publish revised and/or new
 | 
				
			||||||
 | 
					versions of the Lesser General Public License from time to time.
 | 
				
			||||||
 | 
					Such new versions will be similar in spirit to the present version,
 | 
				
			||||||
 | 
					but may differ in detail to address new problems or concerns.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each version is given a distinguishing version number.  If the Library
 | 
				
			||||||
 | 
					specifies a version number of this License which applies to it and
 | 
				
			||||||
 | 
					"any later version", you have the option of following the terms and
 | 
				
			||||||
 | 
					conditions either of that version or of any later version published by
 | 
				
			||||||
 | 
					the Free Software Foundation.  If the Library does not specify a
 | 
				
			||||||
 | 
					license version number, you may choose any version ever published by
 | 
				
			||||||
 | 
					the Free Software Foundation.
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					  14. If you wish to incorporate parts of the Library into other free
 | 
				
			||||||
 | 
					programs whose distribution conditions are incompatible with these,
 | 
				
			||||||
 | 
					write to the author to ask for permission.  For software which is
 | 
				
			||||||
 | 
					copyrighted by the Free Software Foundation, write to the Free
 | 
				
			||||||
 | 
					Software Foundation; we sometimes make exceptions for this.  Our
 | 
				
			||||||
 | 
					decision will be guided by the two goals of preserving the free status
 | 
				
			||||||
 | 
					of all derivatives of our free software and of promoting the sharing
 | 
				
			||||||
 | 
					and reuse of software generally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            NO WARRANTY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
 | 
				
			||||||
 | 
					WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
 | 
				
			||||||
 | 
					EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
 | 
				
			||||||
 | 
					OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
 | 
				
			||||||
 | 
					KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
 | 
				
			||||||
 | 
					IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
				
			||||||
 | 
					PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
 | 
				
			||||||
 | 
					LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
 | 
				
			||||||
 | 
					THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
 | 
				
			||||||
 | 
					WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
 | 
				
			||||||
 | 
					AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
 | 
				
			||||||
 | 
					FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
 | 
				
			||||||
 | 
					CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
 | 
				
			||||||
 | 
					LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
 | 
				
			||||||
 | 
					RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
 | 
				
			||||||
 | 
					FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
 | 
				
			||||||
 | 
					SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 | 
				
			||||||
 | 
					DAMAGES.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                     END OF TERMS AND CONDITIONS
 | 
				
			||||||
 | 
					^L
 | 
				
			||||||
 | 
					           How to Apply These Terms to Your New Libraries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  If you develop a new library, and you want it to be of the greatest
 | 
				
			||||||
 | 
					possible use to the public, we recommend making it free software that
 | 
				
			||||||
 | 
					everyone can redistribute and change.  You can do so by permitting
 | 
				
			||||||
 | 
					redistribution under these terms (or, alternatively, under the terms
 | 
				
			||||||
 | 
					of the ordinary General Public License).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  To apply these terms, attach the following notices to the library.
 | 
				
			||||||
 | 
					It is safest to attach them to the start of each source file to most
 | 
				
			||||||
 | 
					effectively convey the exclusion of warranty; and each file should
 | 
				
			||||||
 | 
					have at least the "copyright" line and a pointer to where the full
 | 
				
			||||||
 | 
					notice is found.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <one line to give the library's name and a brief idea of what it does.>
 | 
				
			||||||
 | 
					    Copyright (C) <year>  <name of author>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					    modify it under the terms of the GNU Lesser General Public
 | 
				
			||||||
 | 
					    License as published by the Free Software Foundation; either
 | 
				
			||||||
 | 
					    version 2.1 of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This library is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					    Lesser General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					    License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also add information on how to contact you by electronic and paper mail.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should also get your employer (if you work as a programmer) or
 | 
				
			||||||
 | 
					your school, if any, to sign a "copyright disclaimer" for the library,
 | 
				
			||||||
 | 
					if necessary.  Here is a sample; alter the names:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Yoyodyne, Inc., hereby disclaims all copyright interest in the
 | 
				
			||||||
 | 
					  library `Frob' (a library for tweaking knobs) written by James
 | 
				
			||||||
 | 
					  Random Hacker.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <signature of Ty Coon>, 1 April 1990
 | 
				
			||||||
 | 
					  Ty Coon, President of Vice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					That's all there is to it!
 | 
				
			||||||
							
								
								
									
										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
											
										
									
								
							
							
								
								
									
										759
									
								
								HACKING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										759
									
								
								HACKING
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,759 @@
 | 
				
			|||||||
 | 
					-*- buffer-read-only: t -*- vi: set ro:
 | 
				
			||||||
 | 
					DO NOT EDIT THIS FILE!  IT IS GENERATED AUTOMATICALLY
 | 
				
			||||||
 | 
					from docs/hacking.html.in!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                         Contributor guidelines
 | 
				
			||||||
 | 
					                         ======================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					General tips for contributing patches
 | 
				
			||||||
 | 
					=====================================
 | 
				
			||||||
 | 
					(1) Discuss any large changes on the mailing list first. Post patches early and
 | 
				
			||||||
 | 
					listen to feedback.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(2) Post patches in unified diff format. A command similar to this should work:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  diff -urp libvirt.orig/ libvirt.modified/ > libvirt-myfeature.patch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					or:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  git diff > libvirt-myfeature.patch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, the usual workflow of libvirt developer is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  git checkout master
 | 
				
			||||||
 | 
					  git pull
 | 
				
			||||||
 | 
					  git checkout -t origin -b workbranch
 | 
				
			||||||
 | 
					  Hack, committing any changes along the way
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then, when you want to post your patches:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  git pull --rebase
 | 
				
			||||||
 | 
					  (fix any conflicts)
 | 
				
			||||||
 | 
					  git send-email --cover-letter --no-chain-reply-to --annotate \
 | 
				
			||||||
 | 
					                 --to=libvir-list@redhat.com master
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(Note that the "git send-email" subcommand may not be in the main git package
 | 
				
			||||||
 | 
					and using it may require installion of a separate package, for example the
 | 
				
			||||||
 | 
					"git-email" package in Fedora.) For a single patch you can omit
 | 
				
			||||||
 | 
					"--cover-letter", but a series of two or more patches needs a cover letter. If
 | 
				
			||||||
 | 
					you get tired of typing "--to=libvir-list@redhat.com" designation you can set
 | 
				
			||||||
 | 
					it in git config:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  git config sendemail.to libvir-list@redhat.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please follow this as close as you can, especially the rebase and git
 | 
				
			||||||
 | 
					send-email part, as it makes life easier for other developers to review your
 | 
				
			||||||
 | 
					patch set. One should avoid sending patches as attachments, but rather send
 | 
				
			||||||
 | 
					them in email body along with commit message. If a developer is sending
 | 
				
			||||||
 | 
					another version of the patch (e.g. to address review comments), he is advised
 | 
				
			||||||
 | 
					to note differences to previous versions after the "---" line in the patch so
 | 
				
			||||||
 | 
					that it helps reviewers but doesn't become part of git history. Moreover, such
 | 
				
			||||||
 | 
					patch needs to be prefixed correctly with "--subject-prefix=PATCHv2" appended
 | 
				
			||||||
 | 
					to "git send-email" (substitute "v2" with the correct version if needed
 | 
				
			||||||
 | 
					though).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(3) Split large changes into a series of smaller patches, self-contained if
 | 
				
			||||||
 | 
					possible, with an explanation of each patch and an explanation of how the
 | 
				
			||||||
 | 
					sequence of patches fits together. Moreover, please keep in mind that it's
 | 
				
			||||||
 | 
					required to be able to compile cleanly (*including* "make check" and "make
 | 
				
			||||||
 | 
					syntax-check") after each patch. A feature does not have to work until the end
 | 
				
			||||||
 | 
					of a series, but intermediate patches must compile and not cause test-suite
 | 
				
			||||||
 | 
					failures (this is to preserve the usefulness of "git bisect", among other
 | 
				
			||||||
 | 
					things).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(4) Make sure your patches apply against libvirt GIT. Developers only follow GIT
 | 
				
			||||||
 | 
					and don't care much about released versions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(5) Run the automated tests on your code before submitting any changes. In
 | 
				
			||||||
 | 
					particular, configure with compile warnings set to -Werror. This is done
 | 
				
			||||||
 | 
					automatically for a git checkout; from a tarball, use:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ./configure --enable-werror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and run the tests:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  make check
 | 
				
			||||||
 | 
					  make syntax-check
 | 
				
			||||||
 | 
					  make -C tests valgrind
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The latter test checks for memory leaks.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you encounter any failing tests, the VIR_TEST_DEBUG environment variable
 | 
				
			||||||
 | 
					may provide extra information to debug the failures. Larger values of
 | 
				
			||||||
 | 
					VIR_TEST_DEBUG may provide larger amounts of information:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  VIR_TEST_DEBUG=1 make check    (or)
 | 
				
			||||||
 | 
					  VIR_TEST_DEBUG=2 make check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also, individual tests can be run from inside the "tests/" directory, like:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ./qemuxml2xmltest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(6) Update tests and/or documentation, particularly if you are adding a new
 | 
				
			||||||
 | 
					feature or changing the output of a program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is more on this subject, including lots of links to background reading
 | 
				
			||||||
 | 
					on the subject, on
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Richard Jones' guide to working with open source projects
 | 
				
			||||||
 | 
					  http://et.redhat.com/~rjones/how-to-supply-code-to-open-source-projects/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Code indentation
 | 
				
			||||||
 | 
					================
 | 
				
			||||||
 | 
					Libvirt's C source code generally adheres to some basic code-formatting
 | 
				
			||||||
 | 
					conventions. The existing code base is not totally consistent on this front,
 | 
				
			||||||
 | 
					but we do prefer that contributed code be formatted similarly. In short, use
 | 
				
			||||||
 | 
					spaces-not-TABs for indentation, use 4 spaces for each indentation level, and
 | 
				
			||||||
 | 
					other than that, follow the K&R style.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you use Emacs, add the following to one of one of your start-up files
 | 
				
			||||||
 | 
					(e.g., ~/.emacs), to help ensure that you get indentation right:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ;;; When editing C sources in libvirt, use this style.
 | 
				
			||||||
 | 
					  (defun libvirt-c-mode ()
 | 
				
			||||||
 | 
					    "C mode with adjusted defaults for use with libvirt."
 | 
				
			||||||
 | 
					    (interactive)
 | 
				
			||||||
 | 
					    (c-set-style "K&R")
 | 
				
			||||||
 | 
					    (setq indent-tabs-mode nil) ; indent using spaces, not TABs
 | 
				
			||||||
 | 
					    (setq c-indent-level 4)
 | 
				
			||||||
 | 
					    (setq c-basic-offset 4))
 | 
				
			||||||
 | 
					  (add-hook 'c-mode-hook
 | 
				
			||||||
 | 
					            '(lambda () (if (string-match "/libvirt" (buffer-file-name))
 | 
				
			||||||
 | 
					                            (libvirt-c-mode))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you use vim, append the following to your ~/.vimrc file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  set nocompatible
 | 
				
			||||||
 | 
					  filetype on
 | 
				
			||||||
 | 
					  set autoindent
 | 
				
			||||||
 | 
					  set smartindent
 | 
				
			||||||
 | 
					  set cindent
 | 
				
			||||||
 | 
					  set tabstop=8
 | 
				
			||||||
 | 
					  set shiftwidth=4
 | 
				
			||||||
 | 
					  set expandtab
 | 
				
			||||||
 | 
					  set cinoptions=(0,:0,l1,t0
 | 
				
			||||||
 | 
					  filetype plugin indent on
 | 
				
			||||||
 | 
					  au FileType make setlocal noexpandtab
 | 
				
			||||||
 | 
					  au BufRead,BufNewFile *.am setlocal noexpandtab
 | 
				
			||||||
 | 
					  match ErrorMsg /\s\+$\| \+\ze\t/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Or if you don't want to mess your ~/.vimrc up, you can save the above into a
 | 
				
			||||||
 | 
					file called .lvimrc (not .vimrc) located at the root of libvirt source, then
 | 
				
			||||||
 | 
					install a vim script from
 | 
				
			||||||
 | 
					http://www.vim.org/scripts/script.php?script_id=1408, which will load the
 | 
				
			||||||
 | 
					.lvimrc only when you edit libvirt code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Code formatting (especially for new code)
 | 
				
			||||||
 | 
					=========================================
 | 
				
			||||||
 | 
					With new code, we can be even more strict. Please apply the following function
 | 
				
			||||||
 | 
					(using GNU indent) to any new code. Note that this also gives you an idea of
 | 
				
			||||||
 | 
					the type of spacing we prefer around operators and keywords:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  indent-libvirt()
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    indent -bad -bap -bbb -bli4 -br -ce -brs -cs -i4 -l75 -lc75 \
 | 
				
			||||||
 | 
					      -sbi4 -psl -saf -sai -saw -sbi4 -ss -sc -cdw -cli4 -npcs -nbc \
 | 
				
			||||||
 | 
					      --no-tabs "$@"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that sometimes you'll have to post-process that output further, by piping
 | 
				
			||||||
 | 
					it through "expand -i", since some leading TABs can get through. Usually
 | 
				
			||||||
 | 
					they're in macro definitions or strings, and should be converted anyhow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Libvirt requires a C99 compiler for various reasons. However, most of the code
 | 
				
			||||||
 | 
					base prefers to stick to C89 syntax unless there is a compelling reason
 | 
				
			||||||
 | 
					otherwise. For example, it is preferable to use "/* */" comments rather than
 | 
				
			||||||
 | 
					"//". Also, when declaring local variables, the prevailing style has been to
 | 
				
			||||||
 | 
					declare them at the beginning of a scope, rather than immediately before use.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Curly braces
 | 
				
			||||||
 | 
					============
 | 
				
			||||||
 | 
					Omit the curly braces around an "if", "while", "for" etc. body only when that
 | 
				
			||||||
 | 
					body occupies a single line. In every other case we require the braces. This
 | 
				
			||||||
 | 
					ensures that it is trivially easy to identify a single-'statement' loop: each
 | 
				
			||||||
 | 
					has only one 'line' in its body.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Omitting braces with a single-line body is fine:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (expr) // one-line body -> omitting curly braces is ok
 | 
				
			||||||
 | 
					      single_line_stmt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, the moment your loop/if/else body extends onto a second line, for
 | 
				
			||||||
 | 
					whatever reason (even if it's just an added comment), then you should add
 | 
				
			||||||
 | 
					braces. Otherwise, it would be too easy to insert a statement just before that
 | 
				
			||||||
 | 
					comment (without adding braces), thinking it is already a multi-statement loop:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (true) // BAD! multi-line body with no braces
 | 
				
			||||||
 | 
					      /* comment... */
 | 
				
			||||||
 | 
					      single_line_stmt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Do this instead:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (true) { // Always put braces around a multi-line body.
 | 
				
			||||||
 | 
					      /* comment... */
 | 
				
			||||||
 | 
					      single_line_stmt();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is one exception: when the second body line is not at the same
 | 
				
			||||||
 | 
					indentation level as the first body line:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (expr)
 | 
				
			||||||
 | 
					      die("a diagnostic that would make this line"
 | 
				
			||||||
 | 
					          " extend past the 80-column limit"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is safe to omit the braces in the code above, since the further-indented
 | 
				
			||||||
 | 
					second body line makes it obvious that this is still a single-statement body.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To reiterate, don't do this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (expr)            // BAD: no braces around...
 | 
				
			||||||
 | 
					      while (expr_2) { // ... a multi-line body
 | 
				
			||||||
 | 
					          ...
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Do this, instead:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (expr) {
 | 
				
			||||||
 | 
					      while (expr_2) {
 | 
				
			||||||
 | 
					          ...
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, there is one exception in the other direction, when even a one-line
 | 
				
			||||||
 | 
					block should have braces. That occurs when that one-line, brace-less block is
 | 
				
			||||||
 | 
					an "if" or "else" block, and the counterpart block *does* use braces. In that
 | 
				
			||||||
 | 
					case, put braces around both blocks. Also, if the "else" block is much shorter
 | 
				
			||||||
 | 
					than the "if" block, consider negating the "if"-condition and swapping the
 | 
				
			||||||
 | 
					bodies, putting the short block first and making the longer, multi-line block
 | 
				
			||||||
 | 
					be the "else" block.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (expr) {
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					      x = y;    // BAD: braceless "else" with braced "then",
 | 
				
			||||||
 | 
					                // and short block last
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (expr)
 | 
				
			||||||
 | 
					      x = y;    // BAD: braceless "if" with braced "else"
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Keeping braces consistent and putting the short block first is preferred,
 | 
				
			||||||
 | 
					especially when the multi-line body is more than a few lines long, because it
 | 
				
			||||||
 | 
					is easier to read and grasp the semantics of an if-then-else block when the
 | 
				
			||||||
 | 
					simpler block occurs first, rather than after the more involved block:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!expr) {
 | 
				
			||||||
 | 
					    x = y; // putting the smaller block first is more readable
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					But if negating a complex condition is too ugly, then at least add braces:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (complex expr not worth negating) {
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					      x = y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Preprocessor
 | 
				
			||||||
 | 
					============
 | 
				
			||||||
 | 
					For variadic macros, stick with C99 syntax:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #define vshPrint(_ctl, ...) fprintf(stdout, __VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use parenthesis when checking if a macro is defined, and use indentation to
 | 
				
			||||||
 | 
					track nesting:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #if defined(HAVE_POSIX_FALLOCATE) && !defined(HAVE_FALLOCATE)
 | 
				
			||||||
 | 
					  # define fallocate(a,ignored,b,c) posix_fallocate(a,b,c)
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					C types
 | 
				
			||||||
 | 
					=======
 | 
				
			||||||
 | 
					Use the right type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Scalars
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					- If you're using "int" or "long", odds are good that there's a better type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If a variable is counting something, be sure to declare it with an unsigned
 | 
				
			||||||
 | 
					type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If it's memory-size-related, use "size_t" (use "ssize_t" only if required).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If it's file-size related, use uintmax_t, or maybe "off_t".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If it's file-offset related (i.e., signed), use "off_t".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If it's just counting small numbers use "unsigned int"; (on all but oddball
 | 
				
			||||||
 | 
					embedded systems, you can assume that that type is at least four bytes wide).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If a variable has boolean semantics, give it the "bool" type and use the
 | 
				
			||||||
 | 
					corresponding "true" and "false" macros. It's ok to include <stdbool.h>, since
 | 
				
			||||||
 | 
					libvirt's use of gnulib ensures that it exists and is usable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- In the unusual event that you require a specific width, use a standard type
 | 
				
			||||||
 | 
					like "int32_t", "uint32_t", "uint64_t", etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- While using "bool" is good for readability, it comes with minor caveats:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Don't use "bool" in places where the type size must be constant across all
 | 
				
			||||||
 | 
					systems, like public interfaces and on-the-wire protocols. Note that it would
 | 
				
			||||||
 | 
					be possible (albeit wasteful) to use "bool" in libvirt's logical wire
 | 
				
			||||||
 | 
					protocol, since XDR maps that to its lower-level "bool_t" type, which *is*
 | 
				
			||||||
 | 
					fixed-size.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Don't compare a bool variable against the literal, "true", since a value with
 | 
				
			||||||
 | 
					a logical non-false value need not be "1". I.e., don't write "if (seen ==
 | 
				
			||||||
 | 
					true) ...". Rather, write "if (seen)...".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Of course, take all of the above with a grain of salt. If you're about to use
 | 
				
			||||||
 | 
					some system interface that requires a type like "size_t", "pid_t" or "off_t",
 | 
				
			||||||
 | 
					use matching types for any corresponding variables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also, if you try to use e.g., "unsigned int" as a type, and that conflicts
 | 
				
			||||||
 | 
					with the signedness of a related variable, sometimes it's best just to use the
 | 
				
			||||||
 | 
					*wrong* type, if 'pulling the thread' and fixing all related variables would
 | 
				
			||||||
 | 
					be too invasive.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally, while using descriptive types is important, be careful not to go
 | 
				
			||||||
 | 
					overboard. If whatever you're doing causes warnings, or requires casts, then
 | 
				
			||||||
 | 
					reconsider or ask for help.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pointers
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					Ensure that all of your pointers are 'const-correct'. Unless a pointer is used
 | 
				
			||||||
 | 
					to modify the pointed-to storage, give it the "const" attribute. That way, the
 | 
				
			||||||
 | 
					reader knows up-front that this is a read-only pointer. Perhaps more
 | 
				
			||||||
 | 
					importantly, if we're diligent about this, when you see a non-const pointer,
 | 
				
			||||||
 | 
					you're guaranteed that it is used to modify the storage it points to, or it is
 | 
				
			||||||
 | 
					aliased to another pointer that is.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Low level memory management
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					Use of the malloc/free/realloc/calloc APIs is deprecated in the libvirt
 | 
				
			||||||
 | 
					codebase, because they encourage a number of serious coding bugs and do not
 | 
				
			||||||
 | 
					enable compile time verification of checks for NULL. Instead of these
 | 
				
			||||||
 | 
					routines, use the macros from memory.h.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To allocate a single object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_ALLOC(domain) < 0) {
 | 
				
			||||||
 | 
					      virReportOOMError();
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To allocate an array of objects:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr domains;
 | 
				
			||||||
 | 
					  size_t ndomains = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_ALLOC_N(domains, ndomains) < 0) {
 | 
				
			||||||
 | 
					      virReportOOMError();
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To allocate an array of object pointers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr *domains;
 | 
				
			||||||
 | 
					  size_t ndomains = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_ALLOC_N(domains, ndomains) < 0) {
 | 
				
			||||||
 | 
					      virReportOOMError();
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To re-allocate the array of domains to be 1 element longer (however, note that
 | 
				
			||||||
 | 
					repeatedly expanding an array by 1 scales quadratically, so this is
 | 
				
			||||||
 | 
					recommended only for smaller arrays):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr domains;
 | 
				
			||||||
 | 
					  size_t ndomains = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_EXPAND_N(domains, ndomains, 1) < 0) {
 | 
				
			||||||
 | 
					      virReportOOMError();
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  domains[ndomains - 1] = domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To ensure an array has room to hold at least one more element (this approach
 | 
				
			||||||
 | 
					scales better, but requires tracking allocation separately from usage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr domains;
 | 
				
			||||||
 | 
					  size_t ndomains = 0;
 | 
				
			||||||
 | 
					  size_t ndomains_max = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_RESIZE_N(domains, ndomains_max, ndomains, 1) < 0) {
 | 
				
			||||||
 | 
					      virReportOOMError();
 | 
				
			||||||
 | 
					      return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  domains[ndomains++] = domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To trim an array of domains from its allocated size down to the actual used
 | 
				
			||||||
 | 
					size:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr domains;
 | 
				
			||||||
 | 
					  size_t ndomains = x;
 | 
				
			||||||
 | 
					  size_t ndomains_max = y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  VIR_SHRINK_N(domains, ndomains_max, ndomains_max - ndomains);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To free an array of domains:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virDomainPtr domains;
 | 
				
			||||||
 | 
					  size_t ndomains = x;
 | 
				
			||||||
 | 
					  size_t ndomains_max = y;
 | 
				
			||||||
 | 
					  size_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (i = 0; i < ndomains; i++)
 | 
				
			||||||
 | 
					      VIR_FREE(domains[i]);
 | 
				
			||||||
 | 
					  VIR_FREE(domains);
 | 
				
			||||||
 | 
					  ndomains_max = ndomains = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					File handling
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					Usage of the "fdopen()", "close()", "fclose()" APIs is deprecated in libvirt
 | 
				
			||||||
 | 
					code base to help avoiding double-closing of files or file descriptors, which
 | 
				
			||||||
 | 
					is particulary dangerous in a multi-threaded applications. Instead of these
 | 
				
			||||||
 | 
					APIs, use the macros from virfile.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Open a file from a file descriptor:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((file = VIR_FDOPEN(fd, "r")) == NULL) {
 | 
				
			||||||
 | 
					      virReportSystemError(errno, "%s",
 | 
				
			||||||
 | 
					                           _("failed to open file from file descriptor"));
 | 
				
			||||||
 | 
					      return -1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  /* fd is now invalid; only access the file using file variable */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Close a file descriptor:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_CLOSE(fd) < 0) {
 | 
				
			||||||
 | 
					      virReportSystemError(errno, "%s", _("failed to close file"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Close a file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (VIR_FCLOSE(file) < 0) {
 | 
				
			||||||
 | 
					      virReportSystemError(errno, "%s", _("failed to close file"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Close a file or file descriptor in an error path, without losing the previous
 | 
				
			||||||
 | 
					"errno" value:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  VIR_FORCE_CLOSE(fd);
 | 
				
			||||||
 | 
					  VIR_FORCE_FCLOSE(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					String comparisons
 | 
				
			||||||
 | 
					==================
 | 
				
			||||||
 | 
					Do not use the strcmp, strncmp, etc functions directly. Instead use one of the
 | 
				
			||||||
 | 
					following semantically named macros
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For strict equality:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  STREQ(a,b)
 | 
				
			||||||
 | 
					  STRNEQ(a,b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For case insensitive equality:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  STRCASEEQ(a,b)
 | 
				
			||||||
 | 
					  STRCASENEQ(a,b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For strict equality of a substring:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  STREQLEN(a,b,n)
 | 
				
			||||||
 | 
					  STRNEQLEN(a,b,n)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For case insensitive equality of a substring:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  STRCASEEQLEN(a,b,n)
 | 
				
			||||||
 | 
					  STRCASENEQLEN(a,b,n)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For strict equality of a prefix:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  STRPREFIX(a,b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- To avoid having to check if a or b are NULL:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  STREQ_NULLABLE(a, b)
 | 
				
			||||||
 | 
					  STRNEQ_NULLABLE(a, b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					String copying
 | 
				
			||||||
 | 
					==============
 | 
				
			||||||
 | 
					Do not use the strncpy function. According to the man page, it does *not*
 | 
				
			||||||
 | 
					guarantee a NULL-terminated buffer, which makes it extremely dangerous to use.
 | 
				
			||||||
 | 
					Instead, use one of the functionally equivalent functions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The first three arguments have the same meaning as for strncpy; namely the
 | 
				
			||||||
 | 
					destination, source, and number of bytes to copy, respectively. The last
 | 
				
			||||||
 | 
					argument is the number of bytes available in the destination string; if a copy
 | 
				
			||||||
 | 
					of the source string (including a \0) will not fit into the destination, no
 | 
				
			||||||
 | 
					bytes are copied and the routine returns NULL. Otherwise, n bytes from the
 | 
				
			||||||
 | 
					source are copied into the destination and a trailing \0 is appended.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virStrcpy(char *dest, const char *src, size_t destbytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use this variant if you know you want to copy the entire src string into dest.
 | 
				
			||||||
 | 
					Note that this is a macro, so arguments could be evaluated more than once.
 | 
				
			||||||
 | 
					This is equivalent to virStrncpy(dest, src, strlen(src), destbytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virStrcpyStatic(char *dest, const char *src)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use this variant if you know you want to copy the entire src string into dest
 | 
				
			||||||
 | 
					*and* you know that your destination string is a static string (i.e. that
 | 
				
			||||||
 | 
					sizeof(dest) returns something meaningful). Note that this is a macro, so
 | 
				
			||||||
 | 
					arguments could be evaluated more than once. This is equivalent to
 | 
				
			||||||
 | 
					virStrncpy(dest, src, strlen(src), sizeof(dest)).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Variable length string buffer
 | 
				
			||||||
 | 
					=============================
 | 
				
			||||||
 | 
					If there is a need for complex string concatenations, avoid using the usual
 | 
				
			||||||
 | 
					sequence of malloc/strcpy/strcat/snprintf functions and make use of the
 | 
				
			||||||
 | 
					virBuffer API described in buf.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Typical usage is as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char *
 | 
				
			||||||
 | 
					  somefunction(...)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					     virBuffer buf = VIR_BUFFER_INITIALIZER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     virBufferAddLit(&buf, "<domain>\n");
 | 
				
			||||||
 | 
					     virBufferAsprintf(&buf, "  <memory>%d</memory>\n", memory);
 | 
				
			||||||
 | 
					     ...
 | 
				
			||||||
 | 
					     virBufferAddLit(&buf, "</domain>\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     if (virBufferError(&buf)) {
 | 
				
			||||||
 | 
					         virBufferFreeAndReset(&buf);
 | 
				
			||||||
 | 
					         virReportOOMError();
 | 
				
			||||||
 | 
					         return NULL;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     return virBufferContentAndReset(&buf);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Include files
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					There are now quite a large number of include files, both libvirt internal and
 | 
				
			||||||
 | 
					external, and system includes. To manage all this complexity it's best to
 | 
				
			||||||
 | 
					stick to the following general plan for all *.c source files:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Copyright notice
 | 
				
			||||||
 | 
					   * ....
 | 
				
			||||||
 | 
					   * ....
 | 
				
			||||||
 | 
					   * ....
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #include <config.h>             Must come first in every file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #include <stdio.h>              Any system includes you need.
 | 
				
			||||||
 | 
					  #include <string.h>
 | 
				
			||||||
 | 
					  #include <limits.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #if HAVE_NUMACTL                Some system includes aren't supported
 | 
				
			||||||
 | 
					  # include <numa.h>              everywhere so need these #if guards.
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #include "internal.h"           Include this first, after system includes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #include "util.h"               Any libvirt internal header files.
 | 
				
			||||||
 | 
					  #include "buf.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static int
 | 
				
			||||||
 | 
					  myInternalFunc()                The actual code.
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					      ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Of particular note: *Do not* include libvirt/libvirt.h or libvirt/virterror.h.
 | 
				
			||||||
 | 
					It is included by "internal.h" already and there are some special reasons why
 | 
				
			||||||
 | 
					you cannot include these files explicitly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Printf-style functions
 | 
				
			||||||
 | 
					======================
 | 
				
			||||||
 | 
					Whenever you add a new printf-style function, i.e., one with a format string
 | 
				
			||||||
 | 
					argument and following "..." in its prototype, be sure to use gcc's printf
 | 
				
			||||||
 | 
					attribute directive in the prototype. For example, here's the one for
 | 
				
			||||||
 | 
					virAsprintf, in util.h:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int virAsprintf(char **strp, const char *fmt, ...)
 | 
				
			||||||
 | 
					      ATTRIBUTE_FORMAT(printf, 2, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This makes it so gcc's -Wformat and -Wformat-security options can do their
 | 
				
			||||||
 | 
					jobs and cross-check format strings with the number and types of arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When printing to a string, consider using virBuffer for incremental
 | 
				
			||||||
 | 
					allocations, virAsprintf for a one-shot allocation, and snprintf for
 | 
				
			||||||
 | 
					fixed-width buffers. Do not use sprintf, even if you can prove the buffer
 | 
				
			||||||
 | 
					won't overflow, since gnulib does not provide the same portability guarantees
 | 
				
			||||||
 | 
					for sprintf as it does for snprintf.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use of goto
 | 
				
			||||||
 | 
					===========
 | 
				
			||||||
 | 
					The use of goto is not forbidden, and goto is widely used throughout libvirt.
 | 
				
			||||||
 | 
					While the uncontrolled use of goto will quickly lead to unmaintainable code,
 | 
				
			||||||
 | 
					there is a place for it in well structured code where its use increases
 | 
				
			||||||
 | 
					readability and maintainability. In general, if goto is used for error
 | 
				
			||||||
 | 
					recovery, it's likely to be ok, otherwise, be cautious or avoid it all
 | 
				
			||||||
 | 
					together.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The typical use of goto is to jump to cleanup code in the case of a long list
 | 
				
			||||||
 | 
					of actions, any of which may fail and cause the entire operation to fail. In
 | 
				
			||||||
 | 
					this case, a function will have a single label at the end of the function.
 | 
				
			||||||
 | 
					It's almost always ok to use this style. In particular, if the cleanup code
 | 
				
			||||||
 | 
					only involves free'ing memory, then having multiple labels is overkill.
 | 
				
			||||||
 | 
					VIR_FREE() and every function named XXXFree() in libvirt is required to handle
 | 
				
			||||||
 | 
					NULL as its arg. Thus you can safely call free on all the variables even if
 | 
				
			||||||
 | 
					they were not yet allocated (yes they have to have been initialized to NULL).
 | 
				
			||||||
 | 
					This is much simpler and clearer than having multiple labels.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are a couple of signs that a particular use of goto is not ok:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- You're using multiple labels. If you find yourself using multiple labels,
 | 
				
			||||||
 | 
					you're strongly encouraged to rework your code to eliminate all but one of
 | 
				
			||||||
 | 
					them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- The goto jumps back up to a point above the current line of code being
 | 
				
			||||||
 | 
					executed. Please use some combination of looping constructs to re-execute code
 | 
				
			||||||
 | 
					instead; it's almost certainly going to be more understandable by others. One
 | 
				
			||||||
 | 
					well-known exception to this rule is restarting an i/o operation following
 | 
				
			||||||
 | 
					EINTR.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- The goto jumps down to an arbitrary place in the middle of a function followed
 | 
				
			||||||
 | 
					by further potentially failing calls. You should almost certainly be using a
 | 
				
			||||||
 | 
					conditional and a block instead of a goto. Perhaps some of your function's
 | 
				
			||||||
 | 
					logic would be better pulled out into a helper function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Although libvirt does not encourage the Linux kernel wind/unwind style of
 | 
				
			||||||
 | 
					multiple labels, there's a good general discussion of the issue archived at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  KernelTrap
 | 
				
			||||||
 | 
					  http://kerneltrap.org/node/553/2131
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When using goto, please use one of these standard labels if it makes sense:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      error: A path only taken upon return with an error code
 | 
				
			||||||
 | 
					    cleanup: A path taken upon return with success code + optional error
 | 
				
			||||||
 | 
					  no_memory: A path only taken upon return with an OOM error code
 | 
				
			||||||
 | 
					      retry: If needing to jump upwards (e.g., retry on EINTR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Libvirt committer guidelines
 | 
				
			||||||
 | 
					============================
 | 
				
			||||||
 | 
					The AUTHORS files indicates the list of people with commit access right who
 | 
				
			||||||
 | 
					can actually merge the patches.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The general rule for committing a patch is to make sure it has been reviewed
 | 
				
			||||||
 | 
					properly in the mailing-list first, usually if a couple of people gave an ACK
 | 
				
			||||||
 | 
					or +1 to a patch and nobody raised an objection on the list it should be good
 | 
				
			||||||
 | 
					to go. If the patch touches a part of the code where you're not the main
 | 
				
			||||||
 | 
					maintainer, or where you do not have a very clear idea of how things work,
 | 
				
			||||||
 | 
					it's better to wait for a more authoritative feedback though. Before
 | 
				
			||||||
 | 
					committing, please also rebuild locally, run 'make check syntax-check', and
 | 
				
			||||||
 | 
					make sure you don't raise errors. Try to look for warnings too; for example,
 | 
				
			||||||
 | 
					configure with
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  --enable-compile-warnings=error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					which adds -Werror to compile flags, so no warnings get missed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An exception to 'review and approval on the list first' is fixing failures to
 | 
				
			||||||
 | 
					build:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- if a recently committed patch breaks compilation on a platform or for a given
 | 
				
			||||||
 | 
					driver, then it's fine to commit a minimal fix directly without getting the
 | 
				
			||||||
 | 
					review feedback first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- if make check or make syntax-check breaks, if there is an obvious fix, it's
 | 
				
			||||||
 | 
					fine to commit immediately. The patch should still be sent to the list (or
 | 
				
			||||||
 | 
					tell what the fix was if trivial), and 'make check syntax-check' should pass
 | 
				
			||||||
 | 
					too, before committing anything
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- fixes for documentation and code comments can be managed in the same way, but
 | 
				
			||||||
 | 
					still make sure they get reviewed if non-trivial.
 | 
				
			||||||
							
								
								
									
										153
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,112 +1,103 @@
 | 
				
			|||||||
## Process this file with automake to produce Makefile.in
 | 
					## Process this file with automake to produce Makefile.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Copyright (C) 2005-2013 Red Hat, Inc.
 | 
					## Copyright (C) 2005-2011 Red Hat, Inc.
 | 
				
			||||||
##
 | 
					## See COPYING.LIB for the License of this software
 | 
				
			||||||
## 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/>.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
SUBDIRS = . gnulib/lib include/libvirt src tools docs gnulib/tests \
 | 
					LCOV = lcov
 | 
				
			||||||
  tests po examples
 | 
					GENHTML = genhtml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
XZ_OPT ?= -v -T0
 | 
					SUBDIRS = gnulib/lib include src daemon tools docs gnulib/tests \
 | 
				
			||||||
export XZ_OPT
 | 
					  python tests po examples/domain-events/events-c examples/hellolibvirt \
 | 
				
			||||||
 | 
					  examples/dominfo examples/domsuspend examples/python examples/apparmor \
 | 
				
			||||||
 | 
					  examples/xml/nwfilter examples/openauth examples/systemtap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# have gnulib 'make coverage' output to 'cov' dir
 | 
					ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
 | 
				
			||||||
COVERAGE_OUT = "cov"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ACLOCAL_AMFLAGS = -I m4
 | 
					XML_EXAMPLES = \
 | 
				
			||||||
 | 
					  $(patsubst $(srcdir)/%,%,$(wildcard $(addprefix $(srcdir)/examples/xml/, \
 | 
				
			||||||
 | 
										test/*.xml storage/*.xml)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXTRA_DIST = \
 | 
					EXTRA_DIST = \
 | 
				
			||||||
  config-post.h \
 | 
					  ChangeLog-old \
 | 
				
			||||||
  libvirt.spec libvirt.spec.in \
 | 
					  libvirt.spec libvirt.spec.in \
 | 
				
			||||||
  mingw-libvirt.spec.in \
 | 
					  mingw-libvirt.spec.in \
 | 
				
			||||||
  libvirt.pc.in \
 | 
					  libvirt.pc.in \
 | 
				
			||||||
  libvirt-qemu.pc.in \
 | 
					  autobuild.sh \
 | 
				
			||||||
  libvirt-lxc.pc.in \
 | 
					 | 
				
			||||||
  libvirt-admin.pc.in \
 | 
					 | 
				
			||||||
  Makefile.ci \
 | 
					 | 
				
			||||||
  Makefile.nonreentrant \
 | 
					  Makefile.nonreentrant \
 | 
				
			||||||
  autogen.sh \
 | 
					  autogen.sh \
 | 
				
			||||||
  cfg.mk \
 | 
					  cfg.mk \
 | 
				
			||||||
 | 
					  examples/domain-events/events-python \
 | 
				
			||||||
  run.in \
 | 
					  run.in \
 | 
				
			||||||
  README.md \
 | 
					 | 
				
			||||||
  AUTHORS.in \
 | 
					  AUTHORS.in \
 | 
				
			||||||
  build-aux/augeas-gentest.pl \
 | 
					  $(XML_EXAMPLES)
 | 
				
			||||||
  build-aux/check-spacing.pl \
 | 
					 | 
				
			||||||
  build-aux/gitlog-to-changelog \
 | 
					 | 
				
			||||||
  build-aux/header-ifdef.pl \
 | 
					 | 
				
			||||||
  build-aux/minimize-po.pl \
 | 
					 | 
				
			||||||
  build-aux/mock-noinline.pl \
 | 
					 | 
				
			||||||
  build-aux/prohibit-duplicate-header.pl \
 | 
					 | 
				
			||||||
  build-aux/useless-if-before-free \
 | 
					 | 
				
			||||||
  build-aux/vc-list-files \
 | 
					 | 
				
			||||||
  $(NULL)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
					pkgconfigdir = $(libdir)/pkgconfig
 | 
				
			||||||
pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc libvirt-admin.pc
 | 
					pkgconfig_DATA = libvirt.pc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NEWS: \
 | 
					NEWS: $(top_srcdir)/docs/news.xsl $(top_srcdir)/docs/news.html.in
 | 
				
			||||||
	  $(srcdir)/docs/news.xml \
 | 
						-@(if [ -x $(XSLTPROC) ] ; then				\
 | 
				
			||||||
	  $(srcdir)/docs/news-ascii.xsl \
 | 
						  $(XSLTPROC) --nonet $(top_srcdir)/docs/news.xsl	\
 | 
				
			||||||
	  $(srcdir)/docs/reformat-news.py
 | 
						     $(top_srcdir)/docs/news.html.in			\
 | 
				
			||||||
	$(AM_V_GEN) \
 | 
						   | perl -0777 -pe 's/\n\n+$$/\n/'			\
 | 
				
			||||||
	if [ -x $(XSLTPROC) ]; then \
 | 
						   | perl -pe 's/[ \t]+$$//'				\
 | 
				
			||||||
	  $(XSLTPROC) --nonet \
 | 
						   > $@-t && mv $@-t $@ ; fi );
 | 
				
			||||||
	    $(srcdir)/docs/news-ascii.xsl \
 | 
					
 | 
				
			||||||
	    $(srcdir)/docs/news.xml \
 | 
					$(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl $(top_srcdir)/docs/hacking2.xsl \
 | 
				
			||||||
	  >$@-tmp \
 | 
					                       $(top_srcdir)/docs/wrapstring.xsl $(top_srcdir)/docs/hacking.html.in
 | 
				
			||||||
	    || { rm -f $@-tmp; exit 1; }; \
 | 
						-@(if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
	  $(PYTHON) $(srcdir)/docs/reformat-news.py $@-tmp >$@ \
 | 
						   $(XSLTPROC) --nonet $(top_srcdir)/docs/hacking1.xsl $(top_srcdir)/docs/hacking.html.in | \
 | 
				
			||||||
	    || { rm -f $@-tmp; exit 1; }; \
 | 
						   $(XSLTPROC) --nonet $(top_srcdir)/docs/hacking2.xsl - \
 | 
				
			||||||
	  rm -f $@-tmp; \
 | 
						   | perl -0777 -pe 's/\n\n+$$/\n/' \
 | 
				
			||||||
	fi
 | 
						   > $@-t && mv $@-t $@ ; fi );
 | 
				
			||||||
EXTRA_DIST += \
 | 
					 | 
				
			||||||
	$(srcdir)/docs/news.xml \
 | 
					 | 
				
			||||||
	$(srcdir)/docs/news-ascii.xsl \
 | 
					 | 
				
			||||||
	$(srcdir)/docs/reformat-news.py
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
rpm: clean
 | 
					rpm: clean
 | 
				
			||||||
	@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.xz)
 | 
						@(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz)
 | 
				
			||||||
 | 
					 | 
				
			||||||
srpm: clean
 | 
					 | 
				
			||||||
	@(unset CDPATH ; $(MAKE) dist && rpmbuild -ts $(distdir).tar.xz)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
check-local: all tests
 | 
					check-local: all tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check-access: all
 | 
					tests:
 | 
				
			||||||
	@($(MAKE) $(AM_MAKEFLAGS) -C tests check-access)
 | 
						@(cd docs/examples ; $(MAKE) MAKEFLAGS+=--silent tests)
 | 
				
			||||||
 | 
						@(if [ "$(pythondir)" != "" ] ; then cd python ; \
 | 
				
			||||||
 | 
						  $(MAKE) MAKEFLAGS+=--silent tests ; fi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cov: clean-cov
 | 
				
			||||||
 | 
						mkdir $(top_builddir)/coverage
 | 
				
			||||||
 | 
						$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp \
 | 
				
			||||||
 | 
						  -d $(top_builddir)/src  -d $(top_builddir)/daemon \
 | 
				
			||||||
 | 
						  -d $(top_builddir)/tests
 | 
				
			||||||
 | 
						$(LCOV) -r $(top_builddir)/coverage/libvirt.info.tmp \
 | 
				
			||||||
 | 
						  -o $(top_builddir)/coverage/libvirt.info
 | 
				
			||||||
 | 
						rm $(top_builddir)/coverage/libvirt.info.tmp
 | 
				
			||||||
 | 
						$(GENHTML) --show-details -t "libvirt" -o $(top_builddir)/coverage \
 | 
				
			||||||
 | 
						  --legend $(top_builddir)/coverage/libvirt.info
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean-cov:
 | 
				
			||||||
 | 
						rm -rf $(top_builddir)/coverage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MAINTAINERCLEANFILES = .git-module-status
 | 
					MAINTAINERCLEANFILES = .git-module-status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dist-hook: gen-AUTHORS
 | 
					# disable this check
 | 
				
			||||||
 | 
					distuninstallcheck:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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:
 | 
				
			||||||
 | 
						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
 | 
					.PHONY: gen-AUTHORS
 | 
				
			||||||
gen-AUTHORS:
 | 
					gen-AUTHORS:
 | 
				
			||||||
	$(AM_V_GEN)\
 | 
						if test -d .git; then \
 | 
				
			||||||
	if test -d $(srcdir)/.git; then \
 | 
						    out="`git log --pretty=format:'%aN <%aE>' | sort -u`" && \
 | 
				
			||||||
	  ( \
 | 
						    cat $(srcdir)/AUTHORS.in | perl -p -e "s/#authorslist#/$$out/" > \
 | 
				
			||||||
	    cd $(srcdir) && \
 | 
						      $(distdir)/AUTHORS-tmp && \
 | 
				
			||||||
	    git log --pretty=format:'%aN <%aE>' | sort -u \
 | 
						    mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS ; \
 | 
				
			||||||
	  ) > 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; \
 | 
					 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					 | 
				
			||||||
ci-%:
 | 
					 | 
				
			||||||
	$(MAKE) -f Makefile.ci $@
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										269
									
								
								Makefile.ci
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								Makefile.ci
									
									
									
									
									
								
							@@ -1,269 +0,0 @@
 | 
				
			|||||||
# -*- makefile -*-
 | 
					 | 
				
			||||||
# vim: filetype=make
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Figure out name and path to this file. This isn't
 | 
					 | 
				
			||||||
# portable but we only care for modern GNU make
 | 
					 | 
				
			||||||
CI_MAKEFILE = $(abspath $(firstword $(MAKEFILE_LIST)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The directory holding content on the host that we will
 | 
					 | 
				
			||||||
# expose to the container.
 | 
					 | 
				
			||||||
CI_SCRATCHDIR = $(shell pwd)/ci-tree
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The root directory of the libvirt.git checkout
 | 
					 | 
				
			||||||
CI_GIT_ROOT = $(shell git rev-parse --show-toplevel)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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 = /src
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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 =
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Avoid pulling submodules over the network by locally
 | 
					 | 
				
			||||||
# cloning them
 | 
					 | 
				
			||||||
CI_SUBMODULES = $(shell git submodule | awk '{ print $$2 }')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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-
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The default tag is ':latest' but if the container
 | 
					 | 
				
			||||||
# repo above uses different conventions this can override it
 | 
					 | 
				
			||||||
CI_IMAGE_TAG = :master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 error-prone.
 | 
					 | 
				
			||||||
CI_PWDB_MOUNTS = \
 | 
					 | 
				
			||||||
	--volume $(CI_SCRATCHDIR)/group:/etc/group:ro,z \
 | 
					 | 
				
			||||||
	--volume $(CI_SCRATCHDIR)/passwd:/etc/passwd:ro,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 ther eneeds to be some math 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/^$USER:[^:]\+://p" /etc/subuid)
 | 
					 | 
				
			||||||
	CI_MAX_GID = $(shell sed -n "s/^$USER:[^:]\+://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
 | 
					 | 
				
			||||||
#   --workdir to set cwd to vpath build location
 | 
					 | 
				
			||||||
#   --ulimit  lower files limit for performance reasons
 | 
					 | 
				
			||||||
#   --interactive
 | 
					 | 
				
			||||||
#   --tty     Ensure we have ability to Ctrl-C the build
 | 
					 | 
				
			||||||
CI_ENGINE_ARGS = \
 | 
					 | 
				
			||||||
	--rm \
 | 
					 | 
				
			||||||
	--user $(CI_UID):$(CI_GID) \
 | 
					 | 
				
			||||||
	--interactive \
 | 
					 | 
				
			||||||
	--tty \
 | 
					 | 
				
			||||||
	$(CI_PODMAN_ARGS) \
 | 
					 | 
				
			||||||
	$(CI_PWDB_MOUNTS) \
 | 
					 | 
				
			||||||
	--volume $(CI_HOST_SRCDIR):$(CI_CONT_SRCDIR):z \
 | 
					 | 
				
			||||||
	--workdir $(CI_CONT_SRCDIR) \
 | 
					 | 
				
			||||||
	--ulimit nofile=$(CI_ULIMIT_FILES):$(CI_ULIMIT_FILES) \
 | 
					 | 
				
			||||||
	$(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); \
 | 
					 | 
				
			||||||
		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 $(CI_SUBMODULES) ; \
 | 
					 | 
				
			||||||
		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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# $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)
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# gl_public_submodule_commit= to disable gnulib's submodule check
 | 
					 | 
				
			||||||
# which breaks due to way we clone the submodules
 | 
					 | 
				
			||||||
ci-build@%: ci-prepare-tree
 | 
					 | 
				
			||||||
	$(CI_ENGINE) run $(CI_ENGINE_ARGS) $(CI_IMAGE_PREFIX)$*$(CI_IMAGE_TAG) \
 | 
					 | 
				
			||||||
		/bin/bash -c '\
 | 
					 | 
				
			||||||
		mkdir -p $(CI_CONT_BUILDDIR) || exit 1 ; \
 | 
					 | 
				
			||||||
		cd $(CI_CONT_BUILDDIR) ; \
 | 
					 | 
				
			||||||
		NOCONFIGURE=1 $(CI_CONT_SRCDIR)/autogen.sh || exit 1 ; \
 | 
					 | 
				
			||||||
		$(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 ; \
 | 
					 | 
				
			||||||
		export VIR_TEST_DEBUG=1 ; \
 | 
					 | 
				
			||||||
		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'
 | 
					 | 
				
			||||||
	@test "$(CI_CLEAN)" = "1" && rm -rf $(CI_SCRATCHDIR) || :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ci-check@%:
 | 
					 | 
				
			||||||
	$(MAKE) -f $(CI_MAKEFILE) ci-build@$* CI_MAKE_ARGS="check"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ci-shell@%: ci-prepare-tree
 | 
					 | 
				
			||||||
	$(CI_ENGINE) run $(CI_ENGINE_ARGS) $(CI_IMAGE_PREFIX)$*$(CI_IMAGE_TAG) /bin/bash
 | 
					 | 
				
			||||||
	@test "$(CI_CLEAN)" = "1" && rm -rf $(CI_SCRATCHDIR) || :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
	@echo "Available x86 container images:"
 | 
					 | 
				
			||||||
	@echo
 | 
					 | 
				
			||||||
	@echo "    centos-7"
 | 
					 | 
				
			||||||
	@echo "    debian-9"
 | 
					 | 
				
			||||||
	@echo "    debian-sid"
 | 
					 | 
				
			||||||
	@echo "    fedora-28"
 | 
					 | 
				
			||||||
	@echo "    fedora-29"
 | 
					 | 
				
			||||||
	@echo "    fedora-rawhide"
 | 
					 | 
				
			||||||
	@echo "    ubuntu-18"
 | 
					 | 
				
			||||||
	@echo
 | 
					 | 
				
			||||||
	@echo "Available cross-compiler container images:"
 | 
					 | 
				
			||||||
	@echo
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-aarch64"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-armv6l"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-armv7l"
 | 
					 | 
				
			||||||
	@echo "    debian-sid-cross-i686"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-mips64el"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-mips"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-mipsel"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-ppc64le"
 | 
					 | 
				
			||||||
	@echo "    debian-{9,sid}-cross-s390x"
 | 
					 | 
				
			||||||
	@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
 | 
					 | 
				
			||||||
@@ -1,23 +1,8 @@
 | 
				
			|||||||
## Copyright (C) 2009-2010, 2013 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/>.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 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$' \
 | 
					#      | grep '_r$' \
 | 
				
			||||||
#      | awk '{print $3}' \
 | 
					#      | awk '{print $3}' \
 | 
				
			||||||
#      | grep -v __ \
 | 
					#      | grep -v __ \
 | 
				
			||||||
@@ -43,7 +28,6 @@ NON_REENTRANT += ether_ntoa
 | 
				
			|||||||
NON_REENTRANT += fcvt
 | 
					NON_REENTRANT += fcvt
 | 
				
			||||||
NON_REENTRANT += fgetgrent
 | 
					NON_REENTRANT += fgetgrent
 | 
				
			||||||
NON_REENTRANT += fgetpwent
 | 
					NON_REENTRANT += fgetpwent
 | 
				
			||||||
NON_REENTRANT += fgetsgent
 | 
					 | 
				
			||||||
NON_REENTRANT += fgetspent
 | 
					NON_REENTRANT += fgetspent
 | 
				
			||||||
NON_REENTRANT += getaliasbyname
 | 
					NON_REENTRANT += getaliasbyname
 | 
				
			||||||
NON_REENTRANT += getaliasent
 | 
					NON_REENTRANT += getaliasent
 | 
				
			||||||
@@ -73,8 +57,6 @@ NON_REENTRANT += getrpcent
 | 
				
			|||||||
NON_REENTRANT += getservbyname
 | 
					NON_REENTRANT += getservbyname
 | 
				
			||||||
NON_REENTRANT += getservbyport
 | 
					NON_REENTRANT += getservbyport
 | 
				
			||||||
NON_REENTRANT += getservent
 | 
					NON_REENTRANT += getservent
 | 
				
			||||||
NON_REENTRANT += getsgent
 | 
					 | 
				
			||||||
NON_REENTRANT += getsgnam
 | 
					 | 
				
			||||||
NON_REENTRANT += getspent
 | 
					NON_REENTRANT += getspent
 | 
				
			||||||
NON_REENTRANT += getspnam
 | 
					NON_REENTRANT += getspnam
 | 
				
			||||||
NON_REENTRANT += getutent
 | 
					NON_REENTRANT += getutent
 | 
				
			||||||
@@ -98,7 +80,6 @@ NON_REENTRANT += random
 | 
				
			|||||||
NON_REENTRANT += rand
 | 
					NON_REENTRANT += rand
 | 
				
			||||||
NON_REENTRANT += seed48
 | 
					NON_REENTRANT += seed48
 | 
				
			||||||
NON_REENTRANT += setstate
 | 
					NON_REENTRANT += setstate
 | 
				
			||||||
NON_REENTRANT += sgetsgent
 | 
					 | 
				
			||||||
NON_REENTRANT += sgetspent
 | 
					NON_REENTRANT += sgetspent
 | 
				
			||||||
NON_REENTRANT += srand48
 | 
					NON_REENTRANT += srand48
 | 
				
			||||||
NON_REENTRANT += srandom
 | 
					NON_REENTRANT += srandom
 | 
				
			||||||
@@ -117,11 +98,3 @@ NON_REENTRANT += inet_nsap_ntoa
 | 
				
			|||||||
NON_REENTRANT += inet_ntoa
 | 
					NON_REENTRANT += inet_ntoa
 | 
				
			||||||
NON_REENTRANT += inet_ntop
 | 
					NON_REENTRANT += inet_ntop
 | 
				
			||||||
NON_REENTRANT += inet_pton
 | 
					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 notes intend to help people working on the checked-out sources.
 | 
				
			||||||
These requirements do not apply when building from a distribution tarball.
 | 
					These requirements do not apply when building from a distribution tarball.
 | 
				
			||||||
See also docs/hacking.html (after building libvirt using the information
 | 
					See also HACKING for more detailed libvirt contribution guidelines.
 | 
				
			||||||
included in this file) for more detailed contribution guidelines.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Requirements
 | 
					* Requirements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,7 +15,7 @@ Specific development tools and versions will be checked for and listed by
 | 
				
			|||||||
the bootstrap script.
 | 
					the bootstrap script.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Valgrind <http://valgrind.org/> is also highly recommended, if
 | 
					Valgrind <http://valgrind.org/> is also highly recommended, if
 | 
				
			||||||
Valgrind supports your architecture.
 | 
					Valgrind supports your architecture. See also README-valgrind.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
While building from a just-cloned source tree may require installing a
 | 
					While building from a just-cloned source tree may require installing a
 | 
				
			||||||
few prerequisites, later, a plain `git pull && make' should be sufficient.
 | 
					few prerequisites, later, a plain `git pull && make' should be sufficient.
 | 
				
			||||||
@@ -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:
 | 
					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
 | 
					        $ cd libvirt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As an optional step, if you already have a copy of the gnulib git
 | 
					As an optional step, if you already have a copy of the gnulib git
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								README.md
									
									
									
									
									
								
							@@ -1,83 +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.1 (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. For example, to build in a manner
 | 
					 | 
				
			||||||
that is suitable for installing as root, use:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
$ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
 | 
					 | 
				
			||||||
$ make
 | 
					 | 
				
			||||||
$ sudo make install
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
While to build & install as an unprivileged user
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
$ ./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
 | 
				
			||||||
							
								
								
									
										113
									
								
								autobuild.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										113
									
								
								autobuild.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set -e
 | 
				
			||||||
 | 
					set -v
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Make things clean.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test -n "$1" && RESULTS=$1 || RESULTS=results.log
 | 
				
			||||||
 | 
					: ${AUTOBUILD_INSTALL_ROOT=$HOME/builder}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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-test-coverage \
 | 
				
			||||||
 | 
					  --disable-nls \
 | 
				
			||||||
 | 
					  --enable-werror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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_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-werror \
 | 
				
			||||||
 | 
					    --without-libvirtd \
 | 
				
			||||||
 | 
					    --without-python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  make
 | 
				
			||||||
 | 
					  make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Test mingw64 cross-compile
 | 
				
			||||||
 | 
					if test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
 | 
				
			||||||
 | 
					  make distclean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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-werror \
 | 
				
			||||||
 | 
					    --without-libvirtd \
 | 
				
			||||||
 | 
					    --without-python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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
 | 
				
			||||||
							
								
								
									
										285
									
								
								autogen.sh
									
									
									
									
									
								
							
							
						
						
									
										285
									
								
								autogen.sh
									
									
									
									
									
								
							@@ -1,208 +1,105 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					#!/bin/sh
 | 
				
			||||||
# Run this to generate all the initial makefiles, etc.
 | 
					# Run this to generate all the initial makefiles, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
die()
 | 
					set -e
 | 
				
			||||||
{
 | 
					
 | 
				
			||||||
    echo "error: $1" >&2
 | 
					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
 | 
					    exit 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
starting_point=$(pwd)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
srcdir=$(dirname "$0")
 | 
					EXTRA_ARGS=
 | 
				
			||||||
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=
 | 
					 | 
				
			||||||
no_git=
 | 
					no_git=
 | 
				
			||||||
gnulib_srcdir=
 | 
					if test "x$1" = "x--no-git"; then
 | 
				
			||||||
extra_args=
 | 
					  no_git=" $1"
 | 
				
			||||||
while test "$#" -gt 0; do
 | 
					  shift
 | 
				
			||||||
    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"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gnulib_hash()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local no_git=$1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if test "$no_git"; then
 | 
					 | 
				
			||||||
        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 hash-object bootstrap.conf
 | 
					 | 
				
			||||||
    git ls-tree -d HEAD gnulib/local | awk '{ print $3 }'
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Only look into git submodules if we're in a git checkout
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
    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"
 | 
					 | 
				
			||||||
        fi
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					if test -z "$NOCONFIGURE" ; then
 | 
				
			||||||
# When performing a dry run, we can stop here
 | 
					  if test "x$1" = "x--system"; then
 | 
				
			||||||
test "$dry_run" && exit "$dry_run"
 | 
					    shift
 | 
				
			||||||
 | 
					    prefix=/usr
 | 
				
			||||||
# If asked not to run configure, we can stop here
 | 
					    libdir=$prefix/lib
 | 
				
			||||||
test "$NOCONFIGURE" && exit 0
 | 
					    sysconfdir=/etc
 | 
				
			||||||
 | 
					    localstatedir=/var
 | 
				
			||||||
cd "$starting_point" || {
 | 
					    if [ -d /usr/lib64 ]; then
 | 
				
			||||||
    die "Failed to cd into $starting_point"
 | 
					      libdir=$prefix/lib64
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
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
 | 
					    fi
 | 
				
			||||||
done
 | 
					    EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir"
 | 
				
			||||||
test "$MAKE" || {
 | 
					    echo "Running ./configure with $EXTRA_ARGS $@"
 | 
				
			||||||
    die "GNU make is required to build libvirt"
 | 
					  else
 | 
				
			||||||
}
 | 
					    if test -z "$*" && test ! -f "$THEDIR/config.status"; then
 | 
				
			||||||
 | 
					        echo "I am going to run ./configure with no arguments - if you wish "
 | 
				
			||||||
if test -z "$*" && test -z "$extra_args" && test -f config.status; then
 | 
					 | 
				
			||||||
    echo "Running config.status..."
 | 
					 | 
				
			||||||
    ./config.status --recheck || {
 | 
					 | 
				
			||||||
        die "config.status failed"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
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."
 | 
					        echo "to pass any to it, please specify them on the $0 command line."
 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        echo "Running configure with $extra_args $@"
 | 
					 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    "$srcdir/configure" $extra_args "$@" || {
 | 
					  fi
 | 
				
			||||||
        die "configure failed"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo
 | 
					# Compute the hash we'll use to determine whether rerunning bootstrap
 | 
				
			||||||
echo "Now type '$MAKE' to compile libvirt."
 | 
					# 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()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    git submodule status | sed 's/^[ +-]//;s/ .*//'
 | 
				
			||||||
 | 
					    git hash-object bootstrap.conf
 | 
				
			||||||
 | 
					    git ls-tree -d HEAD gnulib/local | awk '{print $3}'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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; then
 | 
				
			||||||
 | 
					    curr_status=.git-module-status
 | 
				
			||||||
 | 
					    t=$(bootstrap_hash; git diff .gnulib)
 | 
				
			||||||
 | 
					    case $t:${CLEAN_SUBMODULE+set} in
 | 
				
			||||||
 | 
					        *:set) ;;
 | 
				
			||||||
 | 
					        *-dirty*)
 | 
				
			||||||
 | 
					            echo "error: gnulib submodule is dirty, please investigate" 2>&1
 | 
				
			||||||
 | 
					            echo "set env-var CLEAN_SUBMODULE to discard gnulib changes" 2>&1
 | 
				
			||||||
 | 
					            exit 1 ;;
 | 
				
			||||||
 | 
					    esac
 | 
				
			||||||
 | 
					    # Keep this test in sync with cfg.mk:_update_required
 | 
				
			||||||
 | 
					    if test "$t" = "$(cat $curr_status 2>/dev/null)" \
 | 
				
			||||||
 | 
					        && test -f "po/Makevars" && test -f AUTHORS; then
 | 
				
			||||||
 | 
					        # good, it's up to date, all we need is autoreconf
 | 
				
			||||||
 | 
					        autoreconf -if
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        if test ${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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test -n "$NOCONFIGURE" && exit 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd "$THEDIR"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if test "x$OBJ_DIR" != x; then
 | 
				
			||||||
 | 
					    mkdir -p "$OBJ_DIR"
 | 
				
			||||||
 | 
					    cd "$OBJ_DIR"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if test -z "$*" && test -z "$EXTRA_ARGS" && test -f config.status; then
 | 
				
			||||||
 | 
					    ./config.status --recheck
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    $srcdir/configure $EXTRA_ARGS "$@"
 | 
				
			||||||
 | 
					fi && {
 | 
				
			||||||
 | 
					    echo
 | 
				
			||||||
 | 
					    echo "Now type 'make' to compile libvirt."
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										489
									
								
								bootstrap
									
									
									
									
									
								
							
							
						
						
									
										489
									
								
								bootstrap
									
									
									
									
									
								
							@@ -1,10 +1,10 @@
 | 
				
			|||||||
#! /bin/sh
 | 
					#! /bin/sh
 | 
				
			||||||
# Print a version string.
 | 
					# Print a version string.
 | 
				
			||||||
scriptversion=2019-01-04.17; # UTC
 | 
					scriptversion=2012-07-19.14; # UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Bootstrap this package from checked-out sources.
 | 
					# Bootstrap this package from checked-out sources.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Copyright (C) 2003-2019 Free Software Foundation, Inc.
 | 
					# Copyright (C) 2003-2012 Free Software Foundation, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This program is free software: you can redistribute it and/or modify
 | 
					# 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
 | 
					# 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.
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# You should have received a copy of the GNU General Public License
 | 
					# 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
 | 
					# Originally written by Paul Eggert.  The canonical version of this
 | 
				
			||||||
# script is maintained as build-aux/bootstrap in gnulib, however, to
 | 
					# script is maintained as build-aux/bootstrap in gnulib, however, to
 | 
				
			||||||
@@ -42,13 +42,8 @@ export LC_ALL
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
local_gl_dir=gl
 | 
					local_gl_dir=gl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Honor $PERL, but work even if there is none.
 | 
					 | 
				
			||||||
PERL="${PERL-perl}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
me=$0
 | 
					me=$0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
default_gnulib_url=git://git.sv.gnu.org/gnulib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
usage() {
 | 
					usage() {
 | 
				
			||||||
  cat <<EOF
 | 
					  cat <<EOF
 | 
				
			||||||
Usage: $me [OPTION]...
 | 
					Usage: $me [OPTION]...
 | 
				
			||||||
@@ -78,37 +73,6 @@ contents are read as shell variables to configure the bootstrap.
 | 
				
			|||||||
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
 | 
					For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
 | 
				
			||||||
are honored.
 | 
					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.
 | 
					Running without arguments will suffice in most cases.
 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -162,28 +126,34 @@ bootstrap_post_import_hook() { :; }
 | 
				
			|||||||
# Override it via your own definition in bootstrap.conf.
 | 
					# Override it via your own definition in bootstrap.conf.
 | 
				
			||||||
bootstrap_epilogue() { :; }
 | 
					bootstrap_epilogue() { :; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The command to download all .po files for a specified domain into a
 | 
					# The command to download all .po files for a specified domain into
 | 
				
			||||||
# specified directory.  Fill in the first %s with the destination
 | 
					# a specified directory.  Fill in the first %s is the domain name, and
 | 
				
			||||||
# directory and the second with the domain name.
 | 
					# 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=\
 | 
					po_download_command_format=\
 | 
				
			||||||
"wget --mirror --level=1 -nd -q -A.po -P '%s' \
 | 
					"rsync --delete --exclude '*.s1' -Lrtvz \
 | 
				
			||||||
 https://translationproject.org/latest/%s/"
 | 
					 '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)
 | 
					 | 
				
			||||||
extract_package_name='
 | 
					extract_package_name='
 | 
				
			||||||
  /^AC_INIT(\[*/{
 | 
					  /^AC_INIT(/{
 | 
				
			||||||
     s///
 | 
					     /.*,.*,.*, */{
 | 
				
			||||||
     /^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
 | 
					       s///
 | 
				
			||||||
       s//\1/
 | 
					       s/[][]//g
 | 
				
			||||||
       s/[],)].*//
 | 
					       s/)$//
 | 
				
			||||||
       p
 | 
					       p
 | 
				
			||||||
       q
 | 
					       q
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     s/[],)].*//
 | 
					     s/AC_INIT(\[*//
 | 
				
			||||||
 | 
					     s/]*,.*//
 | 
				
			||||||
     s/^GNU //
 | 
					     s/^GNU //
 | 
				
			||||||
     y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
 | 
					     y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
 | 
				
			||||||
     s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
 | 
					     s/[^A-Za-z0-9_]/-/g
 | 
				
			||||||
     p
 | 
					     p
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
@@ -196,15 +166,7 @@ source_base=lib
 | 
				
			|||||||
m4_base=m4
 | 
					m4_base=m4
 | 
				
			||||||
doc_base=doc
 | 
					doc_base=doc
 | 
				
			||||||
tests_base=tests
 | 
					tests_base=tests
 | 
				
			||||||
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
 | 
					 | 
				
			||||||
"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Additional gnulib-tool options to use.  Use "\newline" to break lines.
 | 
					# Additional gnulib-tool options to use.  Use "\newline" to break lines.
 | 
				
			||||||
gnulib_tool_option_extras=
 | 
					gnulib_tool_option_extras=
 | 
				
			||||||
@@ -246,26 +208,12 @@ bootstrap_sync=false
 | 
				
			|||||||
# Use git to update gnulib sources
 | 
					# Use git to update gnulib sources
 | 
				
			||||||
use_git=true
 | 
					use_git=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check_exists() {
 | 
					 | 
				
			||||||
  if test "$1" = "--verbose"; then
 | 
					 | 
				
			||||||
    ($2 --version </dev/null) >/dev/null 2>&1
 | 
					 | 
				
			||||||
    if test $? -ge 126; then
 | 
					 | 
				
			||||||
      # If not found, run with diagnostics as one may be
 | 
					 | 
				
			||||||
      # presented with env variables to set to find the right version
 | 
					 | 
				
			||||||
      ($2 --version </dev/null)
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    ($1 --version </dev/null) >/dev/null 2>&1
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  test $? -lt 126
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# find_tool ENVVAR NAMES...
 | 
					# find_tool ENVVAR NAMES...
 | 
				
			||||||
# -------------------------
 | 
					# -------------------------
 | 
				
			||||||
# Search for a required program.  Use the value of ENVVAR, if set,
 | 
					# Search for a required program.  Use the value of ENVVAR, if set,
 | 
				
			||||||
# otherwise find the first of the NAMES that can be run.
 | 
					# otherwise find the first of the NAMES that can be run (i.e.,
 | 
				
			||||||
# If found, set ENVVAR to the program name, die otherwise.
 | 
					# supports --version).  If found, set ENVVAR to the program name,
 | 
				
			||||||
 | 
					# die otherwise.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# FIXME: code duplication, see also gnu-web-doc-update.
 | 
					# FIXME: code duplication, see also gnu-web-doc-update.
 | 
				
			||||||
find_tool ()
 | 
					find_tool ()
 | 
				
			||||||
@@ -275,21 +223,27 @@ find_tool ()
 | 
				
			|||||||
  find_tool_names=$@
 | 
					  find_tool_names=$@
 | 
				
			||||||
  eval "find_tool_res=\$$find_tool_envvar"
 | 
					  eval "find_tool_res=\$$find_tool_envvar"
 | 
				
			||||||
  if test x"$find_tool_res" = x; then
 | 
					  if test x"$find_tool_res" = x; then
 | 
				
			||||||
    for i; do
 | 
					    for i
 | 
				
			||||||
      if check_exists $i; then
 | 
					    do
 | 
				
			||||||
        find_tool_res=$i
 | 
					      if ($i --version </dev/null) >/dev/null 2>&1; then
 | 
				
			||||||
        break
 | 
					       find_tool_res=$i
 | 
				
			||||||
 | 
					       break
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
    done
 | 
					    done
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    find_tool_error_prefix="\$$find_tool_envvar: "
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  if test x"$find_tool_res" = x; then
 | 
					  test x"$find_tool_res" != x \
 | 
				
			||||||
    warn_ "one of these is required: $find_tool_names;"
 | 
					    || die "one of these is required: $find_tool_names"
 | 
				
			||||||
    die   "alternatively set $find_tool_envvar to a compatible tool"
 | 
					  ($find_tool_res --version </dev/null) >/dev/null 2>&1 \
 | 
				
			||||||
  fi
 | 
					    || die "${find_tool_error_prefix}cannot run $find_tool_res --version"
 | 
				
			||||||
  eval "$find_tool_envvar=\$find_tool_res"
 | 
					  eval "$find_tool_envvar=\$find_tool_res"
 | 
				
			||||||
  eval "export $find_tool_envvar"
 | 
					  eval "export $find_tool_envvar"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
 | 
				
			||||||
 | 
					find_tool SHA1SUM sha1sum gsha1sum shasum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Override the default configuration, if necessary.
 | 
					# Override the default configuration, if necessary.
 | 
				
			||||||
# Make sure that bootstrap.conf is sourced from the current directory
 | 
					# Make sure that bootstrap.conf is sourced from the current directory
 | 
				
			||||||
# if we were invoked as "sh bootstrap".
 | 
					# if we were invoked as "sh bootstrap".
 | 
				
			||||||
@@ -298,18 +252,24 @@ case "$0" in
 | 
				
			|||||||
  *) test -r "$0.conf" && . ./"$0.conf" ;;
 | 
					  *) test -r "$0.conf" && . ./"$0.conf" ;;
 | 
				
			||||||
esac
 | 
					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
 | 
					if test "$vc_ignore" = auto; then
 | 
				
			||||||
  vc_ignore=
 | 
					  vc_ignore=
 | 
				
			||||||
  test -d .git && vc_ignore=.gitignore
 | 
					  test -d .git && vc_ignore=.gitignore
 | 
				
			||||||
  test -d CVS && vc_ignore="$vc_ignore .cvsignore"
 | 
					  test -d CVS && vc_ignore="$vc_ignore .cvsignore"
 | 
				
			||||||
fi
 | 
					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.
 | 
					# Translate configuration into internal form.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Parse options.
 | 
					# Parse options.
 | 
				
			||||||
@@ -346,34 +306,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
 | 
				
			|||||||
  die "Bootstrapping from a non-checked-out distribution is risky."
 | 
					  die "Bootstrapping from a non-checked-out distribution is risky."
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Strip blank and comment lines to leave significant entries.
 | 
					# Ensure that lines starting with ! sort last, per gitignore conventions
 | 
				
			||||||
gitignore_entries() {
 | 
					# for whitelisting exceptions after a more generic blacklist pattern.
 | 
				
			||||||
  sed '/^#/d; /^$/d' "$@"
 | 
					sort_patterns() {
 | 
				
			||||||
 | 
					  sort -u "$@" | sed '/^!/ {
 | 
				
			||||||
 | 
					    H
 | 
				
			||||||
 | 
					    d
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  $ {
 | 
				
			||||||
 | 
					    P
 | 
				
			||||||
 | 
					    x
 | 
				
			||||||
 | 
					    s/^\n//
 | 
				
			||||||
 | 
					  }' | sed '/^$/d'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# If $STR is not already on a line by itself in $FILE, insert it at the start.
 | 
					# If $STR is not already on a line by itself in $FILE, insert it,
 | 
				
			||||||
# Entries are inserted at the start of the ignore list to ensure existing
 | 
					# sorting the new contents of the file and replacing $FILE with the result.
 | 
				
			||||||
# entries starting with ! are not overridden.  Such entries support
 | 
					insert_sorted_if_absent() {
 | 
				
			||||||
# whitelisting exceptions after a more generic blacklist pattern.
 | 
					 | 
				
			||||||
insert_if_absent() {
 | 
					 | 
				
			||||||
  file=$1
 | 
					  file=$1
 | 
				
			||||||
  str=$2
 | 
					  str=$2
 | 
				
			||||||
  test -f $file || touch $file
 | 
					  test -f $file || touch $file
 | 
				
			||||||
  test -r $file || die "Error: failed to read ignore file: $file"
 | 
					  echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
 | 
				
			||||||
  duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
 | 
					    || { echo "$str" | sort_patterns - $file > $file.bak \
 | 
				
			||||||
  if [ "$duplicate_entries" ] ; then
 | 
					      && mv $file.bak $file; } \
 | 
				
			||||||
    die "Error: Duplicate entries in $file: " $duplicate_entries
 | 
					    || die "insert_sorted_if_absent $file $str: failed"
 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
  linesold=$(gitignore_entries $file | wc -l)
 | 
					 | 
				
			||||||
  linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
 | 
					 | 
				
			||||||
  if [ $linesold != $linesnew ] ; then
 | 
					 | 
				
			||||||
    { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
 | 
					 | 
				
			||||||
      || die "insert_if_absent $file $str: failed"
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
 | 
					# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
 | 
				
			||||||
# insert_if_absent.
 | 
					# insert_sorted_if_absent.
 | 
				
			||||||
insert_vc_ignore() {
 | 
					insert_vc_ignore() {
 | 
				
			||||||
  vc_ignore_file="$1"
 | 
					  vc_ignore_file="$1"
 | 
				
			||||||
  pattern="$2"
 | 
					  pattern="$2"
 | 
				
			||||||
@@ -384,7 +344,7 @@ insert_vc_ignore() {
 | 
				
			|||||||
    # .gitignore entry.
 | 
					    # .gitignore entry.
 | 
				
			||||||
    pattern=$(echo "$pattern" | sed s,^,/,);;
 | 
					    pattern=$(echo "$pattern" | sed s,^,/,);;
 | 
				
			||||||
  esac
 | 
					  esac
 | 
				
			||||||
  insert_if_absent "$vc_ignore_file" "$pattern"
 | 
					  insert_sorted_if_absent "$vc_ignore_file" "$pattern"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
 | 
					# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
 | 
				
			||||||
@@ -446,30 +406,28 @@ sort_ver() { # sort -V is not generally available
 | 
				
			|||||||
  done
 | 
					  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() {
 | 
					get_version() {
 | 
				
			||||||
  app=$1
 | 
					  app=$1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $app --version >/dev/null 2>&1 || { $app --version; return 1; }
 | 
					  $app --version >/dev/null 2>&1 || 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() {
 | 
					check_versions() {
 | 
				
			||||||
@@ -489,7 +447,6 @@ check_versions() {
 | 
				
			|||||||
    test "$appvar" = TAR && appvar=AMTAR
 | 
					    test "$appvar" = TAR && appvar=AMTAR
 | 
				
			||||||
    case $appvar in
 | 
					    case $appvar in
 | 
				
			||||||
        GZIP) ;; # Do not use $GZIP:  it contains gzip options.
 | 
					        GZIP) ;; # Do not use $GZIP:  it contains gzip options.
 | 
				
			||||||
        PERL::*) ;; # Keep perl modules as-is
 | 
					 | 
				
			||||||
        *) eval "app=\${$appvar-$app}" ;;
 | 
					        *) eval "app=\${$appvar-$app}" ;;
 | 
				
			||||||
    esac
 | 
					    esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -507,22 +464,12 @@ check_versions() {
 | 
				
			|||||||
          ret=1
 | 
					          ret=1
 | 
				
			||||||
          continue
 | 
					          continue
 | 
				
			||||||
        } ;;
 | 
					        } ;;
 | 
				
			||||||
      # Another check is for perl modules.  These can be written as
 | 
					 | 
				
			||||||
      # e.g. perl::XML::XPath in case of XML::XPath module, etc.
 | 
					 | 
				
			||||||
      perl::*)
 | 
					 | 
				
			||||||
        # Extract module name
 | 
					 | 
				
			||||||
        app="${app#perl::}"
 | 
					 | 
				
			||||||
        if ! $PERL -m"$app" -e 'exit 0' >/dev/null 2>&1; then
 | 
					 | 
				
			||||||
          warn_ "Error: perl module '$app' not found"
 | 
					 | 
				
			||||||
          ret=1
 | 
					 | 
				
			||||||
        fi
 | 
					 | 
				
			||||||
        continue
 | 
					 | 
				
			||||||
        ;;
 | 
					 | 
				
			||||||
    esac
 | 
					    esac
 | 
				
			||||||
    if [ "$req_ver" = "-" ]; then
 | 
					    if [ "$req_ver" = "-" ]; then
 | 
				
			||||||
      # Merely require app to exist; not all prereq apps are well-behaved
 | 
					      # Merely require app to exist; not all prereq apps are well-behaved
 | 
				
			||||||
      # so we have to rely on $? rather than get_version.
 | 
					      # so we have to rely on $? rather than get_version.
 | 
				
			||||||
      if ! check_exists --verbose $app; then
 | 
					      $app --version >/dev/null 2>&1
 | 
				
			||||||
 | 
					      if [ 126 -le $? ]; then
 | 
				
			||||||
        warn_ "Error: '$app' not found"
 | 
					        warn_ "Error: '$app' not found"
 | 
				
			||||||
        ret=1
 | 
					        ret=1
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
@@ -555,12 +502,6 @@ print_versions() {
 | 
				
			|||||||
  # can't depend on column -t
 | 
					  # can't depend on column -t
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
 | 
					 | 
				
			||||||
# Also find the compatible sha1 utility on the BSDs
 | 
					 | 
				
			||||||
if test x"$SKIP_PO" = x; then
 | 
					 | 
				
			||||||
  find_tool SHA1SUM sha1sum gsha1sum shasum sha1
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use_libtool=0
 | 
					use_libtool=0
 | 
				
			||||||
# We'd like to use grep -E, to see if any of LT_INIT,
 | 
					# We'd like to use grep -E, to see if any of LT_INIT,
 | 
				
			||||||
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
 | 
					# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
 | 
				
			||||||
@@ -606,21 +547,13 @@ if ! printf "$buildreq" | check_versions; then
 | 
				
			|||||||
  fi
 | 
					  fi
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Warn the user if autom4te appears to be broken; this causes known
 | 
					 | 
				
			||||||
# issues with at least gettext 0.18.3.
 | 
					 | 
				
			||||||
probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -)
 | 
					 | 
				
			||||||
if test "x$probe" != xhi; then
 | 
					 | 
				
			||||||
  warn_ "WARNING: your autom4te wrapper eats stdin;"
 | 
					 | 
				
			||||||
  warn_ "if bootstrap fails, consider upgrading your autotools"
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo "$0: Bootstrapping from checked-out $package sources..."
 | 
					echo "$0: Bootstrapping from checked-out $package sources..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# See if we can use gnulib's git-merge-changelog merge driver.
 | 
					# See if we can use gnulib's git-merge-changelog merge driver.
 | 
				
			||||||
if $use_git && test -d .git && check_exists git; then
 | 
					if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
 | 
				
			||||||
  if git config merge.merge-changelog.driver >/dev/null ; then
 | 
					  if git config merge.merge-changelog.driver >/dev/null ; then
 | 
				
			||||||
    :
 | 
					    :
 | 
				
			||||||
  elif check_exists git-merge-changelog; then
 | 
					  elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
 | 
				
			||||||
    echo "$0: initializing git-merge-changelog driver"
 | 
					    echo "$0: initializing git-merge-changelog driver"
 | 
				
			||||||
    git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
 | 
					    git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
 | 
				
			||||||
    git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
 | 
					    git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
 | 
				
			||||||
@@ -640,101 +573,83 @@ git_modules_config () {
 | 
				
			|||||||
  test -f .gitmodules && git config --file .gitmodules "$@"
 | 
					  test -f .gitmodules && git config --file .gitmodules "$@"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if $use_gnulib; then
 | 
					gnulib_path=$(git_modules_config submodule.gnulib.path)
 | 
				
			||||||
  if $use_git; then
 | 
					test -z "$gnulib_path" && gnulib_path=gnulib
 | 
				
			||||||
    gnulib_path=$(git_modules_config submodule.gnulib.path)
 | 
					
 | 
				
			||||||
    test -z "$gnulib_path" && gnulib_path=gnulib
 | 
					# Get gnulib files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case ${GNULIB_SRCDIR--} in
 | 
				
			||||||
 | 
					-)
 | 
				
			||||||
 | 
					  if git_modules_config submodule.gnulib.url >/dev/null; then
 | 
				
			||||||
 | 
					    echo "$0: getting gnulib files..."
 | 
				
			||||||
 | 
					    git submodule init || exit $?
 | 
				
			||||||
 | 
					    git submodule update || 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
 | 
					  fi
 | 
				
			||||||
 | 
					  GNULIB_SRCDIR=$gnulib_path
 | 
				
			||||||
  # Get gnulib files.  Populate $GNULIB_SRCDIR, possibly updating a
 | 
					  ;;
 | 
				
			||||||
  # submodule, for use in the rest of the script.
 | 
					*)
 | 
				
			||||||
 | 
					  # Use GNULIB_SRCDIR as a reference.
 | 
				
			||||||
  case ${GNULIB_SRCDIR--} in
 | 
					  if test -d "$GNULIB_SRCDIR"/.git && \
 | 
				
			||||||
  -)
 | 
					        git_modules_config submodule.gnulib.url >/dev/null; then
 | 
				
			||||||
    # Note that $use_git is necessarily true in this case.
 | 
					    echo "$0: getting gnulib files..."
 | 
				
			||||||
    if git_modules_config submodule.gnulib.url >/dev/null; then
 | 
					    if git submodule -h|grep -- --reference > /dev/null; then
 | 
				
			||||||
      echo "$0: getting gnulib files..."
 | 
					      # Prefer the one-liner available in git 1.6.4 or newer.
 | 
				
			||||||
      git submodule init -- "$gnulib_path" || exit $?
 | 
					      git submodule update --init --reference "$GNULIB_SRCDIR" \
 | 
				
			||||||
      git submodule update -- "$gnulib_path" || exit $?
 | 
					        "$gnulib_path" || exit $?
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
    elif [ ! -d "$gnulib_path" ]; then
 | 
					      # This fallback allows at least git 1.5.5.
 | 
				
			||||||
      echo "$0: getting gnulib files..."
 | 
					      if test -f "$gnulib_path"/gnulib-tool; then
 | 
				
			||||||
 | 
					        # Since file already exists, assume submodule init already complete.
 | 
				
			||||||
      trap cleanup_gnulib 1 2 13 15
 | 
					        git submodule update || exit $?
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
      shallow=
 | 
					        # Older git can't clone into an empty directory.
 | 
				
			||||||
      if test -z "$GNULIB_REVISION"; then
 | 
					        rmdir "$gnulib_path" 2>/dev/null
 | 
				
			||||||
        git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
 | 
					        git clone --reference "$GNULIB_SRCDIR" \
 | 
				
			||||||
 | 
					          "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
 | 
				
			||||||
 | 
					          && git submodule init && git submodule update \
 | 
				
			||||||
 | 
					          || exit $?
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
      git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \
 | 
					 | 
				
			||||||
        || cleanup_gnulib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      trap - 1 2 13 15
 | 
					 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    GNULIB_SRCDIR=$gnulib_path
 | 
					    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
 | 
					  fi
 | 
				
			||||||
 | 
					  ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # $GNULIB_SRCDIR now points to the version of gnulib to use, and
 | 
					if $bootstrap_sync; then
 | 
				
			||||||
  # we no longer need to use git or $gnulib_path below here.
 | 
					  cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
 | 
				
			||||||
 | 
					    echo "$0: updating bootstrap and restarting..."
 | 
				
			||||||
  if $bootstrap_sync; then
 | 
					    exec sh -c \
 | 
				
			||||||
    cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
 | 
					      'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
 | 
				
			||||||
      echo "$0: updating bootstrap and restarting..."
 | 
					      -- "$GNULIB_SRCDIR/build-aux/bootstrap" \
 | 
				
			||||||
      case $(sh -c 'echo "$1"' -- a) in
 | 
					      "$0" "$@" --no-bootstrap-sync
 | 
				
			||||||
        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 $?
 | 
					 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
 | 
				
			||||||
 | 
					<$gnulib_tool || exit $?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Get translations.
 | 
					# Get translations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
download_po_files() {
 | 
					download_po_files() {
 | 
				
			||||||
  subdir=$1
 | 
					  subdir=$1
 | 
				
			||||||
  domain=$2
 | 
					  domain=$2
 | 
				
			||||||
  echo "$me: getting translations into $subdir for $domain..."
 | 
					  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"
 | 
					  eval "$cmd"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -765,10 +680,11 @@ update_po_files() {
 | 
				
			|||||||
    cksum_file="$ref_po_dir/$po.s1"
 | 
					    cksum_file="$ref_po_dir/$po.s1"
 | 
				
			||||||
    if ! test -f "$cksum_file" ||
 | 
					    if ! test -f "$cksum_file" ||
 | 
				
			||||||
        ! test -f "$po_dir/$po.po" ||
 | 
					        ! test -f "$po_dir/$po.po" ||
 | 
				
			||||||
        ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
 | 
					        ! $SHA1SUM -c --status "$cksum_file" \
 | 
				
			||||||
 | 
					            < "$new_po" > /dev/null; then
 | 
				
			||||||
      echo "$me: updated $po_dir/$po.po..."
 | 
					      echo "$me: updated $po_dir/$po.po..."
 | 
				
			||||||
      cp "$new_po" "$po_dir/$po.po" \
 | 
					      cp "$new_po" "$po_dir/$po.po" \
 | 
				
			||||||
          && $SHA1SUM < "$new_po" > "$cksum_file" || return
 | 
					          && $SHA1SUM < "$new_po" > "$cksum_file"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -824,9 +740,9 @@ symlink_to_dir()
 | 
				
			|||||||
      # Leave any existing symlink alone, if it already points to the source,
 | 
					      # Leave any existing symlink alone, if it already points to the source,
 | 
				
			||||||
      # so that broken build tools that care about symlink times
 | 
					      # so that broken build tools that care about symlink times
 | 
				
			||||||
      # aren't confused into doing unnecessary builds.  Conversely, if the
 | 
					      # 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
 | 
					      # 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" &&
 | 
					      test -h "$dst" &&
 | 
				
			||||||
      src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
 | 
					      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 &&
 | 
					      dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
 | 
				
			||||||
@@ -932,47 +848,35 @@ fi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Import from gnulib.
 | 
					# Import from gnulib.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if $use_gnulib; then
 | 
					gnulib_tool_options="\
 | 
				
			||||||
  gnulib_tool_options="\
 | 
					 --import\
 | 
				
			||||||
   --no-changelog\
 | 
					 --no-changelog\
 | 
				
			||||||
   --aux-dir=$build_aux\
 | 
					 --aux-dir $build_aux\
 | 
				
			||||||
   --doc-base=$doc_base\
 | 
					 --doc-base $doc_base\
 | 
				
			||||||
   --lib=$gnulib_name\
 | 
					 --lib $gnulib_name\
 | 
				
			||||||
   --m4-base=$m4_base/\
 | 
					 --m4-base $m4_base/\
 | 
				
			||||||
   --source-base=$source_base/\
 | 
					 --source-base $source_base/\
 | 
				
			||||||
   --tests-base=$tests_base\
 | 
					 --tests-base $tests_base\
 | 
				
			||||||
   --local-dir=$local_gl_dir\
 | 
					 --local-dir $local_gl_dir\
 | 
				
			||||||
   $gnulib_tool_option_extras\
 | 
					 $gnulib_tool_option_extras\
 | 
				
			||||||
  "
 | 
					"
 | 
				
			||||||
  if test $use_libtool = 1; then
 | 
					if test $use_libtool = 1; then
 | 
				
			||||||
    case "$gnulib_tool_options " in
 | 
					  case "$gnulib_tool_options " in
 | 
				
			||||||
      *' --libtool '*) ;;
 | 
					    *' --libtool '*) ;;
 | 
				
			||||||
      *) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
 | 
					    *) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
 | 
				
			||||||
    esac
 | 
					  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
 | 
					 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
 | 
				
			||||||
 | 
					$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for file in $gnulib_files; do
 | 
				
			||||||
 | 
					  symlink_to_dir "$GNULIB_SRCDIR" $file \
 | 
				
			||||||
 | 
					    || die "failed to symlink $file"
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bootstrap_post_import_hook \
 | 
					bootstrap_post_import_hook \
 | 
				
			||||||
  || die "bootstrap_post_import_hook failed"
 | 
					  || 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
 | 
					# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
 | 
				
			||||||
# gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
 | 
					# gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
 | 
				
			||||||
# The following requires GNU find 4.2.3 or newer.  Considering the usual
 | 
					# The following requires GNU find 4.2.3 or newer.  Considering the usual
 | 
				
			||||||
@@ -985,21 +889,20 @@ find "$m4_base" "$source_base" \
 | 
				
			|||||||
  -depth \( -name '*.m4' -o -name '*.[ch]' \) \
 | 
					  -depth \( -name '*.m4' -o -name '*.[ch]' \) \
 | 
				
			||||||
  -type l -xtype l -delete > /dev/null 2>&1
 | 
					  -type l -xtype l -delete > /dev/null 2>&1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Invoke autoreconf with --force --install to ensure upgrades of tools
 | 
					 | 
				
			||||||
# such as ylwrap.
 | 
					 | 
				
			||||||
AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Some systems (RHEL 5) are using ancient autotools, for which the
 | 
					# Some systems (RHEL 5) are using ancient autotools, for which the
 | 
				
			||||||
# --no-recursive option had not been invented.  Detect that lack and
 | 
					# --no-recursive option had not been invented.  Detect that lack and
 | 
				
			||||||
# omit the option when it's not supported.  FIXME in 2017: remove this
 | 
					# omit the option when it's not supported.  FIXME in 2017: remove this
 | 
				
			||||||
# hack when RHEL 5 autotools are updated, or when they become irrelevant.
 | 
					# hack when RHEL 5 autotools are updated, or when they become irrelevant.
 | 
				
			||||||
 | 
					no_recursive=
 | 
				
			||||||
case $($AUTORECONF --help) in
 | 
					case $($AUTORECONF --help) in
 | 
				
			||||||
  *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
 | 
					  *--no-recursive*) no_recursive=--no-recursive;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
 | 
					# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
 | 
				
			||||||
echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
 | 
					echo "running: AUTOPOINT=true LIBTOOLIZE=true " \
 | 
				
			||||||
AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
 | 
					    "$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS"
 | 
				
			||||||
 | 
					AUTOPOINT=true LIBTOOLIZE=true \
 | 
				
			||||||
 | 
					    $AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS \
 | 
				
			||||||
  || die "autoreconf failed"
 | 
					  || die "autoreconf failed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Get some extra files from gnulib, overriding existing files.
 | 
					# Get some extra files from gnulib, overriding existing files.
 | 
				
			||||||
@@ -1065,9 +968,9 @@ bootstrap_epilogue
 | 
				
			|||||||
echo "$0: done.  Now you can run './configure'."
 | 
					echo "$0: done.  Now you can run './configure'."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Local variables:
 | 
					# Local variables:
 | 
				
			||||||
# eval: (add-hook 'before-save-hook 'time-stamp)
 | 
					# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
				
			||||||
# time-stamp-start: "scriptversion="
 | 
					# time-stamp-start: "scriptversion="
 | 
				
			||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
					# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
				
			||||||
# time-stamp-time-zone: "UTC0"
 | 
					# time-stamp-time-zone: "UTC"
 | 
				
			||||||
# time-stamp-end: "; # UTC"
 | 
					# time-stamp-end: "; # UTC"
 | 
				
			||||||
# End:
 | 
					# End:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
# Bootstrap configuration.
 | 
					# Bootstrap configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Copyright (C) 2010-2014 Red Hat, Inc.
 | 
					# Copyright (C) 2010-2012 Red Hat, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This library is free software; you can redistribute it and/or
 | 
					# This library is free software; you can redistribute it and/or
 | 
				
			||||||
# modify it under the terms of the GNU Lesser General Public
 | 
					# modify it under the terms of the GNU Lesser General Public
 | 
				
			||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
# This program is distributed in the hope that it will be useful,
 | 
					# This program is distributed in the hope that it will be useful,
 | 
				
			||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					# 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
 | 
					# You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
# License along with this library.  If not, see
 | 
					# License along with this library.  If not, see
 | 
				
			||||||
@@ -20,7 +20,6 @@
 | 
				
			|||||||
gnulib_modules='
 | 
					gnulib_modules='
 | 
				
			||||||
accept
 | 
					accept
 | 
				
			||||||
areadlink
 | 
					areadlink
 | 
				
			||||||
autobuild
 | 
					 | 
				
			||||||
base64
 | 
					base64
 | 
				
			||||||
bind
 | 
					bind
 | 
				
			||||||
bitrotate
 | 
					bitrotate
 | 
				
			||||||
@@ -35,8 +34,8 @@ clock-time
 | 
				
			|||||||
close
 | 
					close
 | 
				
			||||||
connect
 | 
					connect
 | 
				
			||||||
configmake
 | 
					configmake
 | 
				
			||||||
count-leading-zeros
 | 
					 | 
				
			||||||
count-one-bits
 | 
					count-one-bits
 | 
				
			||||||
 | 
					crypto/md5
 | 
				
			||||||
dirname-lgpl
 | 
					dirname-lgpl
 | 
				
			||||||
environ
 | 
					environ
 | 
				
			||||||
execinfo
 | 
					execinfo
 | 
				
			||||||
@@ -52,10 +51,10 @@ func
 | 
				
			|||||||
getaddrinfo
 | 
					getaddrinfo
 | 
				
			||||||
getcwd-lgpl
 | 
					getcwd-lgpl
 | 
				
			||||||
gethostname
 | 
					gethostname
 | 
				
			||||||
getopt-posix
 | 
					 | 
				
			||||||
getpass
 | 
					getpass
 | 
				
			||||||
getpeername
 | 
					getpeername
 | 
				
			||||||
getsockname
 | 
					getsockname
 | 
				
			||||||
 | 
					gettext-h
 | 
				
			||||||
gettimeofday
 | 
					gettimeofday
 | 
				
			||||||
gitlog-to-changelog
 | 
					gitlog-to-changelog
 | 
				
			||||||
gnumakefile
 | 
					gnumakefile
 | 
				
			||||||
@@ -70,10 +69,8 @@ listen
 | 
				
			|||||||
localeconv
 | 
					localeconv
 | 
				
			||||||
maintainer-makefile
 | 
					maintainer-makefile
 | 
				
			||||||
manywarnings
 | 
					manywarnings
 | 
				
			||||||
mgetgroups
 | 
					mkstemp
 | 
				
			||||||
mkdtemp
 | 
					mkstemps
 | 
				
			||||||
mkostemp
 | 
					 | 
				
			||||||
mkostemps
 | 
					 | 
				
			||||||
mktempd
 | 
					mktempd
 | 
				
			||||||
net_if
 | 
					net_if
 | 
				
			||||||
netdb
 | 
					netdb
 | 
				
			||||||
@@ -90,10 +87,9 @@ pthread
 | 
				
			|||||||
pthread_sigmask
 | 
					pthread_sigmask
 | 
				
			||||||
recv
 | 
					recv
 | 
				
			||||||
regex
 | 
					regex
 | 
				
			||||||
 | 
					random_r
 | 
				
			||||||
sched
 | 
					sched
 | 
				
			||||||
secure_getenv
 | 
					 | 
				
			||||||
send
 | 
					send
 | 
				
			||||||
setenv
 | 
					 | 
				
			||||||
setsockopt
 | 
					setsockopt
 | 
				
			||||||
sigaction
 | 
					sigaction
 | 
				
			||||||
sigpipe
 | 
					sigpipe
 | 
				
			||||||
@@ -117,7 +113,6 @@ time_r
 | 
				
			|||||||
timegm
 | 
					timegm
 | 
				
			||||||
ttyname_r
 | 
					ttyname_r
 | 
				
			||||||
uname
 | 
					uname
 | 
				
			||||||
unsetenv
 | 
					 | 
				
			||||||
useless-if-before-free
 | 
					useless-if-before-free
 | 
				
			||||||
usleep
 | 
					usleep
 | 
				
			||||||
vasprintf
 | 
					vasprintf
 | 
				
			||||||
@@ -126,9 +121,18 @@ vc-list-files
 | 
				
			|||||||
vsnprintf
 | 
					vsnprintf
 | 
				
			||||||
waitpid
 | 
					waitpid
 | 
				
			||||||
warnings
 | 
					warnings
 | 
				
			||||||
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
 | 
					SKIP_PO=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Enable copy-mode for MSYS/MinGW. MSYS' ln doesn't work well in the way
 | 
					# Enable copy-mode for MSYS/MinGW. MSYS' ln doesn't work well in the way
 | 
				
			||||||
@@ -137,15 +141,40 @@ if test -n "$MSYSTEM"; then
 | 
				
			|||||||
    copy=true
 | 
					    copy=true
 | 
				
			||||||
fi
 | 
					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:
 | 
					# Tell gnulib to:
 | 
				
			||||||
#   require LGPLv2+
 | 
					#   require LGPLv2+
 | 
				
			||||||
#   apply any local diffs in gnulib/local/ dir
 | 
					#   apply any local diffs in gnulib/local/ dir
 | 
				
			||||||
#   put *.m4 files in m4/ dir
 | 
					#   put *.m4 files in new gnulib/m4/ dir
 | 
				
			||||||
#   put *.[ch] files in new gnulib/lib/ dir
 | 
					#   put *.[ch] files in new gnulib/lib/ dir
 | 
				
			||||||
#   import gnulib tests in new gnulib/tests/ dir
 | 
					#   import gnulib tests in new gnulib/tests/ dir
 | 
				
			||||||
gnulib_name=libgnu
 | 
					gnulib_name=libgnu
 | 
				
			||||||
m4_base=m4
 | 
					m4_base=gnulib/m4
 | 
				
			||||||
source_base=gnulib/lib
 | 
					source_base=gnulib/lib
 | 
				
			||||||
tests_base=gnulib/tests
 | 
					tests_base=gnulib/tests
 | 
				
			||||||
gnulib_tool_option_extras="\
 | 
					gnulib_tool_option_extras="\
 | 
				
			||||||
@@ -157,43 +186,62 @@ gnulib_tool_option_extras="\
 | 
				
			|||||||
"
 | 
					"
 | 
				
			||||||
local_gl_dir=gnulib/local
 | 
					local_gl_dir=gnulib/local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Convince bootstrap to use multiple m4 directories.
 | 
				
			||||||
 | 
					: ${ACLOCAL=aclocal}
 | 
				
			||||||
 | 
					ACLOCAL="$ACLOCAL -I m4"
 | 
				
			||||||
 | 
					export ACLOCAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build prerequisites
 | 
					# Build prerequisites
 | 
				
			||||||
# Note that some of these programs are only required for 'make dist' to
 | 
					# Note that some of these programs are only required for 'make dist' to
 | 
				
			||||||
# succeed from a fresh git checkout; not all of these programs are
 | 
					# succeed from a fresh git checkout; not all of these programs are
 | 
				
			||||||
# required to run 'make dist' on a tarball.
 | 
					# required to run 'make dist' on a tarball.  As a special case, we want
 | 
				
			||||||
 | 
					# to require the equivalent of the Fedora python-devel package, but
 | 
				
			||||||
 | 
					# RHEL 5 lacks the witness python-config package; we hack around that
 | 
				
			||||||
 | 
					# old environment below.
 | 
				
			||||||
buildreq="\
 | 
					buildreq="\
 | 
				
			||||||
autoconf   2.59
 | 
					autoconf   2.59
 | 
				
			||||||
automake   1.9.6
 | 
					automake   1.9.6
 | 
				
			||||||
 | 
					autopoint  -
 | 
				
			||||||
 | 
					gettext    0.17
 | 
				
			||||||
git        1.5.5
 | 
					git        1.5.5
 | 
				
			||||||
gzip       -
 | 
					gzip       -
 | 
				
			||||||
libtool    -
 | 
					libtool    -
 | 
				
			||||||
patch      -
 | 
					patch      -
 | 
				
			||||||
perl       5.5
 | 
					perl       5.5
 | 
				
			||||||
pkg-config -
 | 
					pkg-config -
 | 
				
			||||||
 | 
					python-config -
 | 
				
			||||||
rpcgen     -
 | 
					rpcgen     -
 | 
				
			||||||
tar        -
 | 
					tar        -
 | 
				
			||||||
xmllint	   -
 | 
					xmllint	   -
 | 
				
			||||||
xsltproc   -
 | 
					xsltproc   -
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
 | 
					# Use rpm as a fallback to bypass the bootstrap probe for python-config,
 | 
				
			||||||
 | 
					# for the sake of RHEL 5; without requiring it on newer systems that
 | 
				
			||||||
 | 
					# have python-config to begin with.
 | 
				
			||||||
 | 
					if `(${PYTHON_CONFIG-python-config} --version;
 | 
				
			||||||
 | 
					     test $? -lt 126 || rpm -q python-devel) >/dev/null 2>&1`; then
 | 
				
			||||||
 | 
					  PYTHON_CONFIG=true
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Automake requires that AUTHORS exist.
 | 
					# Automake requires that ChangeLog and AUTHORS exist.
 | 
				
			||||||
touch AUTHORS || exit 1
 | 
					touch AUTHORS ChangeLog || exit 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Override bootstrap's list - we don't use mdate-sh or texinfo.tex.
 | 
					# Override bootstrap's list - we don't use mdate-sh or texinfo.tex.
 | 
				
			||||||
gnulib_extra_files="
 | 
					gnulib_extra_files="
 | 
				
			||||||
        build-aux/install-sh
 | 
					        $build_aux/install-sh
 | 
				
			||||||
        build-aux/depcomp
 | 
					        $build_aux/depcomp
 | 
				
			||||||
        build-aux/config.guess
 | 
					        $build_aux/config.guess
 | 
				
			||||||
        build-aux/config.sub
 | 
					        $build_aux/config.sub
 | 
				
			||||||
        doc/INSTALL
 | 
					        doc/INSTALL
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bootstrap_post_import_hook()
 | 
					bootstrap_epilogue()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  # Change paths in gnulib/tests/gnulib.mk from "../../.." to "../..",
 | 
					  # Change paths in gnulib/tests/gnulib.mk from "../../.." to "../..",
 | 
				
			||||||
  # and make tests conditional by changing "TESTS" to "GNULIB_TESTS".
 | 
					  # then ensure that gnulib/tests/Makefile.in is up-to-date.
 | 
				
			||||||
  m=gnulib/tests/gnulib.mk
 | 
					  m=gnulib/tests/gnulib.mk
 | 
				
			||||||
  sed 's,\.\./\.\./\.\.,../..,g; s/^TESTS /GNULIB_TESTS /' $m > $m-t
 | 
					  sed 's,\.\./\.\./\.\.,../..,g' $m > $m-t
 | 
				
			||||||
  mv -f $m-t $m
 | 
					  mv -f $m-t $m
 | 
				
			||||||
 | 
					  ${AUTOMAKE-automake} gnulib/tests/Makefile
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
#!/usr/bin/env perl
 | 
					#!/usr/bin/perl
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# augeas-gentest.pl: Generate an augeas test file, from an
 | 
					# augeas-gentest.pl: Generate an augeas test file, from an
 | 
				
			||||||
#                    example config file + test file template
 | 
					#                    example config file + test file template
 | 
				
			||||||
@@ -16,6 +16,9 @@
 | 
				
			|||||||
# You should have received a copy of the GNU Lesser General Public
 | 
					# You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
# License along with this library.  If not, see
 | 
					# License along with this library.  If not, see
 | 
				
			||||||
# <http://www.gnu.org/licenses/>.
 | 
					# <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Authors:
 | 
				
			||||||
 | 
					#     Daniel P. Berrange <berrange@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use strict;
 | 
					use strict;
 | 
				
			||||||
use warnings;
 | 
					use warnings;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
					 | 
				
			||||||
@@ -1,161 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/perl
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Validate that header files follow a standard layout:
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# /*
 | 
					 | 
				
			||||||
#  ...copyright header...
 | 
					 | 
				
			||||||
#  */
 | 
					 | 
				
			||||||
# <one blank line>
 | 
					 | 
				
			||||||
# #ifndef SYMBOL
 | 
					 | 
				
			||||||
# # define SYMBOL
 | 
					 | 
				
			||||||
# ....content....
 | 
					 | 
				
			||||||
# #endif /* SYMBOL */
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# For any file ending priv.h, before the #ifndef
 | 
					 | 
				
			||||||
# We will have a further section
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# #ifndef SYMBOL_ALLOW
 | 
					 | 
				
			||||||
# # error ....
 | 
					 | 
				
			||||||
# #endif /* SYMBOL_ALLOW */
 | 
					 | 
				
			||||||
# <one blank line>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use strict;
 | 
					 | 
				
			||||||
use warnings;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my $STATE_COPYRIGHT_COMMENT = 0;
 | 
					 | 
				
			||||||
my $STATE_COPYRIGHT_BLANK = 1;
 | 
					 | 
				
			||||||
my $STATE_PRIV_START = 2;
 | 
					 | 
				
			||||||
my $STATE_PRIV_ERROR = 3;
 | 
					 | 
				
			||||||
my $STATE_PRIV_END = 4;
 | 
					 | 
				
			||||||
my $STATE_PRIV_BLANK = 5;
 | 
					 | 
				
			||||||
my $STATE_GUARD_START = 6;
 | 
					 | 
				
			||||||
my $STATE_GUARD_DEFINE = 7;
 | 
					 | 
				
			||||||
my $STATE_GUARD_END = 8;
 | 
					 | 
				
			||||||
my $STATE_EOF = 9;
 | 
					 | 
				
			||||||
my $STATE_PRAGMA = 10;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my $file = " ";
 | 
					 | 
				
			||||||
my $ret = 0;
 | 
					 | 
				
			||||||
my $ifdef = "";
 | 
					 | 
				
			||||||
my $ifdefpriv = "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my $state = $STATE_EOF;
 | 
					 | 
				
			||||||
my $mistake = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sub mistake {
 | 
					 | 
				
			||||||
    my $msg = shift;
 | 
					 | 
				
			||||||
    warn $msg;
 | 
					 | 
				
			||||||
    $mistake = 1;
 | 
					 | 
				
			||||||
    $ret = 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
while (<>) {
 | 
					 | 
				
			||||||
    if (not $file eq $ARGV) {
 | 
					 | 
				
			||||||
        if ($state == $STATE_COPYRIGHT_COMMENT) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing copyright comment");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_COPYRIGHT_BLANK) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing blank line after copyright header");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_PRIV_START) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#ifndef $ifdefpriv'");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_PRIV_ERROR) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '# error ...priv allow...'");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_PRIV_END) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#endif /* $ifdefpriv */'");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_PRIV_BLANK) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing blank line after priv header check");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_GUARD_START) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#ifndef $ifdef'");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_GUARD_DEFINE) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '# define $ifdef'");
 | 
					 | 
				
			||||||
        } elsif ($state == $STATE_GUARD_END) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#endif /* $ifdef */'");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $ifdef = uc $ARGV;
 | 
					 | 
				
			||||||
        $ifdef =~ s,.*/,,;
 | 
					 | 
				
			||||||
        $ifdef =~ s,[^A-Z0-9],_,g;
 | 
					 | 
				
			||||||
        $ifdef =~ s,__+,_,g;
 | 
					 | 
				
			||||||
        unless ($ifdef =~ /^LIBVIRT_/ && $ARGV !~ /libvirt_internal.h/) {
 | 
					 | 
				
			||||||
            $ifdef = "LIBVIRT_" . $ifdef;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $ifdefpriv = $ifdef . "_ALLOW";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $file = $ARGV;
 | 
					 | 
				
			||||||
        $state = $STATE_COPYRIGHT_COMMENT;
 | 
					 | 
				
			||||||
        $mistake = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($mistake ||
 | 
					 | 
				
			||||||
        $ARGV =~ /config-post\.h$/ ||
 | 
					 | 
				
			||||||
        $ARGV =~ /vbox_(CAPI|XPCOM)/) {
 | 
					 | 
				
			||||||
        $state = $STATE_EOF;
 | 
					 | 
				
			||||||
        next;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($state == $STATE_COPYRIGHT_COMMENT) {
 | 
					 | 
				
			||||||
        if (m,\*/,) {
 | 
					 | 
				
			||||||
            $state = $STATE_COPYRIGHT_BLANK;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_COPYRIGHT_BLANK) {
 | 
					 | 
				
			||||||
        if (! /^$/) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing blank line after copyright header");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ($ARGV =~ /priv\.h$/) {
 | 
					 | 
				
			||||||
            $state = $STATE_PRIV_START;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            $state = $STATE_GUARD_START;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_PRIV_START) {
 | 
					 | 
				
			||||||
        if (/^$/) {
 | 
					 | 
				
			||||||
            &mistake("$file: too many blank lines after copyright header");
 | 
					 | 
				
			||||||
        } elsif (/#ifndef $ifdefpriv$/) {
 | 
					 | 
				
			||||||
            $state = $STATE_PRIV_ERROR;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#ifndef $ifdefpriv'");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_PRIV_ERROR) {
 | 
					 | 
				
			||||||
        if (/# error ".*"$/) {
 | 
					 | 
				
			||||||
            $state = $STATE_PRIV_END;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '# error ...priv allow...'");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_PRIV_END) {
 | 
					 | 
				
			||||||
        if (m,#endif /\* $ifdefpriv \*/,) {
 | 
					 | 
				
			||||||
            $state = $STATE_PRIV_BLANK;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#endif /* $ifdefpriv */'");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_PRIV_BLANK) {
 | 
					 | 
				
			||||||
        if (! /^$/) {
 | 
					 | 
				
			||||||
            &mistake("$file: missing blank line after priv guard");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $state = $STATE_GUARD_START;
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_GUARD_START) {
 | 
					 | 
				
			||||||
        if (/^$/) {
 | 
					 | 
				
			||||||
            &mistake("$file: too many blank lines after copyright header");
 | 
					 | 
				
			||||||
        } elsif(/#pragma once/) {
 | 
					 | 
				
			||||||
            $state = $STATE_PRAGMA;
 | 
					 | 
				
			||||||
        } elsif (/#ifndef $ifdef$/) {
 | 
					 | 
				
			||||||
            $state = $STATE_GUARD_DEFINE;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '#ifndef $ifdef'");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_GUARD_DEFINE) {
 | 
					 | 
				
			||||||
        if (/# define $ifdef$/) {
 | 
					 | 
				
			||||||
            $state = $STATE_GUARD_END;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            &mistake("$file: missing '# define $ifdef'");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_GUARD_END) {
 | 
					 | 
				
			||||||
        if (m,#endif /\* $ifdef \*/$,) {
 | 
					 | 
				
			||||||
            $state = $STATE_EOF;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_PRAGMA) {
 | 
					 | 
				
			||||||
        next;
 | 
					 | 
				
			||||||
    } elsif ($state == $STATE_EOF) {
 | 
					 | 
				
			||||||
        die "$file: unexpected content after '#endif /* $ifdef */'";
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        die "$file: unexpected state $state";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
exit $ret;
 | 
					 | 
				
			||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/perl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my @block;
 | 
					 | 
				
			||||||
my $msgstr = 0;
 | 
					 | 
				
			||||||
my $empty = 0;
 | 
					 | 
				
			||||||
my $unused = 0;
 | 
					 | 
				
			||||||
my $fuzzy = 0;
 | 
					 | 
				
			||||||
while (<>) {
 | 
					 | 
				
			||||||
    if (/^$/) {
 | 
					 | 
				
			||||||
        if (!$empty && !$unused && !$fuzzy) {
 | 
					 | 
				
			||||||
            print @block;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        @block = ();
 | 
					 | 
				
			||||||
        $msgstr = 0;
 | 
					 | 
				
			||||||
        $fuzzy = 0;
 | 
					 | 
				
			||||||
        push @block, $_;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        if (/^msgstr/) {
 | 
					 | 
				
			||||||
            $msgstr = 1;
 | 
					 | 
				
			||||||
            $empty = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (/^#.*fuzzy/) {
 | 
					 | 
				
			||||||
            $fuzzy = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (/^#~ msgstr/) {
 | 
					 | 
				
			||||||
            $unused = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ($msgstr && /".+"/) {
 | 
					 | 
				
			||||||
            $empty = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        push @block, $_;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (@block && !$empty && !$unused) {
 | 
					 | 
				
			||||||
    print @block;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,75 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env perl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my %noninlined;
 | 
					 | 
				
			||||||
my %mocked;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Functions in public header don't get the noinline annotation
 | 
					 | 
				
			||||||
# so whitelist them here
 | 
					 | 
				
			||||||
$noninlined{"virEventAddTimeout"} = 1;
 | 
					 | 
				
			||||||
# This one confuses the script as its defined in the mock file
 | 
					 | 
				
			||||||
# but is actually just a local helper
 | 
					 | 
				
			||||||
$noninlined{"virMockStatRedirect"} = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
foreach my $arg (@ARGV) {
 | 
					 | 
				
			||||||
    if ($arg =~ /\.h$/) {
 | 
					 | 
				
			||||||
        #print "Scan header $arg\n";
 | 
					 | 
				
			||||||
        &scan_annotations($arg);
 | 
					 | 
				
			||||||
    } elsif ($arg =~ /mock\.c$/) {
 | 
					 | 
				
			||||||
        #print "Scan mock $arg\n";
 | 
					 | 
				
			||||||
        &scan_overrides($arg);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my $warned = 0;
 | 
					 | 
				
			||||||
foreach my $func (keys %mocked) {
 | 
					 | 
				
			||||||
    next if exists $noninlined{$func};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $warned++;
 | 
					 | 
				
			||||||
    print STDERR "$func is mocked at $mocked{$func} but missing noinline annotation\n";
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exit $warned ? 1 : 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sub scan_annotations {
 | 
					 | 
				
			||||||
    my $file = shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    open FH, $file or die "cannot read $file: $!";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    my $func;
 | 
					 | 
				
			||||||
    while (<FH>) {
 | 
					 | 
				
			||||||
        if (/^\s*(\w+)\(/ || /^(?:\w+\*?\s+)+(?:\*\s*)?(\w+)\(/) {
 | 
					 | 
				
			||||||
            my $name = $1;
 | 
					 | 
				
			||||||
            if ($name !~ /ATTRIBUTE/) {
 | 
					 | 
				
			||||||
                $func = $name;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } elsif (/^\s*$/) {
 | 
					 | 
				
			||||||
            $func = undef;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (/ATTRIBUTE_NOINLINE/) {
 | 
					 | 
				
			||||||
            if (defined $func) {
 | 
					 | 
				
			||||||
                $noninlined{$func} = 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    close FH
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sub scan_overrides {
 | 
					 | 
				
			||||||
    my $file = shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    open FH, $file or die "cannot read $file: $!";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    my $func;
 | 
					 | 
				
			||||||
    while (<FH>) {
 | 
					 | 
				
			||||||
        if (/^(\w+)\(/ || /^\w+\s*(?:\*\s*)?(\w+)\(/) {
 | 
					 | 
				
			||||||
            my $name = $1;
 | 
					 | 
				
			||||||
            if ($name =~ /^vir/) {
 | 
					 | 
				
			||||||
                $mocked{$name} = "$file:$.";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    close FH
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env perl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use strict;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
my $file = " ";
 | 
					 | 
				
			||||||
my $ret = 0;
 | 
					 | 
				
			||||||
my %includes = ( );
 | 
					 | 
				
			||||||
my $lineno = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
while (<>) {
 | 
					 | 
				
			||||||
    if (not $file eq $ARGV) {
 | 
					 | 
				
			||||||
        %includes = ( );
 | 
					 | 
				
			||||||
        $file = $ARGV;
 | 
					 | 
				
			||||||
        $lineno = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $lineno++;
 | 
					 | 
				
			||||||
    if (/^# *include *[<"]([^>"]*\.h)[">]/) {
 | 
					 | 
				
			||||||
        $includes{$1}++;
 | 
					 | 
				
			||||||
        if ($includes{$1} == 2) {
 | 
					 | 
				
			||||||
            $ret = 1;
 | 
					 | 
				
			||||||
            print STDERR "$ARGV:$lineno: $_";
 | 
					 | 
				
			||||||
            print STDERR "Do not include a header more than once per file\n";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
exit $ret;
 | 
					 | 
				
			||||||
@@ -1,91 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (C) 2013 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/>.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Since virt-login-shell will be setuid, we must do everything
 | 
					 | 
				
			||||||
 * we can to avoid linking to other libraries. Many of them do
 | 
					 | 
				
			||||||
 * unsafe things in functions marked __attribute__((constructor)).
 | 
					 | 
				
			||||||
 * The only way to avoid such deps is to re-compile the
 | 
					 | 
				
			||||||
 * functions with the code in question disabled, and for that we
 | 
					 | 
				
			||||||
 * must override the main config.h rules. Hence this file :-(
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef LIBVIRT_SETUID_RPC_CLIENT
 | 
					 | 
				
			||||||
# undef HAVE_LIBNL
 | 
					 | 
				
			||||||
# undef HAVE_LIBNL3
 | 
					 | 
				
			||||||
# undef HAVE_LIBSASL2
 | 
					 | 
				
			||||||
# undef HAVE_SYS_ACL_H
 | 
					 | 
				
			||||||
# undef WITH_CAPNG
 | 
					 | 
				
			||||||
# undef WITH_CURL
 | 
					 | 
				
			||||||
# undef WITH_DBUS
 | 
					 | 
				
			||||||
# undef WITH_DEVMAPPER
 | 
					 | 
				
			||||||
# undef WITH_DTRACE_PROBES
 | 
					 | 
				
			||||||
# undef WITH_GNUTLS
 | 
					 | 
				
			||||||
# undef WITH_LIBSSH
 | 
					 | 
				
			||||||
# undef WITH_MACVTAP
 | 
					 | 
				
			||||||
# undef WITH_NUMACTL
 | 
					 | 
				
			||||||
# undef WITH_SASL
 | 
					 | 
				
			||||||
# undef WITH_SSH2
 | 
					 | 
				
			||||||
# undef WITH_SYSTEMD_DAEMON
 | 
					 | 
				
			||||||
# undef WITH_VIRTUALPORT
 | 
					 | 
				
			||||||
# undef WITH_YAJL
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * With the NSS module it's the same story as virt-login-shell. See the
 | 
					 | 
				
			||||||
 * explanation above.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifdef LIBVIRT_NSS
 | 
					 | 
				
			||||||
# undef HAVE_LIBNL
 | 
					 | 
				
			||||||
# undef HAVE_LIBNL3
 | 
					 | 
				
			||||||
# undef HAVE_LIBSASL2
 | 
					 | 
				
			||||||
# undef HAVE_SYS_ACL_H
 | 
					 | 
				
			||||||
# undef WITH_CAPNG
 | 
					 | 
				
			||||||
# undef WITH_CURL
 | 
					 | 
				
			||||||
# undef WITH_DEVMAPPER
 | 
					 | 
				
			||||||
# undef WITH_DTRACE_PROBES
 | 
					 | 
				
			||||||
# undef WITH_GNUTLS
 | 
					 | 
				
			||||||
# undef WITH_LIBSSH
 | 
					 | 
				
			||||||
# undef WITH_MACVTAP
 | 
					 | 
				
			||||||
# undef WITH_NUMACTL
 | 
					 | 
				
			||||||
# undef WITH_SASL
 | 
					 | 
				
			||||||
# undef WITH_SSH2
 | 
					 | 
				
			||||||
# undef WITH_VIRTUALPORT
 | 
					 | 
				
			||||||
# undef WITH_SECDRIVER_SELINUX
 | 
					 | 
				
			||||||
# undef WITH_SECDRIVER_APPARMOR
 | 
					 | 
				
			||||||
#endif /* LIBVIRT_NSS */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __GNUC__
 | 
					 | 
				
			||||||
# error "Libvirt requires GCC >= 4.4, 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.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifndef __GNUC_PREREQ
 | 
					 | 
				
			||||||
# define __GNUC_PREREQ(maj, min) \
 | 
					 | 
				
			||||||
    ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !(__GNUC_PREREQ(4, 4) || defined(__clang__))
 | 
					 | 
				
			||||||
# error "Libvirt requires GCC >= 4.4, or CLang"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										3591
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										3591
									
								
								configure.ac
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										403
									
								
								daemon/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								daemon/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,403 @@
 | 
				
			|||||||
 | 
					## Process this file with automake to produce Makefile.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Copyright (C) 2005-2013 Red Hat, Inc.
 | 
				
			||||||
 | 
					## See COPYING.LIB for the License of this software
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INCLUDES = \
 | 
				
			||||||
 | 
						-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
 | 
				
			||||||
 | 
						-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 \
 | 
				
			||||||
 | 
						$(GETTEXT_CPPFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLEANFILES =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DAEMON_GENERATED =					\
 | 
				
			||||||
 | 
							$(srcdir)/remote_dispatch.h		\
 | 
				
			||||||
 | 
							$(srcdir)/qemu_dispatch.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DAEMON_SOURCES =					\
 | 
				
			||||||
 | 
							libvirtd.c libvirtd.h			\
 | 
				
			||||||
 | 
							libvirtd-config.c libvirtd-config.h	\
 | 
				
			||||||
 | 
							remote.c remote.h			\
 | 
				
			||||||
 | 
							stream.c stream.h			\
 | 
				
			||||||
 | 
							../src/remote/remote_protocol.c		\
 | 
				
			||||||
 | 
							../src/remote/qemu_protocol.c		\
 | 
				
			||||||
 | 
							$(DAEMON_GENERATED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DISTCLEANFILES =
 | 
				
			||||||
 | 
					EXTRA_DIST =						\
 | 
				
			||||||
 | 
						remote_dispatch.h				\
 | 
				
			||||||
 | 
						qemu_dispatch.h					\
 | 
				
			||||||
 | 
						libvirtd.conf					\
 | 
				
			||||||
 | 
						libvirtd.init.in				\
 | 
				
			||||||
 | 
						libvirtd.upstart				\
 | 
				
			||||||
 | 
						libvirtd.policy-0				\
 | 
				
			||||||
 | 
						libvirtd.policy-1				\
 | 
				
			||||||
 | 
						libvirtd.sasl					\
 | 
				
			||||||
 | 
						libvirtd.sysconf				\
 | 
				
			||||||
 | 
						libvirtd.sysctl					\
 | 
				
			||||||
 | 
						libvirtd.aug                                    \
 | 
				
			||||||
 | 
						libvirtd.logrotate.in                           \
 | 
				
			||||||
 | 
						libvirtd.qemu.logrotate.in                      \
 | 
				
			||||||
 | 
						libvirtd.lxc.logrotate.in                       \
 | 
				
			||||||
 | 
						libvirtd.uml.logrotate.in                       \
 | 
				
			||||||
 | 
						test_libvirtd.aug.in                             \
 | 
				
			||||||
 | 
						THREADS.txt					\
 | 
				
			||||||
 | 
						libvirtd.pod.in					\
 | 
				
			||||||
 | 
						libvirtd.8.in					\
 | 
				
			||||||
 | 
						$(DAEMON_SOURCES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BUILT_SOURCES =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
 | 
				
			||||||
 | 
					QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
 | 
				
			||||||
 | 
							$(REMOTE_PROTOCOL)
 | 
				
			||||||
 | 
						$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b remote REMOTE \
 | 
				
			||||||
 | 
						  $(REMOTE_PROTOCOL) > $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
 | 
				
			||||||
 | 
							$(QEMU_PROTOCOL)
 | 
				
			||||||
 | 
						$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b qemu QEMU \
 | 
				
			||||||
 | 
						  $(QEMU_PROTOCOL) > $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_LIBVIRTD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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) $(POLKIT_CFLAGS) $(DBUS_CFLAGS) $(LIBNL_CFLAGS) \
 | 
				
			||||||
 | 
						$(WARN_CFLAGS) \
 | 
				
			||||||
 | 
						$(COVERAGE_CFLAGS) \
 | 
				
			||||||
 | 
						-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvirtd_LDFLAGS =					\
 | 
				
			||||||
 | 
						$(WARN_CFLAGS)					\
 | 
				
			||||||
 | 
						$(COVERAGE_LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvirtd_LDADD =					\
 | 
				
			||||||
 | 
						$(LIBXML_LIBS)					\
 | 
				
			||||||
 | 
						$(GNUTLS_LIBS)					\
 | 
				
			||||||
 | 
						$(SASL_LIBS)					\
 | 
				
			||||||
 | 
						$(DBUS_LIBS)					\
 | 
				
			||||||
 | 
						$(POLKIT_LIBS)					\
 | 
				
			||||||
 | 
						$(LIBNL_LIBS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_DTRACE_PROBES
 | 
				
			||||||
 | 
					libvirtd_LDADD += ../src/libvirt_probes.lo
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvirtd_LDADD += \
 | 
				
			||||||
 | 
						../src/libvirt-qemu.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_LXC
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_lxc.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_XEN
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_xen.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_LIBXL
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_libxl.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_UML
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_uml.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_STORAGE
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_storage.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_NETWORK
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_network.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_INTERFACE
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_interface.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_NODE_DEVICES
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_nodedev.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_SECRETS
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_secret.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if WITH_NWFILTER
 | 
				
			||||||
 | 
					    libvirtd_LDADD += ../src/libvirt_driver_nwfilter.la
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvirtd_LDADD += ../src/libvirt.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if HAVE_POLKIT
 | 
				
			||||||
 | 
					if HAVE_POLKIT0
 | 
				
			||||||
 | 
					policydir = $(datadir)/PolicyKit/policy
 | 
				
			||||||
 | 
					policyfile = libvirtd.policy-0
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					policydir = $(datadir)/polkit-1/actions
 | 
				
			||||||
 | 
					policyfile = libvirtd.policy-1
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 HAVE_POLKIT
 | 
				
			||||||
 | 
					install-data-polkit::
 | 
				
			||||||
 | 
						$(MKDIR_P) $(DESTDIR)$(policydir)
 | 
				
			||||||
 | 
						$(INSTALL_DATA) $(srcdir)/$(policyfile) $(DESTDIR)$(policydir)/org.libvirt.unix.policy
 | 
				
			||||||
 | 
					uninstall-data-polkit::
 | 
				
			||||||
 | 
						rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
 | 
				
			||||||
 | 
						rmdir $(DESTDIR)$(policydir) || :
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					install-data-polkit::
 | 
				
			||||||
 | 
					uninstall-data-polkit::
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					remote.c: $(DAEMON_GENERATED)
 | 
				
			||||||
 | 
					remote.h: $(DAEMON_GENERATED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOGROTATE_CONFS = libvirtd.qemu.logrotate libvirtd.lxc.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.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.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.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/libvirtd.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uninstall-sysctl:
 | 
				
			||||||
 | 
						rm -f $(DESTDIR)$(prefix)/lib/sysctl.d/libvirtd.conf
 | 
				
			||||||
 | 
						rmdir $(DESTDIR)$(prefix)/lib/sysctl.d || :
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					install-sysctl:
 | 
				
			||||||
 | 
					uninstall-sysctl:
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					install-init-upstart:
 | 
				
			||||||
 | 
					uninstall-init-upstart:
 | 
				
			||||||
 | 
					endif # LIBVIRT_INIT_SCRIPT_UPSTART
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXTRA_DIST += libvirtd.service.in
 | 
				
			||||||
 | 
					if LIBVIRT_INIT_SCRIPT_SYSTEMD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SYSTEMD_UNIT_DIR = /lib/systemd/system
 | 
				
			||||||
 | 
					BUILT_SOURCES += libvirtd.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install-init-systemd: install-sysconfig libvirtd.service
 | 
				
			||||||
 | 
						$(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR)
 | 
				
			||||||
 | 
						$(INSTALL_DATA) libvirtd.service \
 | 
				
			||||||
 | 
						  $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uninstall-init-systemd: uninstall-sysconfig
 | 
				
			||||||
 | 
						rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
 | 
				
			||||||
 | 
						rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || :
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					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 $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
						$(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 HAVE_SASL
 | 
				
			||||||
 | 
					install-data-sasl:
 | 
				
			||||||
 | 
						$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sasl2/
 | 
				
			||||||
 | 
						$(INSTALL_DATA) $(srcdir)/libvirtd.sasl $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uninstall-data-sasl:
 | 
				
			||||||
 | 
						rm -f $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
 | 
				
			||||||
 | 
						rmdir $(DESTDIR)$(sysconfdir)/sasl2/ || :
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					install-data-sasl:
 | 
				
			||||||
 | 
					uninstall-data-sasl:
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLEANFILES += $(BUILT_SOURCES) $(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 onto the 'dx' job queue for the
 | 
				
			||||||
 | 
					associated client object. The job condition will be signalled and
 | 
				
			||||||
 | 
					a worker will wakup and process it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The worker thread must quickly drop its locks on the server and
 | 
				
			||||||
 | 
					client to allow the main event loop thread to continue running
 | 
				
			||||||
 | 
					with its other work. Critically important, is that now libvirt
 | 
				
			||||||
 | 
					API call will ever be made with the server or client locks held.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- End
 | 
				
			||||||
							
								
								
									
										492
									
								
								daemon/libvirtd-config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										492
									
								
								daemon/libvirtd-config.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,492 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * libvirtd.c: daemon start of day, guest process & i/o management
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2006-2012 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 "conf.h"
 | 
				
			||||||
 | 
					#include "memory.h"
 | 
				
			||||||
 | 
					#include "virterror_internal.h"
 | 
				
			||||||
 | 
					#include "logging.h"
 | 
				
			||||||
 | 
					#include "rpc/virnetserver.h"
 | 
				
			||||||
 | 
					#include "configmake.h"
 | 
				
			||||||
 | 
					#include "remote/remote_protocol.h"
 | 
				
			||||||
 | 
					#include "remote/remote_driver.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VIR_FROM_THIS VIR_FROM_CONF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        list[0] = strdup (p->str);
 | 
				
			||||||
 | 
					        list[1] = NULL;
 | 
				
			||||||
 | 
					        if (list[0] == NULL) {
 | 
				
			||||||
 | 
					            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
				
			||||||
 | 
					                           _("failed to allocate memory for %s config list value"),
 | 
				
			||||||
 | 
					                           key);
 | 
				
			||||||
 | 
					            VIR_FREE(list);
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case VIR_CONF_LIST: {
 | 
				
			||||||
 | 
					        int i, len = 0;
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            list[i] = strdup (pp->str);
 | 
				
			||||||
 | 
					            if (list[i] == NULL) {
 | 
				
			||||||
 | 
					                int j;
 | 
				
			||||||
 | 
					                for (j = 0 ; j < i ; j++)
 | 
				
			||||||
 | 
					                    VIR_FREE(list[j]);
 | 
				
			||||||
 | 
					                VIR_FREE(list);
 | 
				
			||||||
 | 
					                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 | 
				
			||||||
 | 
					                               _("failed to allocate memory for %s config list value"),
 | 
				
			||||||
 | 
					                               key);
 | 
				
			||||||
 | 
					                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,
 | 
				
			||||||
 | 
					                       virConfTypeName (p->type),
 | 
				
			||||||
 | 
					                       virConfTypeName (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 strdup succeeds,
 | 
				
			||||||
 | 
					   store the result in var_name.  Otherwise, (i.e. invalid type, or 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 (!(data->var_name = strdup (p->str))) {                  \
 | 
				
			||||||
 | 
					                virReportOOMError();                                    \
 | 
				
			||||||
 | 
					                goto error;                                             \
 | 
				
			||||||
 | 
					            }                                                           \
 | 
				
			||||||
 | 
					        }                                                               \
 | 
				
			||||||
 | 
					    } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Like GET_CONF_STR, but for integral values.  */
 | 
				
			||||||
 | 
					#define GET_CONF_INT(conf, filename, var_name)                          \
 | 
				
			||||||
 | 
					    do {                                                                \
 | 
				
			||||||
 | 
					        virConfValuePtr p = virConfGetValue (conf, #var_name);          \
 | 
				
			||||||
 | 
					        if (p) {                                                        \
 | 
				
			||||||
 | 
					            if (checkType (p, filename, #var_name, VIR_CONF_LONG) < 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 HAVE_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 (!(*configfile = strdup(SYSCONFDIR "/libvirt/libvirtd.conf")))
 | 
				
			||||||
 | 
					            goto no_memory;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        char *configdir = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!(configdir = virGetUserConfigDirectory()))
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (virAsprintf(configfile, "%s/libvirtd.conf", configdir) < 0) {
 | 
				
			||||||
 | 
					            VIR_FREE(configdir);
 | 
				
			||||||
 | 
					            goto no_memory;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        VIR_FREE(configdir);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					no_memory:
 | 
				
			||||||
 | 
					    virReportOOMError();
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct daemonConfig*
 | 
				
			||||||
 | 
					daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct daemonConfig *data;
 | 
				
			||||||
 | 
					    char *localhost;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (VIR_ALLOC(data) < 0) {
 | 
				
			||||||
 | 
					        virReportOOMError();
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data->listen_tls = 1;
 | 
				
			||||||
 | 
					    data->listen_tcp = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(data->tls_port = strdup(LIBVIRTD_TLS_PORT)))
 | 
				
			||||||
 | 
					        goto no_memory;
 | 
				
			||||||
 | 
					    if (!(data->tcp_port = strdup(LIBVIRTD_TCP_PORT)))
 | 
				
			||||||
 | 
					        goto no_memory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Only default to PolicyKit if running as root */
 | 
				
			||||||
 | 
					#if HAVE_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 HAVE_POLKIT
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT)
 | 
				
			||||||
 | 
					        data->unix_sock_rw_perms = strdup("0777"); /* Allow world */
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        data->unix_sock_rw_perms = strdup("0700"); /* Allow user only */
 | 
				
			||||||
 | 
					    data->unix_sock_ro_perms = strdup("0777"); /* Always allow world */
 | 
				
			||||||
 | 
					    if (!data->unix_sock_ro_perms ||
 | 
				
			||||||
 | 
					        !data->unix_sock_rw_perms)
 | 
				
			||||||
 | 
					        goto no_memory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if HAVE_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 = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data->prio_workers = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data->max_requests = 20;
 | 
				
			||||||
 | 
					    data->max_client_requests = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data->log_buffer_size = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data->audit_level = 1;
 | 
				
			||||||
 | 
					    data->audit_logging = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data->keepalive_interval = 5;
 | 
				
			||||||
 | 
					    data->keepalive_count = 5;
 | 
				
			||||||
 | 
					    data->keepalive_required = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    localhost = virGetHostname(NULL);
 | 
				
			||||||
 | 
					    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 = virAsprintf(&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 no_memory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					no_memory:
 | 
				
			||||||
 | 
					    virReportOOMError();
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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_INT (conf, filename, listen_tcp);
 | 
				
			||||||
 | 
					    GET_CONF_INT (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 HAVE_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 (!(data->unix_sock_rw_perms = strdup("0777"))) {
 | 
				
			||||||
 | 
					            virReportOOMError();
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_STR (conf, filename, unix_sock_group);
 | 
				
			||||||
 | 
					    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_INT (conf, filename, mdns_adv);
 | 
				
			||||||
 | 
					    GET_CONF_STR (conf, filename, mdns_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
 | 
				
			||||||
 | 
					    GET_CONF_INT (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_INT (conf, filename, min_workers);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, max_workers);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, max_clients);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, prio_workers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, max_requests);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, max_client_requests);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, audit_level);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, audit_logging);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_STR (conf, filename, host_uuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, log_level);
 | 
				
			||||||
 | 
					    GET_CONF_STR (conf, filename, log_filters);
 | 
				
			||||||
 | 
					    GET_CONF_STR (conf, filename, log_outputs);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, log_buffer_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, keepalive_interval);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, keepalive_count);
 | 
				
			||||||
 | 
					    GET_CONF_INT (conf, filename, keepalive_required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Read the config file if it exists.
 | 
				
			||||||
 | 
					 * Only used in the remote case, hence the name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					daemonConfigLoadFile(struct daemonConfig *data,
 | 
				
			||||||
 | 
					                     const char *filename,
 | 
				
			||||||
 | 
					                     bool allow_missing)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    virConfPtr conf;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (allow_missing &&
 | 
				
			||||||
 | 
					        access(filename, R_OK) == -1 &&
 | 
				
			||||||
 | 
					        errno == ENOENT)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conf = virConfReadFile(filename, 0);
 | 
				
			||||||
 | 
					    if (!conf)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = daemonConfigLoadOptions(data, filename, conf);
 | 
				
			||||||
 | 
					    virConfFree(conf);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int daemonConfigLoadData(struct daemonConfig *data,
 | 
				
			||||||
 | 
					                         const char *filename,
 | 
				
			||||||
 | 
					                         const char *filedata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    virConfPtr conf;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conf = virConfReadMem(filedata, strlen(filedata), 0);
 | 
				
			||||||
 | 
					    if (!conf)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = daemonConfigLoadOptions(data, filename, conf);
 | 
				
			||||||
 | 
					    virConfFree(conf);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										94
									
								
								daemon/libvirtd-config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								daemon/libvirtd-config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * libvirtd.c: daemon start of day, guest process & i/o management
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2006-2012 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_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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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 prio_workers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int max_requests;
 | 
				
			||||||
 | 
					    int max_client_requests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int log_level;
 | 
				
			||||||
 | 
					    char *log_filters;
 | 
				
			||||||
 | 
					    char *log_outputs;
 | 
				
			||||||
 | 
					    int log_buffer_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int audit_level;
 | 
				
			||||||
 | 
					    int audit_logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int keepalive_interval;
 | 
				
			||||||
 | 
					    unsigned int keepalive_count;
 | 
				
			||||||
 | 
					    int keepalive_required;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int daemonConfigFilePath(bool privileged, char **configfile);
 | 
				
			||||||
 | 
					struct daemonConfig* daemonConfigNew(bool privileged);
 | 
				
			||||||
 | 
					void daemonConfigFree(struct daemonConfig *data);
 | 
				
			||||||
 | 
					int daemonConfigLoadFile(struct daemonConfig *data,
 | 
				
			||||||
 | 
					                         const char *filename,
 | 
				
			||||||
 | 
					                         bool allow_missing);
 | 
				
			||||||
 | 
					int daemonConfigLoadData(struct daemonConfig *data,
 | 
				
			||||||
 | 
					                         const char *filename,
 | 
				
			||||||
 | 
					                         const char *filedata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __LIBVIRTD_CONFIG_H__ */
 | 
				
			||||||
@@ -13,7 +13,7 @@ module Libvirtd =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
   let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
 | 
					   let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
 | 
				
			||||||
   let bool_val = store /0|1/
 | 
					   let bool_val = store /0|1/
 | 
				
			||||||
   let int_val = store /-?[0-9]+/
 | 
					   let int_val = store /[0-9]+/
 | 
				
			||||||
   let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ ""
 | 
					   let str_array_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_array_val = counter "el" . array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +35,6 @@ module Libvirtd =
 | 
				
			|||||||
   let sock_acl_entry = str_entry "unix_sock_group"
 | 
					   let sock_acl_entry = str_entry "unix_sock_group"
 | 
				
			||||||
                      | str_entry "unix_sock_ro_perms"
 | 
					                      | str_entry "unix_sock_ro_perms"
 | 
				
			||||||
                      | str_entry "unix_sock_rw_perms"
 | 
					                      | str_entry "unix_sock_rw_perms"
 | 
				
			||||||
                      | str_entry "unix_sock_admin_perms"
 | 
					 | 
				
			||||||
                      | str_entry "unix_sock_dir"
 | 
					                      | str_entry "unix_sock_dir"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   let authentication_entry = str_entry "auth_unix_ro"
 | 
					   let authentication_entry = str_entry "auth_unix_ro"
 | 
				
			||||||
@@ -52,26 +51,18 @@ module Libvirtd =
 | 
				
			|||||||
                           | bool_entry "tls_no_sanity_certificate"
 | 
					                           | bool_entry "tls_no_sanity_certificate"
 | 
				
			||||||
                           | str_array_entry "tls_allowed_dn_list"
 | 
					                           | str_array_entry "tls_allowed_dn_list"
 | 
				
			||||||
                           | str_array_entry "sasl_allowed_username_list"
 | 
					                           | str_array_entry "sasl_allowed_username_list"
 | 
				
			||||||
                           | str_array_entry "access_drivers"
 | 
					 | 
				
			||||||
                           | str_entry "tls_priority"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   let processing_entry = int_entry "min_workers"
 | 
					   let processing_entry = int_entry "min_workers"
 | 
				
			||||||
                        | int_entry "max_workers"
 | 
					                        | int_entry "max_workers"
 | 
				
			||||||
                        | int_entry "max_clients"
 | 
					                        | int_entry "max_clients"
 | 
				
			||||||
                        | int_entry "max_queued_clients"
 | 
					                        | int_entry "max_requests"
 | 
				
			||||||
                        | int_entry "max_anonymous_clients"
 | 
					 | 
				
			||||||
                        | int_entry "max_client_requests"
 | 
					                        | int_entry "max_client_requests"
 | 
				
			||||||
                        | int_entry "prio_workers"
 | 
					                        | 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"
 | 
					   let logging_entry = int_entry "log_level"
 | 
				
			||||||
                     | str_entry "log_filters"
 | 
					                     | str_entry "log_filters"
 | 
				
			||||||
                     | str_entry "log_outputs"
 | 
					                     | str_entry "log_outputs"
 | 
				
			||||||
 | 
					                     | int_entry "log_buffer_size"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   let auditing_entry = int_entry "audit_level"
 | 
					   let auditing_entry = int_entry "audit_level"
 | 
				
			||||||
                      | bool_entry "audit_logging"
 | 
					                      | bool_entry "audit_logging"
 | 
				
			||||||
@@ -80,13 +71,7 @@ module Libvirtd =
 | 
				
			|||||||
                       | int_entry "keepalive_count"
 | 
					                       | int_entry "keepalive_count"
 | 
				
			||||||
                       | bool_entry "keepalive_required"
 | 
					                       | 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"
 | 
					   let misc_entry = str_entry "host_uuid"
 | 
				
			||||||
                  | str_entry "host_uuid_source"
 | 
					 | 
				
			||||||
                  | int_entry "ovs_timeout"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   (* Each enty in the config is one of the following three ... *)
 | 
					   (* Each enty in the config is one of the following three ... *)
 | 
				
			||||||
   let entry = network_entry
 | 
					   let entry = network_entry
 | 
				
			||||||
@@ -95,11 +80,9 @@ module Libvirtd =
 | 
				
			|||||||
             | certificate_entry
 | 
					             | certificate_entry
 | 
				
			||||||
             | authorization_entry
 | 
					             | authorization_entry
 | 
				
			||||||
             | processing_entry
 | 
					             | processing_entry
 | 
				
			||||||
             | admin_processing_entry
 | 
					 | 
				
			||||||
             | logging_entry
 | 
					             | logging_entry
 | 
				
			||||||
             | auditing_entry
 | 
					             | auditing_entry
 | 
				
			||||||
             | keepalive_entry
 | 
					             | keepalive_entry
 | 
				
			||||||
             | admin_keepalive_entry
 | 
					 | 
				
			||||||
             | misc_entry
 | 
					             | misc_entry
 | 
				
			||||||
   let comment = [ label "#comment" . del /#[ \t]*/ "# " .  store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
 | 
					   let comment = [ label "#comment" . del /#[ \t]*/ "# " .  store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
 | 
				
			||||||
   let empty = [ label "#empty" . eol ]
 | 
					   let empty = [ label "#empty" . eol ]
 | 
				
			||||||
							
								
								
									
										1377
									
								
								daemon/libvirtd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1377
									
								
								daemon/libvirtd.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										395
									
								
								daemon/libvirtd.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								daemon/libvirtd.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,395 @@
 | 
				
			|||||||
 | 
					# Master libvirt daemon configuration file
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# For further information consult http://libvirt.org/format.html
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# NOTE: the tests/daemon-conf regression test script requires
 | 
				
			||||||
 | 
					# that each "PARAMETER = VALUE" line in this file have the parameter
 | 
				
			||||||
 | 
					# name just after a leading "#".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Network connectivity controls
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Flag listening for secure TLS connections on the public TCP/IP port.
 | 
				
			||||||
 | 
					# NB, must pass the --listen flag to the libvirtd process for this to
 | 
				
			||||||
 | 
					# have any effect.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# It is necessary to setup a CA and issue server certificates before
 | 
				
			||||||
 | 
					# using this capability.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is enabled by default, uncomment this to disable it
 | 
				
			||||||
 | 
					#listen_tls = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Listen for unencrypted TCP connections on the public TCP/IP port.
 | 
				
			||||||
 | 
					# NB, must pass the --listen flag to the libvirtd process for this to
 | 
				
			||||||
 | 
					# have any effect.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Using the TCP socket requires SASL authentication by default. Only
 | 
				
			||||||
 | 
					# SASL mechanisms which support data encryption are allowed. This is
 | 
				
			||||||
 | 
					# DIGEST_MD5 and GSSAPI (Kerberos5)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is disabled by default, uncomment this to enable it.
 | 
				
			||||||
 | 
					#listen_tcp = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the port for accepting secure TLS connections
 | 
				
			||||||
 | 
					# This can be a port number, or service name
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#tls_port = "16514"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the port for accepting insecure TCP connections
 | 
				
			||||||
 | 
					# This can be a port number, or service name
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#tcp_port = "16509"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the default configuration which binds to all network
 | 
				
			||||||
 | 
					# interfaces. This can be a numeric IPv4/6 address, or hostname
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#listen_addr = "192.168.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Flag toggling mDNS advertizement of the libvirt service.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Alternatively can disable for all services on a host by
 | 
				
			||||||
 | 
					# stopping the Avahi daemon
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is 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 subsituted for the short hostname of the machine (without domain)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#mdns_name = "Virtualization Host Joe Demo"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# UNIX socket access controls
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set the UNIX domain socket group ownership. This can be used to
 | 
				
			||||||
 | 
					# allow a 'trusted' set of users access to management capabilities
 | 
				
			||||||
 | 
					# without becoming root.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is restricted to 'root' by default.
 | 
				
			||||||
 | 
					#unix_sock_group = "libvirt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set the UNIX socket permissions for the R/O socket. This is used
 | 
				
			||||||
 | 
					# for monitoring VM status only
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Default allows any user. If setting group ownership may want to
 | 
				
			||||||
 | 
					# restrict this to:
 | 
				
			||||||
 | 
					#unix_sock_ro_perms = "0777"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set the UNIX socket permissions for the R/W socket. This is used
 | 
				
			||||||
 | 
					# for full management of VMs
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Default allows only root. If PolicyKit is enabled on the socket,
 | 
				
			||||||
 | 
					# the default will change to allow everyone (eg, 0777)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# If not using PolicyKit and setting group ownership for access
 | 
				
			||||||
 | 
					# control then you may want to relax this to:
 | 
				
			||||||
 | 
					#unix_sock_rw_perms = "0770"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set the name of the directory in which sockets will be found/created.
 | 
				
			||||||
 | 
					#unix_sock_dir = "/var/run/libvirt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Authentication.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  - none: do not perform auth checks. If you can connect to the
 | 
				
			||||||
 | 
					#          socket you are allowed. This is suitable if there are
 | 
				
			||||||
 | 
					#          restrictions on connecting to the socket (eg, UNIX
 | 
				
			||||||
 | 
					#          socket permissions), or if there is a lower layer in
 | 
				
			||||||
 | 
					#          the network providing auth (eg, TLS/x509 certificates)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  - sasl: use SASL infrastructure. The actual auth scheme is then
 | 
				
			||||||
 | 
					#          controlled from /etc/sasl2/libvirt.conf. For the TCP
 | 
				
			||||||
 | 
					#          socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
 | 
				
			||||||
 | 
					#          For non-TCP or TLS sockets,  any scheme is allowed.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#  - polkit: use PolicyKit to authenticate. This is only suitable
 | 
				
			||||||
 | 
					#            for use on the UNIX sockets. The default policy will
 | 
				
			||||||
 | 
					#            require a user to supply their own password to gain
 | 
				
			||||||
 | 
					#            full read/write access (aka sudo like), while anyone
 | 
				
			||||||
 | 
					#            is allowed read/only access.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Set an authentication scheme for UNIX read-only sockets
 | 
				
			||||||
 | 
					# By default socket permissions allow anyone to connect
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# To restrict monitoring of domains you may wish to enable
 | 
				
			||||||
 | 
					# an authentication mechanism here
 | 
				
			||||||
 | 
					#auth_unix_ro = "none"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set an authentication scheme for UNIX read-write sockets
 | 
				
			||||||
 | 
					# By default socket permissions only allow root. If PolicyKit
 | 
				
			||||||
 | 
					# support was compiled into libvirt, the default will be to
 | 
				
			||||||
 | 
					# use 'polkit' auth.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# If the unix_sock_rw_perms are changed you may wish to enable
 | 
				
			||||||
 | 
					# an authentication mechanism here
 | 
				
			||||||
 | 
					#auth_unix_rw = "none"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Change the authentication scheme for TCP sockets.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# If you don't enable SASL, then all TCP traffic is cleartext.
 | 
				
			||||||
 | 
					# Don't do this outside of a dev/test scenario. For real world
 | 
				
			||||||
 | 
					# use, always enable SASL and use the GSSAPI or DIGEST-MD5
 | 
				
			||||||
 | 
					# mechanism in /etc/sasl2/libvirt.conf
 | 
				
			||||||
 | 
					#auth_tcp = "sasl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Change the authentication scheme for TLS sockets.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# TLS sockets already have encryption provided by the TLS
 | 
				
			||||||
 | 
					# layer, and limited authentication is done by certificates
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# It is possible to make use of any SASL authentication
 | 
				
			||||||
 | 
					# mechanism as well, by using 'sasl' for this option
 | 
				
			||||||
 | 
					#auth_tls = "none"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# TLS x509 certificate configuration
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the default server key file path
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#key_file = "/etc/pki/libvirt/private/serverkey.pem"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the default server certificate file path
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#cert_file = "/etc/pki/libvirt/servercert.pem"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the default CA certificate path
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#ca_file = "/etc/pki/CA/cacert.pem"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Specify a certificate revocation list.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Defaults to not using a CRL, uncomment to enable it
 | 
				
			||||||
 | 
					#crl_file = "/etc/pki/CA/crl.pem"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Authorization controls
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Flag to disable verification of 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 = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The minimum limit sets the number of workers to start up
 | 
				
			||||||
 | 
					# initially. If the number of active clients exceeds this,
 | 
				
			||||||
 | 
					# then more threads are spawned, upto max_workers limit.
 | 
				
			||||||
 | 
					# Typically you'd want max_workers to equal maximum number
 | 
				
			||||||
 | 
					# of clients allowed
 | 
				
			||||||
 | 
					#min_workers = 5
 | 
				
			||||||
 | 
					#max_workers = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The number of priority workers. If all workers from above
 | 
				
			||||||
 | 
					# pool will 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 impact
 | 
				
			||||||
 | 
					# memory usage, currently each request requires 256 KB of
 | 
				
			||||||
 | 
					# memory. So by default upto 5 MB of memory is used
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# XXX this isn't actually enforced yet, only the per-client
 | 
				
			||||||
 | 
					# limit is used so far
 | 
				
			||||||
 | 
					#max_requests = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Limit on concurrent requests from a single client
 | 
				
			||||||
 | 
					# connection. To avoid one client monopolizing the server
 | 
				
			||||||
 | 
					# this should be a small fraction of the global max_requests
 | 
				
			||||||
 | 
					# and max_workers parameter
 | 
				
			||||||
 | 
					#max_client_requests = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#################################################################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Logging controls
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Logging level: 4 errors, 3 warnings, 2 information, 1 debug
 | 
				
			||||||
 | 
					# basically 1 will log everything possible
 | 
				
			||||||
 | 
					#log_level = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Logging filters:
 | 
				
			||||||
 | 
					# A filter allows to select a different logging level for a given category
 | 
				
			||||||
 | 
					# of logs
 | 
				
			||||||
 | 
					# The format for a filter is one of:
 | 
				
			||||||
 | 
					#    x:name
 | 
				
			||||||
 | 
					#    x:+name
 | 
				
			||||||
 | 
					#      where name is a string which is matched against source file name,
 | 
				
			||||||
 | 
					#      e.g., "remote", "qemu", or "util/json", the optional "+" prefix
 | 
				
			||||||
 | 
					#      tells libvirt to log stack trace for each message matching name,
 | 
				
			||||||
 | 
					#      and x is the minimal level where matching messages should be logged:
 | 
				
			||||||
 | 
					#    1: DEBUG
 | 
				
			||||||
 | 
					#    2: INFO
 | 
				
			||||||
 | 
					#    3: WARNING
 | 
				
			||||||
 | 
					#    4: ERROR
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Multiple filter 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
 | 
				
			||||||
 | 
					# In all case the x prefix is the minimal level, acting as a filter
 | 
				
			||||||
 | 
					#    1: DEBUG
 | 
				
			||||||
 | 
					#    2: INFO
 | 
				
			||||||
 | 
					#    3: WARNING
 | 
				
			||||||
 | 
					#    4: ERROR
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Multiple output can be defined, they just need to be separated by spaces.
 | 
				
			||||||
 | 
					# e.g. to log all warnings and errors to syslog under the libvirtd ident:
 | 
				
			||||||
 | 
					#log_outputs="3:syslog:libvirtd"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Log debug buffer size: default 64
 | 
				
			||||||
 | 
					# The daemon keeps an internal debug log buffer which will be dumped in case
 | 
				
			||||||
 | 
					# of crash or upon receiving a SIGUSR2 signal. This setting allows to override
 | 
				
			||||||
 | 
					# the default buffer size in kilobytes.
 | 
				
			||||||
 | 
					# If value is 0 or less the debug log buffer is deactivated
 | 
				
			||||||
 | 
					#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 client.  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 deamon will send responses.  When
 | 
				
			||||||
 | 
					# keepalive_count is set to 0, connections will be automatically
 | 
				
			||||||
 | 
					# closed after keepalive_interval seconds of inactivity without
 | 
				
			||||||
 | 
					# sending any keepalive messages.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#keepalive_interval = 5
 | 
				
			||||||
 | 
					#keepalive_count = 5
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# If set to 1, libvirtd will refuse to talk to clients that do not
 | 
				
			||||||
 | 
					# support keepalive protocol.  Defaults to 0.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#keepalive_required = 1
 | 
				
			||||||
							
								
								
									
										75
									
								
								daemon/libvirtd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								daemon/libvirtd.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * libvirtd.h: daemon data structure definitions
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2006-2012 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 <config.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# include <rpc/types.h>
 | 
				
			||||||
 | 
					# include <rpc/xdr.h>
 | 
				
			||||||
 | 
					# include "remote_protocol.h"
 | 
				
			||||||
 | 
					# include "qemu_protocol.h"
 | 
				
			||||||
 | 
					# include "logging.h"
 | 
				
			||||||
 | 
					# include "threads.h"
 | 
				
			||||||
 | 
					# if HAVE_SASL
 | 
				
			||||||
 | 
					#  include "virnetsaslcontext.h"
 | 
				
			||||||
 | 
					# endif
 | 
				
			||||||
 | 
					# include "virnetserverprogram.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct daemonClientStream daemonClientStream;
 | 
				
			||||||
 | 
					typedef daemonClientStream *daemonClientStreamPtr;
 | 
				
			||||||
 | 
					typedef struct daemonClientPrivate daemonClientPrivate;
 | 
				
			||||||
 | 
					typedef daemonClientPrivate *daemonClientPrivatePtr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Stores the per-client connection state */
 | 
				
			||||||
 | 
					struct daemonClientPrivate {
 | 
				
			||||||
 | 
					    /* Hold while accessing any data except conn */
 | 
				
			||||||
 | 
					    virMutex lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if HAVE_SASL
 | 
				
			||||||
 | 
					    virNetSASLSessionPtr sasl;
 | 
				
			||||||
 | 
					# endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* This is only valid if a remote open call has been made on this
 | 
				
			||||||
 | 
					     * connection, otherwise it will be NULL.  Also if remote close is
 | 
				
			||||||
 | 
					     * called, it will be set back to NULL if that succeeds.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virConnectPtr conn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    daemonClientStreamPtr streams;
 | 
				
			||||||
 | 
					    bool keepalive_supported;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if HAVE_SASL
 | 
				
			||||||
 | 
					extern virNetSASLContextPtr saslCtxt;
 | 
				
			||||||
 | 
					# endif
 | 
				
			||||||
 | 
					extern virNetServerProgramPtr remoteProgram;
 | 
				
			||||||
 | 
					extern virNetServerProgramPtr qemuProgram;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										123
									
								
								daemon/libvirtd.init.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								daemon/libvirtd.init.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# the following is the LSB init header see
 | 
				
			||||||
 | 
					# http://www.linux-foundation.org/spec//booksets/LSB-Core-generic/LSB-Core-generic.html#INITSCRCOMCONV
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					### BEGIN INIT INFO
 | 
				
			||||||
 | 
					# Provides: libvirtd
 | 
				
			||||||
 | 
					# Required-Start: $network messagebus
 | 
				
			||||||
 | 
					# Should-Start: $named
 | 
				
			||||||
 | 
					# Should-Start: xend
 | 
				
			||||||
 | 
					# Should-Start: avahi-daemon
 | 
				
			||||||
 | 
					# Required-Stop: $network messagebus
 | 
				
			||||||
 | 
					# Should-Stop: $named
 | 
				
			||||||
 | 
					# Default-Start: 3 4 5
 | 
				
			||||||
 | 
					# Short-Description: daemon for libvirt virtualization API
 | 
				
			||||||
 | 
					# Description: This is a daemon for managing guest instances
 | 
				
			||||||
 | 
					#              and libvirt virtual networks
 | 
				
			||||||
 | 
					#              See http://libvirt.org
 | 
				
			||||||
 | 
					### END INIT INFO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# the following is chkconfig init header
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# libvirtd:   guest and virtual network management daemon
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# chkconfig: 345 97 03
 | 
				
			||||||
 | 
					# description:  This is a daemon for managing guest instances \
 | 
				
			||||||
 | 
					#               and libvirt virtual networks \
 | 
				
			||||||
 | 
					#               See http://libvirt.org
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# processname: libvirtd
 | 
				
			||||||
 | 
					# pidfile: @localstatedir@/run/libvirtd.pid
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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
 | 
				
			||||||
@@ -5,4 +5,5 @@
 | 
				
			|||||||
        compress
 | 
					        compress
 | 
				
			||||||
        delaycompress
 | 
					        delaycompress
 | 
				
			||||||
        copytruncate
 | 
					        copytruncate
 | 
				
			||||||
 | 
					        minsize 100k
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										204
									
								
								daemon/libvirtd.pod.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								daemon/libvirtd.pod.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
				
			|||||||
 | 
					=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<-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
 | 
				
			||||||
							
								
								
									
										42
									
								
								daemon/libvirtd.policy-0
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								daemon/libvirtd.policy-0
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE policyconfig PUBLIC
 | 
				
			||||||
 | 
					 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 | 
				
			||||||
 | 
					 "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--
 | 
				
			||||||
 | 
					Policy definitions for libvirt daemon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvirt is licensed to you under the GNU Lesser General Public License
 | 
				
			||||||
 | 
					version 2. See COPYING for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE: If you make changes to this file, make sure to validate the file
 | 
				
			||||||
 | 
					using the polkit-policy-file-validate(1) tool. Changes made to this
 | 
				
			||||||
 | 
					file are instantly applied.
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<policyconfig>
 | 
				
			||||||
 | 
					    <action id="org.libvirt.unix.monitor">
 | 
				
			||||||
 | 
					      <description>Monitor local virtualized systems</description>
 | 
				
			||||||
 | 
					      <message>System policy prevents monitoring of local virtualized systems</message>
 | 
				
			||||||
 | 
					      <defaults>
 | 
				
			||||||
 | 
					        <!-- Any program can use libvirt in read-only mode for monitoring,
 | 
				
			||||||
 | 
					             even if not part of a session -->
 | 
				
			||||||
 | 
					        <allow_any>yes</allow_any>
 | 
				
			||||||
 | 
					        <allow_inactive>yes</allow_inactive>
 | 
				
			||||||
 | 
					        <allow_active>yes</allow_active>
 | 
				
			||||||
 | 
					      </defaults>
 | 
				
			||||||
 | 
					    </action>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <action id="org.libvirt.unix.manage">
 | 
				
			||||||
 | 
					      <description>Manage local virtualized systems</description>
 | 
				
			||||||
 | 
					      <message>System policy prevents management of local virtualized systems</message>
 | 
				
			||||||
 | 
					      <defaults>
 | 
				
			||||||
 | 
					        <!-- Only a program in the active host session can use libvirt in
 | 
				
			||||||
 | 
					             read-write mode for management, and we require user password -->
 | 
				
			||||||
 | 
					        <allow_any>auth_admin</allow_any>
 | 
				
			||||||
 | 
					        <allow_inactive>auth_admin</allow_inactive>
 | 
				
			||||||
 | 
					        <allow_active>auth_admin_keep_session</allow_active>
 | 
				
			||||||
 | 
					      </defaults>
 | 
				
			||||||
 | 
					    </action>
 | 
				
			||||||
 | 
					</policyconfig>
 | 
				
			||||||
							
								
								
									
										42
									
								
								daemon/libvirtd.policy-1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								daemon/libvirtd.policy-1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE policyconfig PUBLIC
 | 
				
			||||||
 | 
					 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 | 
				
			||||||
 | 
					 "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--
 | 
				
			||||||
 | 
					Policy definitions for libvirt daemon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvirt is licensed to you under the GNU Lesser General Public License
 | 
				
			||||||
 | 
					version 2. See COPYING for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOTE: If you make changes to this file, make sure to validate the file
 | 
				
			||||||
 | 
					using the polkit-policy-file-validate(1) tool. Changes made to this
 | 
				
			||||||
 | 
					file are instantly applied.
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<policyconfig>
 | 
				
			||||||
 | 
					    <action id="org.libvirt.unix.monitor">
 | 
				
			||||||
 | 
					      <description>Monitor local virtualized systems</description>
 | 
				
			||||||
 | 
					      <message>System policy prevents monitoring of local virtualized systems</message>
 | 
				
			||||||
 | 
					      <defaults>
 | 
				
			||||||
 | 
					        <!-- Any program can use libvirt in read-only mode for monitoring,
 | 
				
			||||||
 | 
					             even if not part of a session -->
 | 
				
			||||||
 | 
					        <allow_any>yes</allow_any>
 | 
				
			||||||
 | 
					        <allow_inactive>yes</allow_inactive>
 | 
				
			||||||
 | 
					        <allow_active>yes</allow_active>
 | 
				
			||||||
 | 
					      </defaults>
 | 
				
			||||||
 | 
					    </action>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <action id="org.libvirt.unix.manage">
 | 
				
			||||||
 | 
					      <description>Manage local virtualized systems</description>
 | 
				
			||||||
 | 
					      <message>System policy prevents management of local virtualized systems</message>
 | 
				
			||||||
 | 
					      <defaults>
 | 
				
			||||||
 | 
					        <!-- Only a program in the active host session can use libvirt in
 | 
				
			||||||
 | 
					             read-write mode for management, and we require user password -->
 | 
				
			||||||
 | 
					        <allow_any>auth_admin</allow_any>
 | 
				
			||||||
 | 
					        <allow_inactive>auth_admin</allow_inactive>
 | 
				
			||||||
 | 
					        <allow_active>auth_admin_keep</allow_active>
 | 
				
			||||||
 | 
					      </defaults>
 | 
				
			||||||
 | 
					    </action>
 | 
				
			||||||
 | 
					</policyconfig>
 | 
				
			||||||
@@ -5,4 +5,5 @@
 | 
				
			|||||||
        compress
 | 
					        compress
 | 
				
			||||||
        delaycompress
 | 
					        delaycompress
 | 
				
			||||||
        copytruncate
 | 
					        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 -a libvirt' to browse it
 | 
				
			||||||
 | 
					sasldb_path: /etc/libvirt/passwd.db
 | 
				
			||||||
							
								
								
									
										20
									
								
								daemon/libvirtd.service.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								daemon/libvirtd.service.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					# NB we don't use socket activation. When libvirtd starts it will
 | 
				
			||||||
 | 
					# spawn any virtual machines registered for autostart. We want this
 | 
				
			||||||
 | 
					# to occur on every boot, regardless of whether any client connects
 | 
				
			||||||
 | 
					# to a socket. Thus socket activation doesn't have any benefit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Unit]
 | 
				
			||||||
 | 
					Description=Virtualization daemon
 | 
				
			||||||
 | 
					Before=libvirt-guests.service
 | 
				
			||||||
 | 
					After=network.target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Service]
 | 
				
			||||||
 | 
					EnvironmentFile=-/etc/sysconfig/libvirtd
 | 
				
			||||||
 | 
					ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
 | 
				
			||||||
 | 
					ExecReload=/bin/kill -HUP $MAINPID
 | 
				
			||||||
 | 
					KillMode=process
 | 
				
			||||||
 | 
					# Override the maximum number of opened files
 | 
				
			||||||
 | 
					#LimitNOFILE=2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Install]
 | 
				
			||||||
 | 
					WantedBy=multi-user.target
 | 
				
			||||||
							
								
								
									
										24
									
								
								daemon/libvirtd.sysconf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								daemon/libvirtd.sysconf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					#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
 | 
				
			||||||
							
								
								
									
										4735
									
								
								daemon/remote.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4735
									
								
								daemon/remote.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										42
									
								
								daemon/remote.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								daemon/remote.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 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, 2011 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 "memory.h"
 | 
				
			||||||
 | 
					#include "logging.h"
 | 
				
			||||||
 | 
					#include "virnetserverclient.h"
 | 
				
			||||||
 | 
					#include "virterror_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VIR_FROM_THIS VIR_FROM_STREAMS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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) {
 | 
				
			||||||
 | 
					        virReportOOMError();
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virStreamFree(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 upto one message
 | 
				
			||||||
 | 
					 * worth of data, and then queues that for transmission
 | 
				
			||||||
 | 
					 * to the client.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns 0 if data was queued for TX, or a error RPC
 | 
				
			||||||
 | 
					 * was sent, or -1 on fatal error, indicating client should
 | 
				
			||||||
 | 
					 * be killed
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					daemonStreamHandleRead(virNetServerClientPtr client,
 | 
				
			||||||
 | 
					                       daemonClientStream *stream)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *buffer;
 | 
				
			||||||
 | 
					    size_t bufferLen = VIR_NET_MESSAGE_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__ */
 | 
				
			||||||
							
								
								
									
										49
									
								
								daemon/test_libvirtd.aug.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								daemon/test_libvirtd.aug.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					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_dir" = "/var/run/libvirt" }
 | 
				
			||||||
 | 
					        { "auth_unix_ro" = "none" }
 | 
				
			||||||
 | 
					        { "auth_unix_rw" = "none" }
 | 
				
			||||||
 | 
					        { "auth_tcp" = "sasl" }
 | 
				
			||||||
 | 
					        { "auth_tls" = "none" }
 | 
				
			||||||
 | 
					        { "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" = "20" }
 | 
				
			||||||
 | 
					        { "min_workers" = "5" }
 | 
				
			||||||
 | 
					        { "max_workers" = "20" }
 | 
				
			||||||
 | 
					        { "prio_workers" = "5" }
 | 
				
			||||||
 | 
					        { "max_requests" = "20" }
 | 
				
			||||||
 | 
					        { "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" }
 | 
				
			||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					<html>
 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1>404 page not found</h1>
 | 
					    <h1>404 page not found</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,11 +8,16 @@
 | 
				
			|||||||
      page you were looking for. You might want to try
 | 
					      page you were looking for. You might want to try
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <ul>
 | 
					    <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>
 | 
					        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
 | 
					      <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>
 | 
					        locate the content on this site or mailing list archives</li>
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p class="image">
 | 
				
			||||||
 | 
					      <img src="/libvirtLogo404.png" alt="libvirt Logo"/>
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  </body>
 | 
					  </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										420
									
								
								docs/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										420
									
								
								docs/Makefile.am
									
									
									
									
									
								
							@@ -1,125 +1,66 @@
 | 
				
			|||||||
## Process this file with automake to produce Makefile.in
 | 
					## Process this file with automake to produce Makefile.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Copyright (C) 2005-2016 Red Hat, Inc.
 | 
					## Copyright (C) 2005-2012 Red Hat, Inc.
 | 
				
			||||||
##
 | 
					## See COPYING.LIB for the License of this software
 | 
				
			||||||
## This library is free software; you can redistribute it and/or
 | 
					
 | 
				
			||||||
## modify it under the terms of the GNU Lesser General Public
 | 
					SUBDIRS= schemas
 | 
				
			||||||
## License as published by the Free Software Foundation; either
 | 
					
 | 
				
			||||||
## version 2.1 of the License, or (at your option) any later version.
 | 
					PERL = perl
 | 
				
			||||||
##
 | 
					
 | 
				
			||||||
## This library is distributed in the hope that it will be useful,
 | 
					# The directory containing the source code (if it contains documentation).
 | 
				
			||||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					DOC_SOURCE_DIR=../src
 | 
				
			||||||
## 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/>.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
HTML_DIR = $(docdir)/html
 | 
					 | 
				
			||||||
DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
 | 
					DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
modules = \
 | 
					BUILT_SOURCES=hvsupport.html.in
 | 
				
			||||||
	libvirt-common \
 | 
					 | 
				
			||||||
	libvirt-domain \
 | 
					 | 
				
			||||||
	libvirt-domain-snapshot \
 | 
					 | 
				
			||||||
	libvirt-event \
 | 
					 | 
				
			||||||
	libvirt-host \
 | 
					 | 
				
			||||||
	libvirt-interface \
 | 
					 | 
				
			||||||
	libvirt-network \
 | 
					 | 
				
			||||||
	libvirt-nodedev \
 | 
					 | 
				
			||||||
	libvirt-nwfilter \
 | 
					 | 
				
			||||||
	libvirt-secret \
 | 
					 | 
				
			||||||
	libvirt-storage \
 | 
					 | 
				
			||||||
	libvirt-stream \
 | 
					 | 
				
			||||||
	virterror \
 | 
					 | 
				
			||||||
	$(NULL)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
apihtml = \
 | 
					apihtml =			\
 | 
				
			||||||
  html/index.html \
 | 
					  html/index.html		\
 | 
				
			||||||
  $(apihtml_generated)
 | 
					  html/libvirt-libvirt.html	\
 | 
				
			||||||
 | 
					  html/libvirt-virterror.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
apihtml_generated = \
 | 
					apipng =	\
 | 
				
			||||||
	$(addprefix html/libvirt-,$(addsuffix .html,$(modules))) \
 | 
					  html/left.png	\
 | 
				
			||||||
	$(NULL)
 | 
					  html/up.png	\
 | 
				
			||||||
 | 
					  html/home.png	\
 | 
				
			||||||
apipng = \
 | 
					 | 
				
			||||||
  html/left.png \
 | 
					 | 
				
			||||||
  html/up.png \
 | 
					 | 
				
			||||||
  html/home.png \
 | 
					 | 
				
			||||||
  html/right.png
 | 
					  html/right.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
devhelphtml = \
 | 
					devhelphtml =			\
 | 
				
			||||||
  devhelp/libvirt.devhelp \
 | 
					  devhelp/libvirt.devhelp	\
 | 
				
			||||||
  devhelp/index.html \
 | 
					  devhelp/index.html		\
 | 
				
			||||||
  devhelp/general.html \
 | 
					  devhelp/general.html		\
 | 
				
			||||||
  $(devhelphtml_generated)
 | 
					  devhelp/libvirt-libvirt.html	\
 | 
				
			||||||
 | 
					  devhelp/libvirt-virterror.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
devhelphtml_generated = \
 | 
					css =         \
 | 
				
			||||||
	$(addprefix devhelp/libvirt-,$(addsuffix .html,$(modules))) \
 | 
					 | 
				
			||||||
	$(NULL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
css = \
 | 
					 | 
				
			||||||
  generic.css \
 | 
					  generic.css \
 | 
				
			||||||
  libvirt.css \
 | 
					  libvirt.css \
 | 
				
			||||||
  mobile.css \
 | 
					 | 
				
			||||||
  main.css
 | 
					  main.css
 | 
				
			||||||
 | 
					
 | 
				
			||||||
javascript = \
 | 
					devhelppng =		\
 | 
				
			||||||
  js/main.js \
 | 
					  devhelp/home.png	\
 | 
				
			||||||
  js/jquery-3.1.1.min.js \
 | 
					  devhelp/left.png	\
 | 
				
			||||||
  js/jquery.rss.min.js \
 | 
					  devhelp/right.png	\
 | 
				
			||||||
  js/moment.min.js
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
devhelppng = \
 | 
					 | 
				
			||||||
  devhelp/home.png \
 | 
					 | 
				
			||||||
  devhelp/left.png \
 | 
					 | 
				
			||||||
  devhelp/right.png \
 | 
					 | 
				
			||||||
  devhelp/up.png
 | 
					  devhelp/up.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
devhelpcss = devhelp/style.css
 | 
					devhelpcss = devhelp/style.css
 | 
				
			||||||
 | 
					
 | 
				
			||||||
devhelpxsl = devhelp/devhelp.xsl devhelp/html.xsl
 | 
					devhelpxsl = devhelp/devhelp.xsl devhelp/html.xsl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logofiles = \
 | 
					 | 
				
			||||||
  logos/logo-base.svg \
 | 
					 | 
				
			||||||
  logos/logo-square.svg \
 | 
					 | 
				
			||||||
  logos/logo-square-powered.svg \
 | 
					 | 
				
			||||||
  logos/logo-banner-dark.svg \
 | 
					 | 
				
			||||||
  logos/logo-banner-light.svg \
 | 
					 | 
				
			||||||
  logos/logo-square-96.png \
 | 
					 | 
				
			||||||
  logos/logo-square-128.png \
 | 
					 | 
				
			||||||
  logos/logo-square-192.png \
 | 
					 | 
				
			||||||
  logos/logo-square-256.png \
 | 
					 | 
				
			||||||
  logos/logo-square-powered-96.png \
 | 
					 | 
				
			||||||
  logos/logo-square-powered-128.png \
 | 
					 | 
				
			||||||
  logos/logo-square-powered-192.png \
 | 
					 | 
				
			||||||
  logos/logo-square-powered-256.png \
 | 
					 | 
				
			||||||
  logos/logo-banner-dark-256.png \
 | 
					 | 
				
			||||||
  logos/logo-banner-dark-800.png \
 | 
					 | 
				
			||||||
  logos/logo-banner-light-256.png \
 | 
					 | 
				
			||||||
  logos/logo-banner-light-800.png
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
png = \
 | 
					png = \
 | 
				
			||||||
  32favicon.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-daemon-arch.png \
 | 
				
			||||||
  libvirt-driver-arch.png \
 | 
					  libvirt-driver-arch.png \
 | 
				
			||||||
  libvirt-object-model.png \
 | 
					  libvirt-object-model.png \
 | 
				
			||||||
 | 
					  madeWith.png \
 | 
				
			||||||
 | 
					  et.png \
 | 
				
			||||||
  migration-managed-direct.png \
 | 
					  migration-managed-direct.png \
 | 
				
			||||||
  migration-managed-p2p.png \
 | 
					  migration-managed-p2p.png \
 | 
				
			||||||
  migration-native.png \
 | 
					  migration-native.png \
 | 
				
			||||||
@@ -135,16 +76,17 @@ internals_html_in = \
 | 
				
			|||||||
  $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
 | 
					  $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
 | 
				
			||||||
internals_html = $(internals_html_in:%.html.in=%.html)
 | 
					internals_html = $(internals_html_in:%.html.in=%.html)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Since we ship pre-built html in the tarball, we must also
 | 
					dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) \
 | 
				
			||||||
# ship the sources, even when those sources are themselves
 | 
					  todo.html.in \
 | 
				
			||||||
# generated.
 | 
					  hvsupport.html.in
 | 
				
			||||||
# Generate hvsupport.html and news.html first, since they take one extra step.
 | 
					 | 
				
			||||||
dot_html_in = \
 | 
					 | 
				
			||||||
  hvsupport.html.in \
 | 
					 | 
				
			||||||
  news.html.in \
 | 
					 | 
				
			||||||
  $(notdir $(wildcard $(srcdir)/*.html.in))
 | 
					 | 
				
			||||||
dot_html = $(dot_html_in:%.html.in=%.html)
 | 
					dot_html = $(dot_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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					patches = $(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/api_extension/*.patch))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
xml = \
 | 
					xml = \
 | 
				
			||||||
  libvirt-api.xml \
 | 
					  libvirt-api.xml \
 | 
				
			||||||
  libvirt-refs.xml
 | 
					  libvirt-refs.xml
 | 
				
			||||||
@@ -153,22 +95,12 @@ qemu_xml = \
 | 
				
			|||||||
  libvirt-qemu-api.xml \
 | 
					  libvirt-qemu-api.xml \
 | 
				
			||||||
  libvirt-qemu-refs.xml
 | 
					  libvirt-qemu-refs.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lxc_xml = \
 | 
					 | 
				
			||||||
  libvirt-lxc-api.xml \
 | 
					 | 
				
			||||||
  libvirt-lxc-refs.xml
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
admin_xml = \
 | 
					 | 
				
			||||||
  libvirt-admin-api.xml \
 | 
					 | 
				
			||||||
  libvirt-admin-refs.xml
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
apidir = $(pkgdatadir)/api
 | 
					apidir = $(pkgdatadir)/api
 | 
				
			||||||
api_DATA = \
 | 
					api_DATA = libvirt-api.xml libvirt-qemu-api.xml
 | 
				
			||||||
       libvirt-api.xml \
 | 
					 | 
				
			||||||
       libvirt-qemu-api.xml \
 | 
					 | 
				
			||||||
       libvirt-lxc-api.xml \
 | 
					 | 
				
			||||||
       libvirt-admin-api.xml
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
fig = \
 | 
					fig = \
 | 
				
			||||||
 | 
					  libvirt-net-logical.fig \
 | 
				
			||||||
 | 
					  libvirt-net-physical.fig \
 | 
				
			||||||
  libvirt-daemon-arch.fig \
 | 
					  libvirt-daemon-arch.fig \
 | 
				
			||||||
  libvirt-driver-arch.fig \
 | 
					  libvirt-driver-arch.fig \
 | 
				
			||||||
  libvirt-object-model.fig \
 | 
					  libvirt-object-model.fig \
 | 
				
			||||||
@@ -178,133 +110,122 @@ fig = \
 | 
				
			|||||||
  migration-tunnel.fig \
 | 
					  migration-tunnel.fig \
 | 
				
			||||||
  migration-unmanaged-direct.fig
 | 
					  migration-unmanaged-direct.fig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
schemadir = $(pkgdatadir)/schemas
 | 
					EXTRA_DIST=					\
 | 
				
			||||||
schema_DATA = $(wildcard $(srcdir)/schemas/*.rng)
 | 
					  apibuild.py \
 | 
				
			||||||
 | 
					  site.xsl newapi.xsl news.xsl page.xsl \
 | 
				
			||||||
EXTRA_DIST= \
 | 
					  hacking1.xsl hacking2.xsl wrapstring.xsl \
 | 
				
			||||||
  apibuild.py genaclperms.pl \
 | 
					 | 
				
			||||||
  site.xsl subsite.xsl newapi.xsl page.xsl \
 | 
					 | 
				
			||||||
  wrapstring.xsl \
 | 
					 | 
				
			||||||
  $(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
 | 
					  $(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
 | 
				
			||||||
  $(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
 | 
					  $(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
 | 
				
			||||||
  $(xml) $(qemu_xml) $(lxc_xml) $(admin_xml) $(fig) $(png) $(css) \
 | 
					  $(xml) $(qemu_xml) $(fig) $(png) $(css) \
 | 
				
			||||||
  $(javascript) $(logofiles) \
 | 
					  $(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
 | 
				
			||||||
  $(internals_html_in) $(internals_html) $(fonts) \
 | 
					  $(internals_html_in) $(internals_html) \
 | 
				
			||||||
  aclperms.htmlinc \
 | 
					  sitemap.html.in \
 | 
				
			||||||
  hvsupport.pl \
 | 
					  todo.pl hvsupport.pl todo.cfg-example
 | 
				
			||||||
  $(schema_DATA)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
acl_generated = aclperms.htmlinc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$(srcdir)/aclperms.htmlinc: $(top_srcdir)/src/access/viraccessperm.h \
 | 
					 | 
				
			||||||
        $(srcdir)/genaclperms.pl Makefile.am
 | 
					 | 
				
			||||||
	$(AM_V_GEN)$(PERL) $(srcdir)/genaclperms.pl $< > $@
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
MAINTAINERCLEANFILES = \
 | 
					MAINTAINERCLEANFILES = \
 | 
				
			||||||
  $(addprefix $(srcdir)/,$(dot_html)) \
 | 
					  $(addprefix $(srcdir)/,$(dot_html)) \
 | 
				
			||||||
  $(addprefix $(srcdir)/,$(apihtml)) \
 | 
					  $(addprefix $(srcdir)/,$(apihtml)) \
 | 
				
			||||||
  $(addprefix $(srcdir)/,$(devhelphtml)) \
 | 
					  $(addprefix $(srcdir)/,$(devhelphtml)) \
 | 
				
			||||||
  $(addprefix $(srcdir)/,$(internals_html)) \
 | 
					  $(addprefix $(srcdir)/,$(internals_html)) \
 | 
				
			||||||
  $(srcdir)/hvsupport.html.in $(srcdir)/aclperms.htmlinc
 | 
					  $(addprefix $(srcdir)/,$(dot_php))
 | 
				
			||||||
 | 
					 | 
				
			||||||
timestamp="$(shell if test -n "$$SOURCE_DATE_EPOCH"; \
 | 
					 | 
				
			||||||
		   then \
 | 
					 | 
				
			||||||
		     date -u --date="@$$SOURCE_DATE_EPOCH"; \
 | 
					 | 
				
			||||||
		   else \
 | 
					 | 
				
			||||||
		     date -u; \
 | 
					 | 
				
			||||||
		   fi)"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
all-am: web
 | 
					all-am: web
 | 
				
			||||||
 | 
					
 | 
				
			||||||
api: $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
 | 
					api: $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
 | 
				
			||||||
qemu_api: $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
web: $(dot_html) $(internals_html) html/index.html devhelp/index.html
 | 
					web: $(dot_html) $(internals_html) html/index.html devhelp/index.html \
 | 
				
			||||||
 | 
					  $(dot_php)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hvsupport.html: $(srcdir)/hvsupport.html.in
 | 
					todo.html.in: todo.pl
 | 
				
			||||||
 | 
						if [ -f  todo.cfg ]; then \
 | 
				
			||||||
 | 
							echo "Generating $@"; \
 | 
				
			||||||
 | 
							$(PERL) $< > $@ \
 | 
				
			||||||
 | 
							|| { rm $@ && exit 1; }; \
 | 
				
			||||||
 | 
						else \
 | 
				
			||||||
 | 
							echo "Stubbing $@"; \
 | 
				
			||||||
 | 
							echo "<html><body><h1>Todo list</h1></body></html>" > $@ ; \
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
 | 
					todo:
 | 
				
			||||||
		$(top_srcdir)/src/libvirt_public.syms \
 | 
						rm -f todo.html.in
 | 
				
			||||||
	$(top_srcdir)/src/libvirt_qemu.syms $(top_srcdir)/src/libvirt_lxc.syms \
 | 
						$(MAKE) todo.html
 | 
				
			||||||
	$(top_srcdir)/src/driver.h
 | 
					 | 
				
			||||||
	$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(top_srcdir)/src > $@ \
 | 
					 | 
				
			||||||
		|| { rm $@ && exit 1; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# xsltproc seems to add the xmlns="" attribute to random output elements:
 | 
					hvsupport.html.in: $(srcdir)/hvsupport.pl $(srcdir)/../src/libvirt_public.syms \
 | 
				
			||||||
# use sed to strip it out, as leaving it there triggers XML errors during
 | 
						 $(srcdir)/../src/libvirt_qemu.syms $(srcdir)/../src/driver.h
 | 
				
			||||||
# further transformation steps
 | 
						$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(srcdir)/../src > $@ || { rm $@ && exit 1; }
 | 
				
			||||||
news.html.in: \
 | 
					
 | 
				
			||||||
	  $(srcdir)/news.xml \
 | 
					.PHONY: todo
 | 
				
			||||||
	  $(srcdir)/news-html.xsl
 | 
					 | 
				
			||||||
	$(AM_V_GEN)$(XSLTPROC) --nonet \
 | 
					 | 
				
			||||||
	    $(srcdir)/news-html.xsl \
 | 
					 | 
				
			||||||
	    $(srcdir)/news.xml \
 | 
					 | 
				
			||||||
	  >$@-tmp \
 | 
					 | 
				
			||||||
	    || { rm -f $@-tmp; exit 1; }; \
 | 
					 | 
				
			||||||
	  sed 's/ xmlns=""//g' $@-tmp >$@ \
 | 
					 | 
				
			||||||
	    || { rm -f $@-tmp; exit 1; }; \
 | 
					 | 
				
			||||||
	  rm -f $@-tmp
 | 
					 | 
				
			||||||
EXTRA_DIST += \
 | 
					 | 
				
			||||||
	$(srcdir)/news.xml \
 | 
					 | 
				
			||||||
	$(srcdir)/news.rng \
 | 
					 | 
				
			||||||
	$(srcdir)/news-html.xsl
 | 
					 | 
				
			||||||
MAINTAINERCLEANFILES += \
 | 
					 | 
				
			||||||
	$(srcdir)/news.html.in
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
%.png: %.fig
 | 
					%.png: %.fig
 | 
				
			||||||
	convert -rotate 90 $< $@
 | 
						convert -rotate 90 $< $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \
 | 
					internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
 | 
				
			||||||
		$(acl_generated)
 | 
						@if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
	$(AM_V_GEN)name=`echo $@ | sed -e 's/.tmp//'`; \
 | 
						  echo "Generating $@"; \
 | 
				
			||||||
	  dir=`dirname $@` ; \
 | 
						  $(MKDIR_P) internals; \
 | 
				
			||||||
	  if test "$$dir" = "."; \
 | 
						  name=`echo $@ | sed -e 's/.tmp//'`; \
 | 
				
			||||||
	  then \
 | 
						  $(XSLTPROC) --stringparam pagename $$name --nonet --html \
 | 
				
			||||||
	    style=site.xsl; \
 | 
						    $(top_srcdir)/docs/subsite.xsl $< > $@ \
 | 
				
			||||||
	  else \
 | 
						    || { rm $@ && exit 1; }; fi
 | 
				
			||||||
	    $(MKDIR_P) $$dir; \
 | 
					
 | 
				
			||||||
	    style=subsite.xsl; \
 | 
					%.html.tmp: %.html.in site.xsl page.xsl sitemap.html.in
 | 
				
			||||||
	  fi; \
 | 
						@if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
	  $(XSLTPROC) --stringparam pagename $$name \
 | 
						  echo "Generating $@"; \
 | 
				
			||||||
	    --stringparam timestamp $(timestamp) --nonet \
 | 
						  name=`echo $@ | sed -e 's/.tmp//'`; \
 | 
				
			||||||
	    $(top_srcdir)/docs/$$style $< > $@ \
 | 
						  $(XSLTPROC) --stringparam pagename $$name --nonet --html \
 | 
				
			||||||
	    || { rm $@ && exit 1; }
 | 
						    $(top_srcdir)/docs/site.xsl $< > $@ \
 | 
				
			||||||
 | 
						    || { rm $@ && exit 1; }; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%.html: %.html.tmp
 | 
					%.html: %.html.tmp
 | 
				
			||||||
	$(AM_V_GEN)$(XMLLINT) --nonet --format $< > $(srcdir)/$@ \
 | 
						@if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
 | 
				
			||||||
	  || { rm $(srcdir)/$@ && exit 1; }
 | 
						  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" ; fi ; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(apihtml_generated): html/index.html
 | 
					%.php.tmp: %.php.in site.xsl page.xsl sitemap.html.in
 | 
				
			||||||
 | 
						@if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
 | 
						  echo "Generating $@"; \
 | 
				
			||||||
 | 
						  $(XSLTPROC) --stringparam pagename $(@:.tmp=) --nonet --html \
 | 
				
			||||||
 | 
						    $(top_srcdir)/docs/site.xsl $< > $@ \
 | 
				
			||||||
 | 
						    || { rm $@ && exit 1; }; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
html/index.html: libvirt-api.xml newapi.xsl page.xsl $(APIBUILD_STAMP)
 | 
					%.php: %.php.tmp %.php.code.in
 | 
				
			||||||
	$(AM_V_GEN)$(XSLTPROC) --nonet -o $(srcdir)/ \
 | 
						@if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
	  --stringparam builddir '$(abs_top_builddir)' \
 | 
						  echo "Scripting $@"; \
 | 
				
			||||||
	  --stringparam timestamp $(timestamp) \
 | 
						    sed -e '/<a id="php_placeholder"><\/a>/r '"$(srcdir)/$@.code.in" \
 | 
				
			||||||
	  $(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml && \
 | 
						    -e /php_placeholder/d < $@.tmp > $(srcdir)/$@ \
 | 
				
			||||||
	  $(XMLLINT) --nonet --noout $(srcdir)/html/*.html
 | 
						    || { rm $(srcdir)/$@ && exit 1; }; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
 | 
				
			||||||
 | 
						$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
 | 
						  $(XSLTPROC) --nonet -o $(srcdir)/ \
 | 
				
			||||||
 | 
						  $(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" ; fi ; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
 | 
					$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
 | 
				
			||||||
	$(AM_V_GEN)$(XSLTPROC) --stringparam timestamp $(timestamp) \
 | 
						$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
 | 
				
			||||||
	  --nonet -o $(srcdir)/devhelp/ \
 | 
						  $(XSLTPROC) --nonet -o $(srcdir)/devhelp/ \
 | 
				
			||||||
	  $(top_srcdir)/docs/devhelp/devhelp.xsl $(srcdir)/libvirt-api.xml
 | 
						  $(top_srcdir)/docs/devhelp/devhelp.xsl $(srcdir)/libvirt-api.xml ; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
python_generated_files = \
 | 
					python_generated_files = \
 | 
				
			||||||
		$(srcdir)/html/libvirt-libvirt-lxc.html \
 | 
							$(srcdir)/html/libvirt-libvirt.html \
 | 
				
			||||||
		$(srcdir)/html/libvirt-libvirt-qemu.html \
 | 
							$(srcdir)/html/libvirt-libvirt-qemu.html \
 | 
				
			||||||
		$(srcdir)/html/libvirt-libvirt-admin.html \
 | 
					 | 
				
			||||||
		$(srcdir)/html/libvirt-virterror.html \
 | 
							$(srcdir)/html/libvirt-virterror.html \
 | 
				
			||||||
		$(srcdir)/libvirt-api.xml \
 | 
							$(srcdir)/libvirt-api.xml \
 | 
				
			||||||
		$(srcdir)/libvirt-refs.xml \
 | 
							$(srcdir)/libvirt-refs.xml \
 | 
				
			||||||
		$(srcdir)/libvirt-lxc-api.xml \
 | 
					 | 
				
			||||||
		$(srcdir)/libvirt-lxc-refs.xml \
 | 
					 | 
				
			||||||
		$(srcdir)/libvirt-qemu-api.xml \
 | 
							$(srcdir)/libvirt-qemu-api.xml \
 | 
				
			||||||
		$(srcdir)/libvirt-qemu-refs.xml \
 | 
							$(srcdir)/libvirt-qemu-refs.xml
 | 
				
			||||||
		$(srcdir)/libvirt-admin-api.xml \
 | 
					 | 
				
			||||||
		$(srcdir)/libvirt-admin-refs.xml \
 | 
					 | 
				
			||||||
		$(NULL)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
APIBUILD=$(srcdir)/apibuild.py
 | 
					APIBUILD=$(srcdir)/apibuild.py
 | 
				
			||||||
APIBUILD_STAMP=$(APIBUILD).stamp
 | 
					APIBUILD_STAMP=$(APIBUILD).stamp
 | 
				
			||||||
@@ -313,69 +234,32 @@ EXTRA_DIST += $(APIBUILD_STAMP)
 | 
				
			|||||||
$(python_generated_files): $(APIBUILD_STAMP)
 | 
					$(python_generated_files): $(APIBUILD_STAMP)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(APIBUILD_STAMP): $(srcdir)/apibuild.py \
 | 
					$(APIBUILD_STAMP): $(srcdir)/apibuild.py \
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt.h \
 | 
							$(srcdir)/../include/libvirt/libvirt.h.in \
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-common.h.in \
 | 
							$(srcdir)/../include/libvirt/libvirt-qemu.h \
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-domain-snapshot.h \
 | 
							$(srcdir)/../include/libvirt/virterror.h \
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-domain.h \
 | 
							$(srcdir)/../src/libvirt.c \
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-event.h \
 | 
							$(srcdir)/../src/libvirt-qemu.c \
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-host.h \
 | 
							$(srcdir)/../src/util/virterror.c
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-interface.h \
 | 
						$(AM_V_GEN)srcdir=$(srcdir) $(PYTHON) $(APIBUILD)
 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-network.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-nodedev.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-nwfilter.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-secret.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-storage.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-stream.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-lxc.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-qemu.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/libvirt-admin.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/include/libvirt/virterror.h \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-domain-snapshot.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-domain.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-host.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-interface.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-network.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-nodedev.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-nwfilter.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-secret.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-storage.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-stream.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-lxc.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-qemu.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/libvirt-admin.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/util/virerror.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/util/virevent.c \
 | 
					 | 
				
			||||||
		$(top_srcdir)/src/util/virtypedparam.c
 | 
					 | 
				
			||||||
	$(AM_V_GEN)srcdir=$(srcdir) builddir=$(builddir) $(PYTHON) $(APIBUILD)
 | 
					 | 
				
			||||||
	touch $@
 | 
						touch $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check-local: all
 | 
					check-local: all
 | 
				
			||||||
dist-local: all
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean-local:
 | 
					clean-local:
 | 
				
			||||||
	rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html html/*.html
 | 
						rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
maintainer-clean-local: clean-local
 | 
					maintainer-clean-local: clean-local
 | 
				
			||||||
	rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
 | 
						rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml todo.html.in hvsupport.html.in
 | 
				
			||||||
	rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
 | 
						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)
 | 
						rm -rf $(APIBUILD_STAMP)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rebuild: api qemu_api lxc_api admin_api all
 | 
					rebuild: api qemu_api all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install-data-local:
 | 
					install-data-local:
 | 
				
			||||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
 | 
						$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
 | 
				
			||||||
	for f in $(css) $(dot_html) $(gif) $(png); do \
 | 
						for f in $(css) $(dot_html) $(gif) $(png); do \
 | 
				
			||||||
	  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR); done
 | 
						  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR); done
 | 
				
			||||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/js
 | 
					 | 
				
			||||||
	for f in $(javascript); do \
 | 
					 | 
				
			||||||
	  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR)/js/; done
 | 
					 | 
				
			||||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/logos
 | 
					 | 
				
			||||||
	for f in $(logofiles); do \
 | 
					 | 
				
			||||||
	  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR)/logos; done
 | 
					 | 
				
			||||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/html
 | 
						$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/html
 | 
				
			||||||
	for h in $(apihtml); do \
 | 
						for h in $(apihtml); do \
 | 
				
			||||||
	  $(INSTALL) -m 0644 $(srcdir)/$$h $(DESTDIR)$(HTML_DIR)/html; done
 | 
						  $(INSTALL) -m 0644 $(srcdir)/$$h $(DESTDIR)$(HTML_DIR)/html; done
 | 
				
			||||||
@@ -388,26 +272,10 @@ install-data-local:
 | 
				
			|||||||
	for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
 | 
						for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
 | 
				
			||||||
	    $(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
 | 
						    $(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
	$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/fonts
 | 
					 | 
				
			||||||
	for f in $(fonts); do \
 | 
					 | 
				
			||||||
	  $(INSTALL) -m 0644 $(srcdir)/$$f $(DESTDIR)$(HTML_DIR)/fonts; \
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
uninstall-local:
 | 
					uninstall-local:
 | 
				
			||||||
	for f in $(css) $(dot_html) $(gif) $(png) $(fonts); do \
 | 
						for h in $(apihtml); do rm $(DESTDIR)$(HTML_DIR)/$$h; done
 | 
				
			||||||
	  rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
 | 
						for p in $(apipng); do rm $(DESTDIR)$(HTML_DIR)/$$p; done
 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	for f in $(logofiles); do \
 | 
					 | 
				
			||||||
	  rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	for f in $(javascript); do \
 | 
					 | 
				
			||||||
	  rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	for h in $(apihtml); do rm -f $(DESTDIR)$(HTML_DIR)/$$h; done
 | 
					 | 
				
			||||||
	for p in $(apipng); do rm -f $(DESTDIR)$(HTML_DIR)/$$p; done
 | 
					 | 
				
			||||||
	for f in $(internals_html); do \
 | 
					 | 
				
			||||||
	  rm -f $(DESTDIR)$(HTML_DIR)/$$f; \
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	for f in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
 | 
						for f in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
 | 
				
			||||||
	  rm -f $(DESTDIR)$(DEVHELP_DIR)/$$(basename $$f); \
 | 
						  rm $(DESTDIR)$(DEVHELP_DIR)/$$(basename $$f); \
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								docs/acl.html.in
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								docs/acl.html.in
									
									
									
									
									
								
							@@ -1,100 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					 | 
				
			||||||
    <h1>Client access control</h1>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Libvirt's client access control framework allows administrators
 | 
					 | 
				
			||||||
      to setup fine grained permission rules across client users,
 | 
					 | 
				
			||||||
      managed objects and API operations. This allows client connections
 | 
					 | 
				
			||||||
      to be locked down to a minimal set of privileges.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="intro">Access control introduction</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      In a default configuration, the libvirtd daemon has three levels
 | 
					 | 
				
			||||||
      of access control. All connections start off in an unauthenticated
 | 
					 | 
				
			||||||
      state, where the only API operations allowed are those required
 | 
					 | 
				
			||||||
      to complete authentication. After successful authentication, a
 | 
					 | 
				
			||||||
      connection either has full, unrestricted access to all libvirt
 | 
					 | 
				
			||||||
      API calls, or is locked down to only "read only" operations,
 | 
					 | 
				
			||||||
      according to what socket a client connection originated on.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The access control framework allows authenticated connections to
 | 
					 | 
				
			||||||
      have fine grained permission rules to be defined by the administrator.
 | 
					 | 
				
			||||||
      Every API call in libvirt has a set of permissions that will
 | 
					 | 
				
			||||||
      be validated against the object being used. For example, the
 | 
					 | 
				
			||||||
      <code>virDomainSetSchedulerParametersFlags</code> method will
 | 
					 | 
				
			||||||
      check whether the client user has the <code>write</code>
 | 
					 | 
				
			||||||
      permission on the <code>domain</code> object instance passed
 | 
					 | 
				
			||||||
      in as a parameter. Further permissions will also be checked
 | 
					 | 
				
			||||||
      if certain flags are set in the API call. In addition to
 | 
					 | 
				
			||||||
      checks on the object passed in to an API call, some methods
 | 
					 | 
				
			||||||
      will filter their results. For example the <code>virConnectListAllDomains</code>
 | 
					 | 
				
			||||||
      method will check the <code>search_domains</code> on the <code>connect</code>
 | 
					 | 
				
			||||||
      object, but will also filter the returned <code>domain</code>
 | 
					 | 
				
			||||||
      objects to only those on which the client user has the
 | 
					 | 
				
			||||||
      <code>getattr</code> permission.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="drivers">Access control drivers</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The access control framework is designed as a pluggable
 | 
					 | 
				
			||||||
      system to enable future integration with arbitrary access
 | 
					 | 
				
			||||||
      control technologies. By default, the <code>none</code>
 | 
					 | 
				
			||||||
      driver is used, which does no access control checks at
 | 
					 | 
				
			||||||
      all. At this time, libvirt ships with support for using
 | 
					 | 
				
			||||||
      <a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a> as a real access
 | 
					 | 
				
			||||||
      control driver. To learn how to use the polkit access
 | 
					 | 
				
			||||||
      driver consult <a href="aclpolkit.html">the configuration
 | 
					 | 
				
			||||||
      docs</a>.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The access driver is configured in the <code>libvirtd.conf</code>
 | 
					 | 
				
			||||||
      configuration file, using the <code>access_drivers</code>
 | 
					 | 
				
			||||||
      parameter. This parameter accepts an array of access control
 | 
					 | 
				
			||||||
      driver names. If more than one access driver is requested,
 | 
					 | 
				
			||||||
      then all must succeed in order for access to be granted.
 | 
					 | 
				
			||||||
      To enable 'polkit' as the driver:
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <pre>
 | 
					 | 
				
			||||||
# augtool -s set '/files/etc/libvirt/libvirtd.conf/access_drivers[1]' polkit
 | 
					 | 
				
			||||||
    </pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      And to reset back to the default (no-op) driver
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <pre>
 | 
					 | 
				
			||||||
# augtool -s rm /files/etc/libvirt/libvirtd.conf/access_drivers
 | 
					 | 
				
			||||||
    </pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      <strong>Note:</strong> changes to libvirtd.conf require that
 | 
					 | 
				
			||||||
      the libvirtd daemon be restarted.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="perms">Objects and permissions</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Libvirt applies access control to all the main object
 | 
					 | 
				
			||||||
      types in its API. Each object type, in turn, has a set
 | 
					 | 
				
			||||||
      of permissions defined. To determine what permissions
 | 
					 | 
				
			||||||
      are checked for specific API call, consult the
 | 
					 | 
				
			||||||
      <a href="html/index.html">API reference manual</a>
 | 
					 | 
				
			||||||
      documentation for the API in question.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div id="include" filename="aclperms.htmlinc"/>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  </body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
@@ -1,531 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					 | 
				
			||||||
    <h1>Polkit access control</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Libvirt's client <a href="acl.html">access control framework</a> allows
 | 
					 | 
				
			||||||
      administrators to setup fine grained permission rules across client users,
 | 
					 | 
				
			||||||
      managed objects and API operations. This allows client connections
 | 
					 | 
				
			||||||
      to be locked down to a minimal set of privileges. The polkit driver
 | 
					 | 
				
			||||||
      provides a simple implementation of the access control framework.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="intro">Introduction</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      A default install of libvirt will typically use
 | 
					 | 
				
			||||||
      <a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a>
 | 
					 | 
				
			||||||
      to authenticate the initial user connection to libvirtd. This is a
 | 
					 | 
				
			||||||
      very coarse grained check though, either allowing full read-write
 | 
					 | 
				
			||||||
      access to all APIs, or just read-only access. The polkit access
 | 
					 | 
				
			||||||
      control driver in libvirt builds on this capability to allow for
 | 
					 | 
				
			||||||
      fine grained control over the operations a user may perform on an
 | 
					 | 
				
			||||||
      object.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="perms">Permission names</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The libvirt <a href="acl.html#perms">object names and permission names</a>
 | 
					 | 
				
			||||||
      are mapped onto polkit action names using the simple pattern:
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <pre>org.libvirt.api.$object.$permission
 | 
					 | 
				
			||||||
</pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The only caveat is that any underscore characters in the
 | 
					 | 
				
			||||||
      object or permission names are converted to hyphens. So,
 | 
					 | 
				
			||||||
      for example, the <code>search_storage_vols</code> permission
 | 
					 | 
				
			||||||
      on the <code>storage_pool</code> object maps to the polkit
 | 
					 | 
				
			||||||
      action:
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <pre>org.libvirt.api.storage-pool.search-storage-vols
 | 
					 | 
				
			||||||
</pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The default policy for any permission which corresponds to
 | 
					 | 
				
			||||||
      a "read only" operation, is to allow access. All other
 | 
					 | 
				
			||||||
      permissions default to deny access.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="attrs">Object identity attributes</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      To allow polkit authorization rules to be written to match
 | 
					 | 
				
			||||||
      against individual object instances, libvirt provides a number
 | 
					 | 
				
			||||||
      of authorization detail attributes when performing a permission
 | 
					 | 
				
			||||||
      check. The set of attributes varies according to the type
 | 
					 | 
				
			||||||
      of object being checked
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_connect">virConnectPtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_domain">virDomainPtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>domain_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the domain, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>domain_uuid</td>
 | 
					 | 
				
			||||||
          <td>UUID of the domain, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_interface">virInterfacePtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>interface_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the network interface, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>interface_macaddr</td>
 | 
					 | 
				
			||||||
          <td>MAC address of the network interface, not unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_network">virNetworkPtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>network_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the network, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>network_uuid</td>
 | 
					 | 
				
			||||||
          <td>UUID of the network, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_node_device">virNodeDevicePtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>node_device_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the node device, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_nwfilter">virNWFilterPtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>nwfilter_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the network filter, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>nwfilter_uuid</td>
 | 
					 | 
				
			||||||
          <td>UUID of the network filter, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_secret">virSecretPtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>secret_uuid</td>
 | 
					 | 
				
			||||||
          <td>UUID of the secret, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>secret_usage_volume</td>
 | 
					 | 
				
			||||||
          <td>Name of the associated volume, if any</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>secret_usage_ceph</td>
 | 
					 | 
				
			||||||
          <td>Name of the associated Ceph server, if any</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <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 class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>pool_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the storage pool, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>pool_uuid</td>
 | 
					 | 
				
			||||||
          <td>UUID of the storage pool, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_storage_vol">virStorageVolPtr</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Attribute</th>
 | 
					 | 
				
			||||||
          <th>Description</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>connect_driver</td>
 | 
					 | 
				
			||||||
          <td>Name of the libvirt connection driver</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>pool_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the storage pool, unique to the local host</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>pool_uuid</td>
 | 
					 | 
				
			||||||
          <td>UUID of the storage pool, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>vol_name</td>
 | 
					 | 
				
			||||||
          <td>Name of the storage volume, unique to the pool</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>vol_key</td>
 | 
					 | 
				
			||||||
          <td>Key of the storage volume, globally unique</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="connect_driver">Hypervisor Driver connect_driver</a></h2>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>connect_driver</code> parameter describes the
 | 
					 | 
				
			||||||
      client's <a href="remote.html">remote Connection Driver</a>
 | 
					 | 
				
			||||||
      name based on the <a href="uri.html">URI</a> used for the
 | 
					 | 
				
			||||||
      connection.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      <span class="since">Since 4.1.0</span>, when calling an API
 | 
					 | 
				
			||||||
      outside the scope of the primary connection driver, the
 | 
					 | 
				
			||||||
      primary driver will attempt to open a secondary connection
 | 
					 | 
				
			||||||
      to the specific API driver in order to process the API. For
 | 
					 | 
				
			||||||
      example, when hypervisor domain processing needs to make an
 | 
					 | 
				
			||||||
      API call within the storage driver or the network filter driver
 | 
					 | 
				
			||||||
      an attempt to open a connection to the "storage" or "nwfilter"
 | 
					 | 
				
			||||||
      driver will be made. Similarly, a "storage" primary connection
 | 
					 | 
				
			||||||
      may need to create a connection to the "secret" driver in order
 | 
					 | 
				
			||||||
      to process secrets for the API. If successful, then calls to
 | 
					 | 
				
			||||||
      those API's will occur in the <code>connect_driver</code> context
 | 
					 | 
				
			||||||
      of the secondary connection driver rather than in the context of
 | 
					 | 
				
			||||||
      the primary driver. This affects the <code>connect_driver</code>
 | 
					 | 
				
			||||||
      returned from rule generation from the <code>action.loookup</code>
 | 
					 | 
				
			||||||
      function. The following table provides a list of the various
 | 
					 | 
				
			||||||
      connection drivers and the <code>connect_driver</code> name
 | 
					 | 
				
			||||||
      used by each regardless of primary or secondary connection.
 | 
					 | 
				
			||||||
      The access denied error message from libvirt will list the
 | 
					 | 
				
			||||||
      connection driver by name that denied the access.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="object_connect_driver">Connection Driver Name</a></h3>
 | 
					 | 
				
			||||||
    <table class="acl">
 | 
					 | 
				
			||||||
      <thead>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <th>Connection Driver</th>
 | 
					 | 
				
			||||||
          <th><code>connect_driver</code> name</th>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </thead>
 | 
					 | 
				
			||||||
      <tbody>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>bhyve</td>
 | 
					 | 
				
			||||||
          <td>bhyve</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>esx</td>
 | 
					 | 
				
			||||||
          <td>ESX</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>hyperv</td>
 | 
					 | 
				
			||||||
          <td>Hyper-V</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>interface</td>
 | 
					 | 
				
			||||||
          <td>interface</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>libxl</td>
 | 
					 | 
				
			||||||
          <td>xenlight</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>lxc</td>
 | 
					 | 
				
			||||||
          <td>LXC</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>network</td>
 | 
					 | 
				
			||||||
          <td>network</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>nodedev</td>
 | 
					 | 
				
			||||||
          <td>nodedev</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>nwfilter</td>
 | 
					 | 
				
			||||||
          <td>NWFilter</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>openvz</td>
 | 
					 | 
				
			||||||
          <td>OPENVZ</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>phyp</td>
 | 
					 | 
				
			||||||
          <td>PHYP</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>qemu</td>
 | 
					 | 
				
			||||||
          <td>QEMU</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>secret</td>
 | 
					 | 
				
			||||||
          <td>secret</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>storage</td>
 | 
					 | 
				
			||||||
          <td>storage</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>vbox</td>
 | 
					 | 
				
			||||||
          <td>VBOX</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>vmware</td>
 | 
					 | 
				
			||||||
          <td>VMWARE</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>vz</td>
 | 
					 | 
				
			||||||
          <td>vz</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>xenapi</td>
 | 
					 | 
				
			||||||
          <td>XenAPI</td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </tbody>
 | 
					 | 
				
			||||||
    </table>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="user">User identity attributes</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      At this point in time, the only attribute provided by
 | 
					 | 
				
			||||||
      libvirt to identify the user invoking the operation
 | 
					 | 
				
			||||||
      is the PID of the client program. This means that the
 | 
					 | 
				
			||||||
      polkit access control driver is only useful if connections
 | 
					 | 
				
			||||||
      to libvirt are restricted to its UNIX domain socket. If
 | 
					 | 
				
			||||||
      connections are being made to a TCP socket, no identifying
 | 
					 | 
				
			||||||
      information is available and access will be denied.
 | 
					 | 
				
			||||||
      Also note that if the client is connecting via an SSH
 | 
					 | 
				
			||||||
      tunnel, it is the local SSH user that will be identified.
 | 
					 | 
				
			||||||
      In future versions, it is expected that more information
 | 
					 | 
				
			||||||
      about the client user will be provided, including the
 | 
					 | 
				
			||||||
      SASL / Kerberos username and/or x509 distinguished
 | 
					 | 
				
			||||||
      name obtained from the authentication provider in use.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="checks">Writing access control policies</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      If using versions of polkit prior to 0.106 then it is only
 | 
					 | 
				
			||||||
      possible to validate (user, permission) pairs via the <code>.pkla</code>
 | 
					 | 
				
			||||||
      files. Fully validation of the (user, permission, object) triple
 | 
					 | 
				
			||||||
      requires the new JavaScript <code>.rules</code> support that
 | 
					 | 
				
			||||||
      was introduced in version 0.106. The latter is what will be
 | 
					 | 
				
			||||||
      described here.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Libvirt does not ship any rules files by default. It merely
 | 
					 | 
				
			||||||
      provides a definition of the default behaviour for each
 | 
					 | 
				
			||||||
      action (permission). As noted earlier, permissions which
 | 
					 | 
				
			||||||
      correspond to read-only operations in libvirt will be allowed
 | 
					 | 
				
			||||||
      to all users by default; everything else is denied by default.
 | 
					 | 
				
			||||||
      Defining custom rules requires creation of a file in the
 | 
					 | 
				
			||||||
      <code>/etc/polkit-1/rules.d</code> directory with a name
 | 
					 | 
				
			||||||
      chosen by the administrator (<code>100-libvirt-acl.rules</code>
 | 
					 | 
				
			||||||
      would be a reasonable choice). See the <code>polkit(8)</code>
 | 
					 | 
				
			||||||
      manual page for a description of how to write these files
 | 
					 | 
				
			||||||
      in general. The key idea is to create a file containing
 | 
					 | 
				
			||||||
      something like
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <pre>
 | 
					 | 
				
			||||||
polkit.addRule(function(action, subject) {
 | 
					 | 
				
			||||||
  ....logic to check 'action' and 'subject'...
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
    </pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      In this code snippet above, the <code>action</code> object
 | 
					 | 
				
			||||||
      instance will represent the libvirt permission being checked
 | 
					 | 
				
			||||||
      along with identifying attributes for the object it is being
 | 
					 | 
				
			||||||
      applied to. The <code>subject</code> meanwhile will identify
 | 
					 | 
				
			||||||
      the libvirt client app (with the caveat above about it only
 | 
					 | 
				
			||||||
      dealing with local clients connected via the UNIX socket).
 | 
					 | 
				
			||||||
      On the <code>action</code> object, the permission name is
 | 
					 | 
				
			||||||
      accessible via the <code>id</code> attribute, while the
 | 
					 | 
				
			||||||
      object identifying attributes are exposed via the
 | 
					 | 
				
			||||||
      <code>lookup</code> method.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
    See
 | 
					 | 
				
			||||||
    <a href="https://libvirt.org/git/?p=libvirt.git;a=tree;f=examples/polkit;hb=HEAD">source code</a>
 | 
					 | 
				
			||||||
    for a more complex example.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="exconnect">Example: restricting ability to connect to drivers</a></h3>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Consider a local user <code>berrange</code>
 | 
					 | 
				
			||||||
      who has been granted permission to connect to libvirt in
 | 
					 | 
				
			||||||
      full read-write mode. The goal is to only allow them to
 | 
					 | 
				
			||||||
      use the <code>QEMU</code> driver and not the Xen or LXC
 | 
					 | 
				
			||||||
      drivers which are also available in libvirtd.
 | 
					 | 
				
			||||||
      To achieve this we need to write a rule which checks
 | 
					 | 
				
			||||||
      whether the <code>connect_driver</code> attribute
 | 
					 | 
				
			||||||
      is <code>QEMU</code>, and match on an action
 | 
					 | 
				
			||||||
      name of <code>org.libvirt.api.connect.getattr</code>. Using
 | 
					 | 
				
			||||||
      the javascript rules format, this ends up written as
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <pre>
 | 
					 | 
				
			||||||
polkit.addRule(function(action, subject) {
 | 
					 | 
				
			||||||
    if (action.id == "org.libvirt.api.connect.getattr" &&
 | 
					 | 
				
			||||||
        subject.user == "berrange") {
 | 
					 | 
				
			||||||
          if (action.lookup("connect_driver") == 'QEMU') {
 | 
					 | 
				
			||||||
            return polkit.Result.YES;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            return polkit.Result.NO;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
    </pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="exdomain">Example: restricting access to a single domain</a></h3>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Consider a local user <code>berrange</code>
 | 
					 | 
				
			||||||
      who has been granted permission to connect to libvirt in
 | 
					 | 
				
			||||||
      full read-write mode. The goal is to only allow them to
 | 
					 | 
				
			||||||
      see the domain called <code>demo</code> on the LXC driver.
 | 
					 | 
				
			||||||
      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
 | 
					 | 
				
			||||||
      name of <code>org.libvirt.api.domain.getattr</code>. Using
 | 
					 | 
				
			||||||
      the javascript rules format, this ends up written as
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <pre>
 | 
					 | 
				
			||||||
polkit.addRule(function(action, subject) {
 | 
					 | 
				
			||||||
    if (action.id == "org.libvirt.api.domain.getattr" &&
 | 
					 | 
				
			||||||
        subject.user == "berrange") {
 | 
					 | 
				
			||||||
          if (action.lookup("connect_driver") == 'LXC' &&
 | 
					 | 
				
			||||||
              action.lookup("domain_name") == 'demo') {
 | 
					 | 
				
			||||||
            return polkit.Result.YES;
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            return polkit.Result.NO;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
    </pre>
 | 
					 | 
				
			||||||
  </body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 13 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 16 KiB  | 
							
								
								
									
										412
									
								
								docs/api.html.in
									
									
									
									
									
								
							
							
						
						
									
										412
									
								
								docs/api.html.in
									
									
									
									
									
								
							@@ -1,6 +1,5 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					<html>
 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1>The libvirt API concepts</h1>
 | 
					    <h1>The libvirt API concepts</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,31 +8,26 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					    <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
 | 
					    <p> As defined in the <a href="goals.html">goals section</a>, libvirt
 | 
				
			||||||
    API is designed to expose all the resources needed to manage the
 | 
					    API need to expose all the resources needed to manage the virtualization
 | 
				
			||||||
    virtualization support of recent operating systems. The first object
 | 
					    support of recent operating systems. The first object manipulated though
 | 
				
			||||||
    manipulated through the API is the <code>virConnectPtr</code>, which
 | 
					    the API is <code>virConnectPtr</code> which represent a connection to
 | 
				
			||||||
    represents the connection to a hypervisor. Any application using libvirt
 | 
					    an hypervisor. Any application using libvirt is likely to start using the
 | 
				
			||||||
    is likely to start using the
 | 
					    API by calling one of <a href="html/libvirt-libvirt.html#virConnectOpen"
 | 
				
			||||||
    API by calling one of <a href="html/libvirt-libvirt-host.html#virConnectOpen"
 | 
					 | 
				
			||||||
    >the virConnectOpen functions</a>. You will note that those functions take
 | 
					    >the virConnectOpen functions</a>. You will note that those functions take
 | 
				
			||||||
    a name argument which is actually a <a href="uri.html">connection URI</a>
 | 
					    a name argument which is actually an URI to select the right hypervisor to
 | 
				
			||||||
    to select the right hypervisor to open.
 | 
					    open, this is needed to allow remote connections and also select between
 | 
				
			||||||
    A URI is needed to allow remote connections and also select between
 | 
					    different possible hypervisors (for example on a Linux system it may be
 | 
				
			||||||
    different possible hypervisors. For example, on a Linux system it may be
 | 
					    possible to use both KVM and LinuxContainers on the same node). A NULL
 | 
				
			||||||
    possible to use both KVM and LinuxContainers on the same node. A NULL
 | 
					    name will default to a preselected hypervisor but it's probably not a
 | 
				
			||||||
    name will default to a preselected hypervisor, but it's probably not a
 | 
					 | 
				
			||||||
    wise thing to do in most cases. See the <a href="uri.html">connection
 | 
					    wise thing to do in most cases. See the <a href="uri.html">connection
 | 
				
			||||||
    URI</a> page for a full descriptions of the values allowed.</p>
 | 
					    URI</a> page for a full descriptions of the values allowed.</p>
 | 
				
			||||||
    <p> OnDevice the application obtains a
 | 
					    <p> Once the application obtained a <code class='docref'>virConnectPtr</code>
 | 
				
			||||||
      <a href="/html/libvirt-libvirt-host.html#virConnectPtr">
 | 
					    connection to the
 | 
				
			||||||
        <code>virConnectPtr</code>
 | 
					    hypervisor it can then use it to manage domains and related resources
 | 
				
			||||||
      </a>
 | 
					    available for virtualization like storage and networking. All those are
 | 
				
			||||||
    connection to the hypervisor it can then use it to manage the hypervisor's
 | 
					    exposed as first class objects, and connected to the hypervisor connection
 | 
				
			||||||
    available domains and related virtualization
 | 
					 | 
				
			||||||
    resources, such as storage and networking. All those are
 | 
					 | 
				
			||||||
    exposed as first class objects and connected to the hypervisor connection
 | 
					 | 
				
			||||||
    (and the node or cluster where it is available).</p>
 | 
					    (and the node or cluster where it is available).</p>
 | 
				
			||||||
    <p class="image">
 | 
					    <p class="image">
 | 
				
			||||||
      <img alt="first class objects exposed by the API"
 | 
					      <img alt="first class objects exposed by the API"
 | 
				
			||||||
@@ -41,340 +35,92 @@
 | 
				
			|||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <p> The figure above shows the five main objects exported by the API:</p>
 | 
					    <p> The figure above shows the five main objects exported by the API:</p>
 | 
				
			||||||
    <ul>
 | 
					    <ul>
 | 
				
			||||||
      <li>
 | 
					      <li>virConnectPtr: represent a connection to an hypervisor.</li>
 | 
				
			||||||
        <a href="html/libvirt-libvirt-host.html#virConnectPtr">
 | 
					      <li>virDomainPtr: represent one domain either active or defined (i.e.
 | 
				
			||||||
          <code>virConnectPtr</code>
 | 
					      existing as permanent config file and storage but not currently running
 | 
				
			||||||
        </a>
 | 
					      on that node). The function <code class='docref'>virConnectListDomains</code>
 | 
				
			||||||
      <p>Represents the connection to a hypervisor. Use one of the
 | 
					      allows to list all the IDs for the domains active on this hypervisor.</li>
 | 
				
			||||||
      <a href="html/libvirt-libvirt-host.html#virConnectOpen">virConnectOpen</a>
 | 
					      <li>virNetworkPtr: represent one network either active or defined (i.e.
 | 
				
			||||||
      functions to obtain connection to the hypervisor which is then used
 | 
					      existing as permanent config file and storage but not currently activated.
 | 
				
			||||||
      as a parameter to other connection API's.</p></li>
 | 
					      The function <code class='docref'>virConnectListNetworks</code>
 | 
				
			||||||
      <li>
 | 
					      allows to list all the virtualization networks activated on this node.</li>
 | 
				
			||||||
        <a href="html/libvirt-libvirt-domain.html#virDomainPtr">
 | 
					      <li>virStorageVolPtr: represent one storage volume, usually this is used
 | 
				
			||||||
          <code>virDomainPtr</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      <p>Represents one domain either active or defined (i.e. existing as
 | 
					 | 
				
			||||||
      permanent config file and storage but not currently running on that
 | 
					 | 
				
			||||||
      node). The function
 | 
					 | 
				
			||||||
        <a href="html/libvirt-libvirt-domain.html#virConnectListAllDomains">
 | 
					 | 
				
			||||||
          <code>virConnectListAllDomains</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      lists all the domains for the hypervisor.</p></li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <a href="html/libvirt-libvirt-network.html#virNetworkPtr">
 | 
					 | 
				
			||||||
          <code>virNetworkPtr</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      <p>Represents one network either active or defined (i.e. existing
 | 
					 | 
				
			||||||
      as permanent config file and storage but not currently activated).
 | 
					 | 
				
			||||||
      The function
 | 
					 | 
				
			||||||
        <a href="html/libvirt-libvirt-network.html#virConnectListAllNetworks">
 | 
					 | 
				
			||||||
          <code>virConnectListAllNetworks</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      lists all the virtualization networks for the hypervisor.</p></li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <a href="html/libvirt-libvirt-storage.html#virStorageVolPtr">
 | 
					 | 
				
			||||||
          <code>virStorageVolPtr</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      <p>Represents one storage volume generally used
 | 
					 | 
				
			||||||
      as a block device available to one of the domains. The function
 | 
					      as a block device available to one of the domains. The function
 | 
				
			||||||
        <a href="html/libvirt-libvirt-storage.html#virStorageVolLookupByPath">
 | 
					      <code class="docref">virStorageVolLookupByPath</code> allows to find
 | 
				
			||||||
          <code>virStorageVolLookupByPath</code>
 | 
					      the object based on its path on the node.</li>
 | 
				
			||||||
        </a>
 | 
					      <li>virStoragePoolPtr: represent a storage pool, i.e. a logical area
 | 
				
			||||||
      finds the storage volume object based on its path on the node.</p></li>
 | 
					      which can be used to allocate and store storage volumes. The function
 | 
				
			||||||
      <li>
 | 
					      <code class="docref">virStoragePoolLookupByVolume</code> allows to find
 | 
				
			||||||
        <a href="html/libvirt-libvirt-storage.html#virStoragePoolPtr">
 | 
					      the storage pool containing a given storage volume.</li>
 | 
				
			||||||
          <code>virStoragePoolPtr</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      <p>Represents a storage pool, which is a logical area
 | 
					 | 
				
			||||||
      used to allocate and store storage volumes. The function
 | 
					 | 
				
			||||||
        <a href="html/libvirt-libvirt-storage.html#virConnectListAllStoragePools">
 | 
					 | 
				
			||||||
          <code>virConnectListAllStoragePools</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      lists all of the virtualization storage pools on the hypervisor.
 | 
					 | 
				
			||||||
      The function
 | 
					 | 
				
			||||||
        <a href="html/libvirt-libvirt-storage.html#virStoragePoolLookupByVolume">
 | 
					 | 
				
			||||||
          <code>virStoragePoolLookupByVolume</code>
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      finds the storage pool containing a given storage volume.</p></li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    <p> Most objects manipulated by the library can also be represented using
 | 
					    <p> Most object manipulated by the library can also be represented using
 | 
				
			||||||
      XML descriptions. This is used primarily to create those object, but is
 | 
					      XML descriptions. This is used primarily to create those object, but is
 | 
				
			||||||
      also helpful to modify or save their description back.</p>
 | 
					      also helpful to modify or save their description back.</p>
 | 
				
			||||||
    <p> Domains, networks, and storage pools can be either <code>active</code>
 | 
					    <p> Domains, network and storage pools can be either <code>active</code>
 | 
				
			||||||
      i.e. either running or available for immediate use, or
 | 
					      i.e. either running or available for immediate use, or
 | 
				
			||||||
      <code>defined</code> in which case they are inactive but there is
 | 
					      <code>defined</code> in which case they are inactive but there is
 | 
				
			||||||
      a permanent definition available in the system for them. Based on this
 | 
					      a permanent definition available in the system for them. Based on this
 | 
				
			||||||
      they can be activated dynamically in order to be used.</p>
 | 
					      thay can be activated dynamically in order to be used.</p>
 | 
				
			||||||
    <p> Most objects can also be named in various ways:</p>
 | 
					    <p> Most kind of object can also be named in various ways:</p>
 | 
				
			||||||
    <ul>
 | 
					    <ul>
 | 
				
			||||||
      <li><code>name</code>
 | 
					      <li>by their <code>name</code>, an user friendly identifier but
 | 
				
			||||||
      <p>A user friendly identifier but whose uniqueness
 | 
					      whose unicity cannot be garanteed between two nodes.</li>
 | 
				
			||||||
      cannot be guaranteed between two nodes.</p></li>
 | 
					      <li>by their <code>ID</code>, which is a runtime unique identifier
 | 
				
			||||||
      <li><code>ID</code>
 | 
					      provided by the hypervisor for one given activation of the object,
 | 
				
			||||||
      <p>A runtime unique identifier
 | 
					      but it becomes invalid once the resource is deactivated.</li >
 | 
				
			||||||
      provided by the hypervisor for one given activation of the object;
 | 
					      <li>by their <code>UUID</code>, a 16 bytes unique identifier
 | 
				
			||||||
      however, it becomes invalid once the resource is deactivated.</p></li >
 | 
					 | 
				
			||||||
      <li><code>UUID</code>
 | 
					 | 
				
			||||||
      <p> A 16 byte unique identifier
 | 
					 | 
				
			||||||
      as defined in <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>,
 | 
					      as defined in <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>,
 | 
				
			||||||
      which is guaranteed to be unique for long term usage and across a
 | 
					      which is garanteed to be unique for long term usage and across a
 | 
				
			||||||
      set of nodes.</p></li>
 | 
					      set of nodes.</li>
 | 
				
			||||||
    </ul>
 | 
					    </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
 | 
					    <p> The naming of the functions present in the library is usually
 | 
				
			||||||
      composed by a prefix describing the object associated to the function
 | 
					      made of a prefix describing the object associated to the function
 | 
				
			||||||
      and a verb describing the action on that object.</p>
 | 
					      and a verb describing the action on that object.</p>
 | 
				
			||||||
    <p> For each first class object you will find APIs
 | 
					    <p> For each first class object you will find apis
 | 
				
			||||||
      for the following actions:</p>
 | 
					      for the following actions:</p>
 | 
				
			||||||
    <ul>
 | 
					    <ul>
 | 
				
			||||||
      <li><b>Lookup</b> [...LookupBy...]
 | 
					      <li><b>Lookup</b>:...LookupByName,</li>
 | 
				
			||||||
      <p>Used to perform lookups on objects by some type of identifier,
 | 
					      <li><b>Enumeration</b>:virConnectList... and virConnectNumOf...:
 | 
				
			||||||
      such as:</p>
 | 
					        those are used to enumerate a set of object available to an given
 | 
				
			||||||
          <ul>
 | 
					        hypervisor connection like:
 | 
				
			||||||
            <li>
 | 
					        <code class='docref'>virConnectListDomains</code>,
 | 
				
			||||||
              <a href="html/libvirt-libvirt-domain.html#virDomainLookupByID">
 | 
					        <code class='docref'>virConnectNumOfDomains</code>,
 | 
				
			||||||
                <code>virDomainLookupByID</code>
 | 
					        <code class='docref'>virConnectListNetworks</code>,
 | 
				
			||||||
              </a>
 | 
					        <code class='docref'>virConnectListStoragePools</code>, etc.</li>
 | 
				
			||||||
            </li>
 | 
					      <li><b>Description</b>: ...GetInfo: those are generic accessor providing
 | 
				
			||||||
            <li>
 | 
					        a set of informations about an object, they are
 | 
				
			||||||
              <a href="html/libvirt-libvirt-domain.html#virDomainLookupByName">
 | 
					        <code class='docref'>virNodeGetInfo</code>,
 | 
				
			||||||
                <code>virDomainLookupByName</code>
 | 
					        <code class='docref'>virDomainGetInfo</code>,
 | 
				
			||||||
              </a>
 | 
					        <code class='docref'>virStoragePoolGetInfo</code>,
 | 
				
			||||||
            </li>
 | 
					        <code class='docref'>virStorageVolGetInfo</code>.</li>
 | 
				
			||||||
            <li>
 | 
					      <li><b>Accessors</b>: ...Get... and ...Set...: those are more specific
 | 
				
			||||||
              <a href="html/libvirt-libvirt-domain.html#virDomainLookupByUUID">
 | 
					        accessors to query or modify the given object, like
 | 
				
			||||||
                <code>virDomainLookupByUUID</code>
 | 
					        <code class='docref'>virConnectGetType</code>,
 | 
				
			||||||
              </a>
 | 
					        <code class='docref'>virDomainGetMaxMemory</code>,
 | 
				
			||||||
            </li>
 | 
					        <code class='docref'>virDomainSetMemory</code>,
 | 
				
			||||||
            <li>
 | 
					        <code class='docref'>virDomainGetVcpus</code>,
 | 
				
			||||||
              <a href="html/libvirt-libvirt-domain.html#virDomainLookupByUUIDString">
 | 
					        <code class='docref'>virStoragePoolSetAutostart</code>,
 | 
				
			||||||
                <code>virDomainLookupByUUIDString</code>
 | 
					        <code class='docref'>virNetworkGetBridgeName</code>, etc.</li>
 | 
				
			||||||
              </a>
 | 
					      <li><b>Creation</b>: </li>
 | 
				
			||||||
            </li>
 | 
					      <li><b>Destruction</b>: ... </li>
 | 
				
			||||||
          </ul>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li><b>Enumeration</b> [virConnectList..., virConnectNumOf...]
 | 
					 | 
				
			||||||
      <p>Used to enumerate a set of object available to a given
 | 
					 | 
				
			||||||
      hypervisor connection such as:</p>
 | 
					 | 
				
			||||||
          <ul>
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <a href="html/libvirt-libvirt-domain.html#virConnectListDomains">
 | 
					 | 
				
			||||||
                <code>virConnectListDomains</code>
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            </li>
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <a href="html/libvirt-libvirt-domain.html#virConnectNumOfDomains">
 | 
					 | 
				
			||||||
                <code>virConnectNumOfDomains</code>
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            </li>
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <a href="html/libvirt-libvirt-network.html#virConnectListNetworks">
 | 
					 | 
				
			||||||
                <code>virConnectListNetworks</code>
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            </li>
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <a href="html/libvirt-libvirt-storage.html#virConnectListStoragePools">
 | 
					 | 
				
			||||||
                <code>virConnectListStoragePools</code>
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            </li>
 | 
					 | 
				
			||||||
          </ul>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li><b>Description</b> [...GetInfo]
 | 
					 | 
				
			||||||
      <p>Generic accessor providing a set of generic information about an
 | 
					 | 
				
			||||||
      object, such as: </p>
 | 
					 | 
				
			||||||
        <ul>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-host.html#virNodeGetInfo">
 | 
					 | 
				
			||||||
              <code>virNodeGetInfo</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainGetInfo">
 | 
					 | 
				
			||||||
              <code>virDomainGetInfo</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-storage.html#virStoragePoolGetInfo">
 | 
					 | 
				
			||||||
              <code>virStoragePoolGetInfo</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-storage.html#virStorageVolGetInfo">
 | 
					 | 
				
			||||||
              <code>virStorageVolGetInfo</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
        </ul>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li><b>Accessors</b> [...Get..., ...Set...]
 | 
					 | 
				
			||||||
      <p>Specific accessors used to query or modify data for the given object,
 | 
					 | 
				
			||||||
      such as: </p>
 | 
					 | 
				
			||||||
        <ul>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-host.html#virConnectGetType">
 | 
					 | 
				
			||||||
              <code>virConnectGetType</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainGetMaxMemory">
 | 
					 | 
				
			||||||
              <code>virDomainGetMaxMemory</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainSetMemory">
 | 
					 | 
				
			||||||
              <code>virDomainSetMemory</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainGetVcpus">
 | 
					 | 
				
			||||||
              <code>virDomainGetVcpus</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-storage.html#virStoragePoolSetAutostart">
 | 
					 | 
				
			||||||
              <code>virStoragePoolSetAutostart</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-network.html#virNetworkGetBridgeName">
 | 
					 | 
				
			||||||
              <code>virNetworkGetBridgeName</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
        </ul>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li><b>Creation</b> [...Create, ...CreateXML]
 | 
					 | 
				
			||||||
      <p>Used to create and start objects.  The ...CreateXML APIs will create
 | 
					 | 
				
			||||||
      the object based on an XML description, while the ...Create APIs will
 | 
					 | 
				
			||||||
      create the object based on existing object pointer, such as: </p>
 | 
					 | 
				
			||||||
        <ul>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainCreate">
 | 
					 | 
				
			||||||
              <code>virDomainCreate</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainCreateXML">
 | 
					 | 
				
			||||||
              <code>virDomainCreateXML</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-network.html#virNetworkCreate">
 | 
					 | 
				
			||||||
              <code>virNetworkCreate</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-network.html#virNetworkCreateXML">
 | 
					 | 
				
			||||||
              <code>virNetworkCreateXML</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
        </ul>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li><b>Destruction</b> [...Destroy]
 | 
					 | 
				
			||||||
      <p>Used to shutdown or deactivate and destroy objects, such as: </p>
 | 
					 | 
				
			||||||
        <ul>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-domain.html#virDomainDestroy">
 | 
					 | 
				
			||||||
              <code>virDomainDestroy</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-network.html#virNetworkDestroy">
 | 
					 | 
				
			||||||
              <code>virNetworkDestroy</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li>
 | 
					 | 
				
			||||||
            <a href="html/libvirt-libvirt-storage.html#virStoragePoolDestroy">
 | 
					 | 
				
			||||||
              <code>virStoragePoolDestroy</code>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
        </ul>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    <p>Note: functions returning vir*Ptr (like the virDomainLookup functions)
 | 
					 | 
				
			||||||
    allocate memory which needs to be freed by the caller by the corresponding
 | 
					 | 
				
			||||||
    vir*Free function (e.g. virDomainFree for a virDomainPtr object).
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <p> For more in-depth details of the storage related APIs see
 | 
					    <p> For more in-depth details of the storage related APIs see
 | 
				
			||||||
      <a href="storage.html">the storage management page</a>.
 | 
					      <a href="storage.html">the storage management page</a>.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <h2><a id="Drivers">The libvirt Drivers</a></h2>
 | 
					    <h2><a name="Driver">The libvirt drivers</a></h2>
 | 
				
			||||||
    <p>Drivers are the basic building block for libvirt functionality
 | 
					    <p></p>
 | 
				
			||||||
    to support the capability to handle specific hypervisor driver calls.
 | 
					 | 
				
			||||||
    Drivers are discovered and registered during connection processing as
 | 
					 | 
				
			||||||
    part of the
 | 
					 | 
				
			||||||
      <a href="html/libvirt-libvirt-host.html#virInitialize">
 | 
					 | 
				
			||||||
        <code>virInitialize</code>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    API. Each driver
 | 
					 | 
				
			||||||
    has a registration API which loads up the driver specific function
 | 
					 | 
				
			||||||
    references for the libvirt APIs to call. The following is a simplistic
 | 
					 | 
				
			||||||
    view of the hypervisor driver mechanism. Consider the stacked list of
 | 
					 | 
				
			||||||
    drivers as a series of modules that can be plugged into the architecture
 | 
					 | 
				
			||||||
    depending on how libvirt is configured to be built.</p>
 | 
					 | 
				
			||||||
    <p class="image">
 | 
					    <p class="image">
 | 
				
			||||||
      <img alt="The libvirt driver architecture"
 | 
					      <img alt="The libvirt driver architecture"
 | 
				
			||||||
           src="libvirt-driver-arch.png"/>
 | 
					           src="libvirt-driver-arch.png"/>
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <p>The driver architecture is also used to support other virtualization
 | 
					    <h2><a name="Remote">Daemon and remote access</a></h2>
 | 
				
			||||||
    components such as storage, storage pools, host device, networking,
 | 
					    <p></p>
 | 
				
			||||||
    network interfaces, and network filters.</p>
 | 
					 | 
				
			||||||
    <p>See the <a href="drivers.html">libvirt drivers</a> page for more
 | 
					 | 
				
			||||||
    information on hypervisor and storage specific drivers.</p>
 | 
					 | 
				
			||||||
    <p>Not all drivers support every virtualization function possible.
 | 
					 | 
				
			||||||
    The <a href="hvsupport.html">libvirt API support matrix</a> lists
 | 
					 | 
				
			||||||
    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>
 | 
					 | 
				
			||||||
    <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,
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
    <a href="html/libvirt-libvirt-host.html#virInitialize">
 | 
					 | 
				
			||||||
      <code>virInitialize</code>
 | 
					 | 
				
			||||||
    </a>
 | 
					 | 
				
			||||||
    sequence as applications
 | 
					 | 
				
			||||||
    for client-side driver registrations, but then extends the registered
 | 
					 | 
				
			||||||
    driver list to encompass all known drivers supported for all driver
 | 
					 | 
				
			||||||
    types supported on the host. </p>
 | 
					 | 
				
			||||||
    <p>The libvirt client <a href="apps.html">applications</a> use a
 | 
					 | 
				
			||||||
    <a href="uri.html">URI</a> to obtain the <code>virConnectPtr</code>.
 | 
					 | 
				
			||||||
    The <code>virConnectPtr</code> keeps track of the driver connection
 | 
					 | 
				
			||||||
    plus a variety of other connections (network, interface, storage, etc.).
 | 
					 | 
				
			||||||
    The <code>virConnectPtr</code> is then used as a parameter to other
 | 
					 | 
				
			||||||
    virtualization <a href="#Functions">functions</a>. Depending upon the
 | 
					 | 
				
			||||||
    driver being used, calls will be routed through the remote driver to
 | 
					 | 
				
			||||||
    the libvirtd daemon. The daemon will reference the connection specific
 | 
					 | 
				
			||||||
    driver in order to retrieve the requested information and then pass
 | 
					 | 
				
			||||||
    back status and/or data through the connection back to the application.
 | 
					 | 
				
			||||||
    The application can then decide what to do with that data, such as
 | 
					 | 
				
			||||||
    display, write log data, etc. <a href="migration.html">Migration</a>
 | 
					 | 
				
			||||||
    is an example of many facets of the architecture in use.</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p class="image">
 | 
					    <p class="image">
 | 
				
			||||||
      <img alt="The libvirt daemon and remote architecture"
 | 
					      <img alt="The libvirt daemon and remote architecture"
 | 
				
			||||||
           src="libvirt-daemon-arch.png"/>
 | 
					           src="libvirt-daemon-arch.png"/>
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
    The key takeaway from the above diagram is that there is a remote driver
 | 
					 | 
				
			||||||
    which handles transactions for a majority of the drivers. The libvirtd
 | 
					 | 
				
			||||||
    daemon running on the host will receive transaction requests from the
 | 
					 | 
				
			||||||
    remote driver and will then query the hypervisor driver as specified in
 | 
					 | 
				
			||||||
    the <code>virConnectPtr</code> in order to fetch the data. The data will
 | 
					 | 
				
			||||||
    then be returned through the remote driver to the client application
 | 
					 | 
				
			||||||
    for processing.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <p>If you are interested in contributing to libvirt, read the
 | 
					 | 
				
			||||||
    <a href="http://wiki.libvirt.org/page/FAQ">FAQ</a> and
 | 
					 | 
				
			||||||
    <a href="hacking.html">hacking</a> guidelines to gain an understanding
 | 
					 | 
				
			||||||
    of basic rules and guidelines.  In order to add new API functionality
 | 
					 | 
				
			||||||
    follow the instructions regarding
 | 
					 | 
				
			||||||
    <a href="api_extension.html">implementing a new API in libvirt</a>.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  </body>
 | 
					  </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,4 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<html>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1>Implementing a new API in Libvirt</h1>
 | 
					    <h1>Implementing a new API in Libvirt</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -8,9 +6,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      This document walks you through the process of implementing a new
 | 
					      This document walks you through the process of implementing a new
 | 
				
			||||||
      API in libvirt.  Remember that new API consists of any new public
 | 
					      API in libvirt.  It uses as an example the addition of an API for
 | 
				
			||||||
      functions, as well as the addition of flags or extensions of XML used by
 | 
					      separating maximum from current vcpu usage of a domain, over
 | 
				
			||||||
      existing functions.
 | 
					      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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
@@ -22,7 +25,12 @@
 | 
				
			|||||||
      added to libvirt.  Someone may already be working on the feature you
 | 
					      added to libvirt.  Someone may already be working on the feature you
 | 
				
			||||||
      want.  Also, recognize that everything you write is likely to undergo
 | 
					      want.  Also, recognize that everything you write is likely to undergo
 | 
				
			||||||
      significant rework as you discuss it with the other developers, so
 | 
					      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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
@@ -34,7 +42,7 @@
 | 
				
			|||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
@@ -71,12 +79,14 @@
 | 
				
			|||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      Submit new code in the form of one patch per step.  That's not to say
 | 
					      Submit new code in the form shown in the example code: one patch
 | 
				
			||||||
      submit patches before you have working functionality--get the whole thing
 | 
					      per step.  That's not to say submit patches before you have working
 | 
				
			||||||
      working and make sure you're happy with it.  Then use git to break the
 | 
					      functionality--get the whole thing working and make sure you're happy
 | 
				
			||||||
      changes into pieces so you don't drop a big blob of code on the
 | 
					      with it.  Then use git or some other version control system that lets
 | 
				
			||||||
      mailing list in one go.  Also, you should follow the upstream tree, and
 | 
					      you rewrite your commit history and break patches into pieces so you
 | 
				
			||||||
      rebase your series to adapt your patches to work with any other changes
 | 
					      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.
 | 
					      that were accepted upstream during your development.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,6 +99,8 @@
 | 
				
			|||||||
      separately.
 | 
					      separately.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p>With that said, let's begin.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a name='publicapi'>Defining the public API</a></h2>
 | 
					    <h2><a name='publicapi'>Defining the public API</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>The first task is to define the public API.  If the new API
 | 
					    <p>The first task is to define the public API.  If the new API
 | 
				
			||||||
@@ -96,7 +108,7 @@
 | 
				
			|||||||
      schema and document the new elements or attributes:</p>
 | 
					      schema and document the new elements or attributes:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>
 | 
					    <p><code>
 | 
				
			||||||
        docs/schemas/domaincommon.rng<br/>
 | 
					        docs/schemas/domain.rng<br/>
 | 
				
			||||||
        docs/formatdomain.html.in
 | 
					        docs/formatdomain.html.in
 | 
				
			||||||
    </code></p>
 | 
					    </code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,7 +118,7 @@
 | 
				
			|||||||
      libvirt library and call the new function:</p>
 | 
					      libvirt library and call the new function:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>
 | 
					    <p><code>
 | 
				
			||||||
        include/libvirt/libvirt-$MODULE.h.in
 | 
					        include/libvirt/libvirt.h.in
 | 
				
			||||||
        src/libvirt_public.syms
 | 
					        src/libvirt_public.syms
 | 
				
			||||||
    </code></p>
 | 
					    </code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,6 +131,10 @@
 | 
				
			|||||||
      rework it as you go through the process of implementing it.
 | 
					      rework it as you go through the process of implementing it.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p class="example">See <a href="api_extension/0001-add-to-xml.patch">0001-add-to-xml.patch</a>
 | 
				
			||||||
 | 
					    and <a href="api_extension/0002-add-new-public-API.patch">0002-add-new-public-API.patch</a>
 | 
				
			||||||
 | 
					    for example code.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a name='internalapi'>Defining the internal API</a></h2>
 | 
					    <h2><a name='internalapi'>Defining the internal API</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
@@ -137,7 +153,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <p>The driver structs are defined in:</p>
 | 
					    <p>The driver structs are defined in:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>src/driver-$MODULE.h</code></p>
 | 
					    <p><code>src/driver.h</code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      To define the internal API, first typedef the driver function
 | 
					      To define the internal API, first typedef the driver function
 | 
				
			||||||
@@ -146,6 +162,8 @@
 | 
				
			|||||||
      provide a <code>NULL</code> stub for the new function.
 | 
					      provide a <code>NULL</code> stub for the new function.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p class="example">See <a href="api_extension/0003-define-internal-driver-API.patch">0003-define-internal-driver-API.patch</a></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a name='implpublic'>Implementing the public API</a></h2>
 | 
					    <h2><a name='implpublic'>Implementing the public API</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
@@ -160,13 +178,12 @@
 | 
				
			|||||||
        being called and its parameters;</li>
 | 
					        being called and its parameters;</li>
 | 
				
			||||||
      <li>MUST call virResetLastError();</li>
 | 
					      <li>MUST call virResetLastError();</li>
 | 
				
			||||||
      <li>SHOULD confirm that the connection is valid with
 | 
					      <li>SHOULD confirm that the connection is valid with
 | 
				
			||||||
        virCheckConnectReturn() or virCheckConnectGoto();</li>
 | 
					        VIR_IS_CONNECT(conn);</li>
 | 
				
			||||||
      <li><strong>SECURITY: If the API requires a connection with write
 | 
					      <li><strong>SECURITY: If the API requires a connection with write
 | 
				
			||||||
          privileges, MUST confirm that the connection flags do not
 | 
					          privileges, MUST confirm that the connection flags do not
 | 
				
			||||||
          indicate that the connection is read-only with
 | 
					          indicate that the connection is read-only;</strong></li>
 | 
				
			||||||
          virCheckReadOnlyGoto();</strong></li>
 | 
					 | 
				
			||||||
      <li>SHOULD do basic validation of the parameters that are being
 | 
					      <li>SHOULD do basic validation of the parameters that are being
 | 
				
			||||||
        passed in, using helpers like virCheckNonNullArgGoto();</li>
 | 
					        passed in;</li>
 | 
				
			||||||
      <li>MUST confirm that the driver for this connection exists and that
 | 
					      <li>MUST confirm that the driver for this connection exists and that
 | 
				
			||||||
        it implements this function;</li>
 | 
					        it implements this function;</li>
 | 
				
			||||||
      <li>MUST call the internal API;</li>
 | 
					      <li>MUST call the internal API;</li>
 | 
				
			||||||
@@ -177,16 +194,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <p>The public API calls are implemented in:</p>
 | 
					    <p>The public API calls are implemented in:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>src/libvirt-$MODULE.c</code></p>
 | 
					    <p><code>src/libvirt.c</code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p class="example">See <a href="api_extension/0004-implement-the-public-APIs.patch">0004-implement-the-public-APIs.patch</a></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a name='remoteproto'>Implementing the remote protocol</a></h2>
 | 
					    <h2><a name='remoteproto'>Implementing the remote protocol</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      Implementing the remote protocol is essentially a
 | 
					      Implementing the remote protocol is essentially a
 | 
				
			||||||
      straightforward exercise which is probably most easily
 | 
					      straightforward exercise which is probably most easily
 | 
				
			||||||
      understood by referring to the existing code.
 | 
					      understood by referring to the existing code and the example
 | 
				
			||||||
 | 
					      patch.  It involves several related changes, including the
 | 
				
			||||||
 | 
					      regeneration of derived files, with further details below.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <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>
 | 
					    <h3><a name='wireproto'>Defining the wire protocol format</a></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
@@ -219,9 +242,9 @@
 | 
				
			|||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>
 | 
					    <p><code>
 | 
				
			||||||
        src/remote/remote_daemon_dispatch_stubs.h
 | 
					        daemon/remote_dispatch_args.h
 | 
				
			||||||
        src/remote/remote_daemon_dispatch.h
 | 
					        daemon/remote_dispatch_prototypes.h
 | 
				
			||||||
        src/remote/remote_daemon_dispatch.c
 | 
					        daemon/remote_dispatch_table.h
 | 
				
			||||||
        src/remote/remote_protocol.c
 | 
					        src/remote/remote_protocol.c
 | 
				
			||||||
        src/remote/remote_protocol.h
 | 
					        src/remote/remote_protocol.h
 | 
				
			||||||
    </code></p>
 | 
					    </code></p>
 | 
				
			||||||
@@ -233,7 +256,7 @@
 | 
				
			|||||||
      method calls go in:
 | 
					      method calls go in:
 | 
				
			||||||
    </p>
 | 
					    </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>
 | 
					    <p>Each remote method invocation does the following:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -247,7 +270,7 @@
 | 
				
			|||||||
      <li>unlocks the remote driver.</li>
 | 
					      <li>unlocks the remote driver.</li>
 | 
				
			||||||
    </ol>
 | 
					    </ol>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h3><a id="serverdispatch">Implement the server side dispatcher</a></h3>
 | 
					    <h3><a name="serverdispatch">Implement the server side dispatcher</a></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      Implementing the server side of the remote function call is simply a
 | 
					      Implementing the server side of the remote function call is simply a
 | 
				
			||||||
@@ -256,7 +279,7 @@
 | 
				
			|||||||
      The server side dispatchers are implemented in:
 | 
					      The server side dispatchers are implemented in:
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>src/remote/daemon_dispatch.c</code></p>
 | 
					    <p><code>daemon/remote.c</code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>Again, this step uses the .h files generated by make rpcgen.</p>
 | 
					    <p>Again, this step uses the .h files generated by make rpcgen.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -272,7 +295,9 @@
 | 
				
			|||||||
      existing lines probably imply a backwards-incompatible API change.
 | 
					      existing lines probably imply a backwards-incompatible API change.
 | 
				
			||||||
    </p>
 | 
					    </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>
 | 
					    <p>
 | 
				
			||||||
      Sometimes, a new API serves as a superset of existing API, by
 | 
					      Sometimes, a new API serves as a superset of existing API, by
 | 
				
			||||||
@@ -284,7 +309,9 @@
 | 
				
			|||||||
      not necessary if the new API has no relation to existing API.
 | 
					      not necessary if the new API has no relation to existing API.
 | 
				
			||||||
    </p>
 | 
					    </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>
 | 
					    <p>
 | 
				
			||||||
      All new API should be manageable from the virsh command line
 | 
					      All new API should be manageable from the virsh command line
 | 
				
			||||||
@@ -309,11 +336,13 @@
 | 
				
			|||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p><code>
 | 
					    <p><code>
 | 
				
			||||||
        tools/virsh-$MODULE.c<br/>
 | 
					        tools/virsh.c<br/>
 | 
				
			||||||
        tools/virsh.pod
 | 
					        tools/virsh.pod
 | 
				
			||||||
    </code></p>
 | 
					    </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>
 | 
					    <p>
 | 
				
			||||||
      So, after all that, we get to the fun part.  All functionality in
 | 
					      So, after all that, we get to the fun part.  All functionality in
 | 
				
			||||||
@@ -324,7 +353,7 @@
 | 
				
			|||||||
      adding.
 | 
					      adding.
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h3><a id="commonimpl">Implement common handling</a></h3>
 | 
					    <h3><a name="commonimpl">Implement common handling</a></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      If the new API is applicable to more than one driver, it may
 | 
					      If the new API is applicable to more than one driver, it may
 | 
				
			||||||
@@ -339,7 +368,9 @@
 | 
				
			|||||||
      the same way as the older API wrappers.
 | 
					      the same way as the older API wrappers.
 | 
				
			||||||
    </p>
 | 
					    </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>
 | 
					    <p>
 | 
				
			||||||
      The remaining patches should only touch one driver at a time.
 | 
					      The remaining patches should only touch one driver at a time.
 | 
				
			||||||
@@ -350,14 +381,41 @@
 | 
				
			|||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      It is always a good idea to patch the test driver in addition to the
 | 
					      In the example patches, three separate drivers are supported:
 | 
				
			||||||
      target driver, to prove that the API can be used for more than one
 | 
					      test, qemu, and xen.  It is always a good idea to patch the test
 | 
				
			||||||
      driver.
 | 
					      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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <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>
 | 
					    <p>
 | 
				
			||||||
      Any cleanups resulting from the changes should be added as separate
 | 
					      The qemu changes were easier to split into two phases, one for
 | 
				
			||||||
      patches at the end of the series.
 | 
					      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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										1694
									
								
								docs/apibuild.py
									
									
									
									
									
								
							
							
						
						
									
										1694
									
								
								docs/apibuild.py
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 10 KiB  | 
@@ -1,8 +1,6 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<html>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1>Applications using libvirt</h1>
 | 
					    <h1>Applications using <strong>libvirt</strong></h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      This page provides an illustration of the wide variety of
 | 
					      This page provides an illustration of the wide variety of
 | 
				
			||||||
@@ -11,7 +9,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					    <ul id="toc"></ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="add">Add an application</a></h2>
 | 
					    <h2><a name="add">Add an application</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      To add an application not listed on this page, send a message
 | 
					      To add an application not listed on this page, send a message
 | 
				
			||||||
@@ -19,18 +17,35 @@
 | 
				
			|||||||
      be added here, or simply send a patch against the documentation
 | 
					      be added here, or simply send a patch against the documentation
 | 
				
			||||||
      in the libvirt.git docs subdirectory.
 | 
					      in the libvirt.git docs subdirectory.
 | 
				
			||||||
      If your application uses libvirt as its API,
 | 
					      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:
 | 
					      support for libvirt:
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p class="image">
 | 
					    <p class="image">
 | 
				
			||||||
      <img src="logos/logo-square-powered-96.png" alt="libvirt powered"/>
 | 
					      <img src="madeWith.png" alt="Made with libvirt"/>
 | 
				
			||||||
      <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"/>
 | 
					 | 
				
			||||||
    </p>
 | 
					    </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>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="http://libguestfs.org">guestfish</a></dt>
 | 
					      <dt><a href="http://libguestfs.org">guestfish</a></dt>
 | 
				
			||||||
@@ -45,21 +60,21 @@
 | 
				
			|||||||
        management tasks on all libvirt managed domains, networks and
 | 
					        management tasks on all libvirt managed domains, networks and
 | 
				
			||||||
        storage. This is part of the libvirt core distribution.
 | 
					        storage. This is part of the libvirt core distribution.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://virt-manager.org/">virt-clone</a></dt>
 | 
					      <dt><a href="http://virt-manager.org/">virt-clone</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Allows the disk image(s) and configuration for an existing
 | 
					        Allows the disk image(s) and configuration for an existing
 | 
				
			||||||
        virtual machine to be cloned to form a new virtual machine.
 | 
					        virtual machine to be cloned to form a new virtual machine.
 | 
				
			||||||
        It automates copying of data across to new disk images, and
 | 
					        It automates copying of data across to new disk images, and
 | 
				
			||||||
        updates the UUID, MAC address, and name in the configuration.
 | 
					        updates the UUID, MAC address, and name in the configuration.
 | 
				
			||||||
      </dd>
 | 
					      </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>
 | 
					      <dd>
 | 
				
			||||||
        Examine the utilization of each filesystem in a virtual machine
 | 
					        Examine the utilization of each filesystem in a virtual machine
 | 
				
			||||||
        from the comfort of the host machine. This tool peeks into the
 | 
					        from the comfort of the host machine. This tool peeks into the
 | 
				
			||||||
        guest disks and determines how much space is used. It can cope
 | 
					        guest disks and determines how much space is used. It can cope
 | 
				
			||||||
        with common Linux filesystems and LVM volumes.
 | 
					        with common Linux filesystems and LVM volumes.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://virt-manager.org/">virt-image</a></dt>
 | 
					      <dt><a href="http://virt-manager.org/">virt-image</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Provides a way to deploy virtual appliances. It defines a
 | 
					        Provides a way to deploy virtual appliances. It defines a
 | 
				
			||||||
        simplified portable XML format describing the pre-requisites
 | 
					        simplified portable XML format describing the pre-requisites
 | 
				
			||||||
@@ -67,47 +82,28 @@
 | 
				
			|||||||
        into the domain XML format for execution under any libvirt
 | 
					        into the domain XML format for execution under any libvirt
 | 
				
			||||||
        hypervisor meeting the pre-requisites.
 | 
					        hypervisor meeting the pre-requisites.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://virt-manager.org/">virt-install</a></dt>
 | 
					      <dt><a href="http://virt-manager.org/">virt-install</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Provides a way to provision new virtual machines from a
 | 
					        Provides a way to provision new virtual machines from a
 | 
				
			||||||
        OS distribution install tree. It supports provisioning from
 | 
					        OS distribution install tree. It supports provisioning from
 | 
				
			||||||
        local CD images, and the network over NFS, HTTP and FTP.
 | 
					        local CD images, and the network over NFS, HTTP and FTP.
 | 
				
			||||||
      </dd>
 | 
					      </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>
 | 
					      <dd>
 | 
				
			||||||
        Watch the CPU, memory, network and disk utilization of all
 | 
					        Watch the CPU, memory, network and disk utilization of all
 | 
				
			||||||
        virtual machines running on a host.
 | 
					        virtual machines running on a host.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt>
 | 
					      <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>
 | 
					      </dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        virt-what is a shell script for detecting if the program is running
 | 
					        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
 | 
					        in a virtual machine.  It prints out a list of facts about the
 | 
				
			||||||
        virtual machine, derived from heuristics.
 | 
					        virtual machine, derived from heuristics.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://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
 | 
					 | 
				
			||||||
        application stap can use libvirt to gather data within virtual
 | 
					 | 
				
			||||||
        machines.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
      <dt><a href="https://github.com/pradels/vagrant-libvirt/">vagrant-libvirt</a></dt>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        Vagrant-Libvirt is a Vagrant plugin that uses libvirt to manage virtual
 | 
					 | 
				
			||||||
        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>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="configmgmt">Configuration Management</a></h2>
 | 
					    <h2><a name="configmgmt">Configuration Management</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="https://wiki.lcfg.org/bin/view/LCFG/LcfgLibvirt">LCFG</a></dt>
 | 
					      <dt><a href="https://wiki.lcfg.org/bin/view/LCFG/LcfgLibvirt">LCFG</a></dt>
 | 
				
			||||||
@@ -125,10 +121,10 @@
 | 
				
			|||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="continuousintegration">Continuous Integration</a></h2>
 | 
					    <h2><a name="continuousintegration">Continuous Integration</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <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>
 | 
					      <dd>
 | 
				
			||||||
        BuildBot is a system to automate the compile/test cycle required
 | 
					        BuildBot is a system to automate the compile/test cycle required
 | 
				
			||||||
        by most software projects.  CVS commits trigger new builds, run on
 | 
					        by most software projects.  CVS commits trigger new builds, run on
 | 
				
			||||||
@@ -138,7 +134,7 @@
 | 
				
			|||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <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>
 | 
					      <dd>
 | 
				
			||||||
        This plugin for Jenkins adds a way to control guest domains hosted
 | 
					        This plugin for Jenkins adds a way to control guest domains hosted
 | 
				
			||||||
        on Xen or QEMU/KVM.  You configure a Jenkins Slave,
 | 
					        on Xen or QEMU/KVM.  You configure a Jenkins Slave,
 | 
				
			||||||
@@ -149,24 +145,28 @@
 | 
				
			|||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="conversion">Conversion</a></h2>
 | 
					    <h2><a name="conversion">Conversion</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="http://libguestfs.org/virt-p2v.1.html">virt-p2v</a></dt>
 | 
					      <dt><a href="https://rwmj.wordpress.com/2009/10/13/poor-mans-p2v/">Poor mans p2v</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Convert a physical machine to run on KVM.  It is a LiveCD
 | 
					        A simple approach for converting a physical machine to a virtual
 | 
				
			||||||
        which is booted on the machine to be converted.  It collects a
 | 
					        machine, using a rescue CD.
 | 
				
			||||||
        little information from the user, then copies the disks over
 | 
					 | 
				
			||||||
        to a remote machine and defines the XML for a domain to run
 | 
					 | 
				
			||||||
        the guest.  (Note this tool is included with libguestfs)
 | 
					 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="http://libguestfs.org/virt-v2v.1.html">virt-v2v</a></dt>
 | 
					      <dt><a href="http://et.redhat.com/~rjones/virt-p2v/">virt-p2v</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        virt-v2v converts guests from a foreign hypervisor to run on
 | 
					        An older tool for converting a physical machine into a virtual
 | 
				
			||||||
        KVM, managed by libvirt.  It can convert guests from VMware or
 | 
					        machine.  It is a LiveCD which is booted on the machine to be
 | 
				
			||||||
        Xen to run on OpenStack, oVirt (RHEV-M), or local libvirt.  It
 | 
					        converted.  It collects a little information from the user, then
 | 
				
			||||||
 | 
					        copies the disks over to a remote machine and defines the XML for a
 | 
				
			||||||
 | 
					        domain to run the guest.
 | 
				
			||||||
 | 
					      </dd>
 | 
				
			||||||
 | 
					      <dt><a href="http://git.fedorahosted.org/git/?p=virt-v2v.git;a=summary">virt-v2v</a></dt>
 | 
				
			||||||
 | 
					      <dd>
 | 
				
			||||||
 | 
					        virt-v2v converts guests from a foreign hypervisor to run on KVM,
 | 
				
			||||||
 | 
					        managed by libvirt.  It can currently convert Red Hat Enterprise
 | 
				
			||||||
 | 
					        Linux (RHEL) and Fedora guests running on Xen and VMware ESX.  It
 | 
				
			||||||
        will enable VirtIO drivers in the converted guest if possible.
 | 
					        will enable VirtIO drivers in the converted guest if possible.
 | 
				
			||||||
        (Note this tool is included with libguestfs)
 | 
					 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        For RHEL customers of Red Hat, conversion of Windows guests is also
 | 
					        For RHEL customers of Red Hat, conversion of Windows guests is also
 | 
				
			||||||
@@ -180,47 +180,39 @@
 | 
				
			|||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="desktop">Desktop applications</a></h2>
 | 
					    <h2><a name="desktop">Desktop applications</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="https://virt-manager.org/">virt-manager</a></dt>
 | 
					      <dt><a href="http://virt-manager.org/">virt-manager</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        A general purpose desktop management tool, able to manage
 | 
					        A general purpose desktop management tool, able to manage
 | 
				
			||||||
        virtual machines across both local and remotely accessed
 | 
					        virtual machines across both local and remotely accessed
 | 
				
			||||||
        hypervisors. It is targeted at home and small office usage
 | 
					        hypervisors. It is targeted at home and small office usage
 | 
				
			||||||
        up to managing 10-20 hosts and their VMs.
 | 
					        upto managing 10-20 hosts and their VMs.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://virt-manager.org/">virt-viewer</a></dt>
 | 
					      <dt><a href="http://virt-manager.org/">virt-viewer</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        A lightweight tool for accessing the graphical console
 | 
					        A lightweight tool for accessing the graphical console
 | 
				
			||||||
        associated with a virtual machine. It can securely connect
 | 
					        associated with a virtual machine. It can securely connect
 | 
				
			||||||
        to remote consoles supporting the VNC protocol. Also provides
 | 
					        to remote consoles supporting the VNC protocol. Also provides
 | 
				
			||||||
        an optional mozilla browser plugin.
 | 
					        an optional mozilla browser plugin.
 | 
				
			||||||
      </dd>
 | 
					      </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>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="iaas">Infrastructure as a Service (IaaS)</a></h2>
 | 
					    <h2><a name="iaas">Infrastructure as a Service (IaaS)</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="http://cc1.ifj.edu.pl">Cracow Cloud One</a></dt>
 | 
					      <dt><a href="http://www.emotivecloud.net">EMOTIVE Cloud</a></dt>
 | 
				
			||||||
      <dd>The CC1 system provides a complete solution for Private
 | 
					      <dd>The EMOTIVE (Elastic Management Of Tasks In Virtualized
 | 
				
			||||||
        Cloud Computing. An intuitive web access interface with an
 | 
					        Environments) middleware allows executing tasks and providing
 | 
				
			||||||
        administration module and simple installation procedure make
 | 
					        virtualized environments to the users with Xen, KVM or
 | 
				
			||||||
        it easy to benefit from private Cloud Computing technology.
 | 
					        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>
 | 
					      </dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <dt><a href="https://github.com/eucalyptus/eucalyptus">Eucalyptus</a></dt>
 | 
					      <dt><a href="http://www.eucalyptus.com">Eucalyptus</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Eucalyptus is an on-premise Infrastructure as a Service cloud
 | 
					        Eucalyptus is an on-premise Infrastructure as a Service cloud
 | 
				
			||||||
        software platform that is open source and
 | 
					        software platform that is open source and
 | 
				
			||||||
@@ -243,38 +235,9 @@
 | 
				
			|||||||
        integrates libvirt for VM monitoring, live migration, and life-cycle
 | 
					        integrates libvirt for VM monitoring, live migration, and life-cycle
 | 
				
			||||||
        management.
 | 
					        management.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt><a href="https://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,
 | 
					 | 
				
			||||||
        storage and networking resources and interface with the user
 | 
					 | 
				
			||||||
        using a dashboard.  Compute part uses libvirt to manage VM
 | 
					 | 
				
			||||||
        life-cycle, monitoring and so on.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt><a href="https://github.com/gustavfranssonnyvell/cherrypop">Cherrypop</a></dt>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        A cloud software with no masters or central points. Nodes
 | 
					 | 
				
			||||||
        autodetect other nodes and autodistribute virtual
 | 
					 | 
				
			||||||
        machines and autodivide up the workload. Also there is no
 | 
					 | 
				
			||||||
        minimum limit for hosts, well, one might be nice. It's
 | 
					 | 
				
			||||||
        perfect for setting up low-end servers in a cloud or a
 | 
					 | 
				
			||||||
        cloud where you want the most bang for the bucks.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt><a href="http://en.zstack.io/">ZStack</a></dt>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        ZStack is an open source IaaS software that aims to automate the
 | 
					 | 
				
			||||||
        management of all resources (compute, storage, networking, etc.) in a
 | 
					 | 
				
			||||||
        datacenter by using APIs, thus conforming to the principles of a
 | 
					 | 
				
			||||||
        software-defined datacenter. The key strengths of ZStack in terms of
 | 
					 | 
				
			||||||
        management are scalability, performance, and a fast, user-friendly
 | 
					 | 
				
			||||||
        deployment.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="libraries">Libraries</a></h2>
 | 
					    <h2><a name="libraries">Libraries</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="http://libguestfs.org">libguestfs</a></dt>
 | 
					      <dt><a href="http://libguestfs.org">libguestfs</a></dt>
 | 
				
			||||||
@@ -289,28 +252,23 @@
 | 
				
			|||||||
        host, and there is a subproject to allow merging changes into the
 | 
					        host, and there is a subproject to allow merging changes into the
 | 
				
			||||||
        Windows Registry in Windows guests.
 | 
					        Windows Registry in Windows guests.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt><a href="https://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
 | 
					 | 
				
			||||||
        supports either KVM, QEMU or LXC as backends. Integration with
 | 
					 | 
				
			||||||
        systemd facilitates sandboxing of system services like apache.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
      <dt><a href="https://github.com/ohadlevy/virt#readme">Ruby
 | 
					 | 
				
			||||||
          Libvirt Object bindings</a></dt>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        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>.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="livecd">LiveCD / Appliances</a></h2>
 | 
					        <dl>
 | 
				
			||||||
 | 
					            <dt><a href="https://github.com/ohadlevy/virt#readme">Ruby
 | 
				
			||||||
 | 
					            Libvirt Object bindings</a></dt>
 | 
				
			||||||
 | 
					            <dd>
 | 
				
			||||||
 | 
					                Allows using simple ruby objects to manipulate
 | 
				
			||||||
 | 
					                hypervisors, guests, storage, network etc.  It is
 | 
				
			||||||
 | 
					                based on top of
 | 
				
			||||||
 | 
					                the <a href="http://libvirt.org/ruby">native ruby
 | 
				
			||||||
 | 
					                bindings</a>.
 | 
				
			||||||
 | 
					            </dd>
 | 
				
			||||||
 | 
					        </dl>
 | 
				
			||||||
 | 
					    <h2><a name="livecd">LiveCD / Appliances</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <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>
 | 
					      <dd>
 | 
				
			||||||
        An older tool for converting a physical machine into a virtual
 | 
					        An older tool for converting a physical machine into a virtual
 | 
				
			||||||
        machine.  It is a LiveCD which is booted on the machine to be
 | 
					        machine.  It is a LiveCD which is booted on the machine to be
 | 
				
			||||||
@@ -320,9 +278,9 @@
 | 
				
			|||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="monitoring">Monitoring</a></h2>
 | 
					    <h2><a name="monitoring">Monitoring</a></h2>
 | 
				
			||||||
    <dl>
 | 
					    <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>
 | 
					      <dd>
 | 
				
			||||||
        The libvirt-plugin is part of <a href="http://collectd.org/">collectd</a>
 | 
					        The libvirt-plugin is part of <a href="http://collectd.org/">collectd</a>
 | 
				
			||||||
        and gathers statistics about virtualized guests on a system. This
 | 
					        and gathers statistics about virtualized guests on a system. This
 | 
				
			||||||
@@ -331,19 +289,13 @@
 | 
				
			|||||||
        For a full description, please refer to the libvirt section in the
 | 
					        For a full description, please refer to the libvirt section in the
 | 
				
			||||||
        collectd.conf(5) manual page.
 | 
					        collectd.conf(5) manual page.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="http://www.sflow.net/">Host sFlow</a></dt>
 | 
					      <dt><a href="http://honk.sigxcpu.org/projects/libvirt/#munin">Munin</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Host sFlow is a lightweight agent running on KVM hypervisors that
 | 
					        The plugins provided by Guido Günther allow to monitor various things
 | 
				
			||||||
        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>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        The plugins provided by Guido Günther allow to monitor various things
 | 
					 | 
				
			||||||
        like network and block I/O with
 | 
					        like network and block I/O with
 | 
				
			||||||
        <a href="http://munin.projects.linpro.no/">Munin</a>.
 | 
					        <a href="http://munin.projects.linpro.no/">Munin</a>.
 | 
				
			||||||
      </dd>
 | 
					      </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>
 | 
					      <dd>
 | 
				
			||||||
        Nagios-virt is a configuration tool to add monitoring of your
 | 
					        Nagios-virt is a configuration tool to add monitoring of your
 | 
				
			||||||
        virtualised domains to <a href="http://www.nagios.org/">Nagios</a>.
 | 
					        virtualised domains to <a href="http://www.nagios.org/">Nagios</a>.
 | 
				
			||||||
@@ -351,20 +303,18 @@
 | 
				
			|||||||
        your Xen or QEMU/KVM guests, or to integrate with your existing Nagios
 | 
					        your Xen or QEMU/KVM guests, or to integrate with your existing Nagios
 | 
				
			||||||
        installation.
 | 
					        installation.
 | 
				
			||||||
      </dd>
 | 
					      </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>
 | 
					      <dd>
 | 
				
			||||||
        The PCP libvirt PMDA (plugin) is part of the
 | 
					        The Zenoss libvirt Zenpack adds support for monitoring virtualization
 | 
				
			||||||
        <a href="http://pcp.io/">PCP</a> toolkit and provides
 | 
					        servers.  It has been tested with KVM, QEMU, VMware ESX, and VMware
 | 
				
			||||||
        hypervisor and guest information and complete set of guest performance
 | 
					        GSX.
 | 
				
			||||||
        metrics. It supports pCPU, vCPU, memory, block device, network interface,
 | 
					 | 
				
			||||||
        and performance event metrics for each virtual guest.
 | 
					 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="provisioning">Provisioning</a></h2>
 | 
					    <h2><a name="provisioning">Provisioning</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <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>
 | 
					      <dd>
 | 
				
			||||||
        Part of the IBM Tivoli family, Tivoli Provisioning Manager (TPM) is
 | 
					        Part of the IBM Tivoli family, Tivoli Provisioning Manager (TPM) is
 | 
				
			||||||
        an IT lifecycle automation product.  It
 | 
					        an IT lifecycle automation product.  It
 | 
				
			||||||
@@ -374,7 +324,7 @@
 | 
				
			|||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="https://theforeman.org">Foreman</a></dt>
 | 
					      <dt><a href="http://theforeman.org">Foreman</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
      Foreman is an open source web based application aimed to be a
 | 
					      Foreman is an open source web based application aimed to be a
 | 
				
			||||||
      Single Address For All Machines Life Cycle Management. Foreman:
 | 
					      Single Address For All Machines Life Cycle Management. Foreman:
 | 
				
			||||||
@@ -390,15 +340,14 @@
 | 
				
			|||||||
          <li>Shows you Systems Inventory (based on Facter) and
 | 
					          <li>Shows you Systems Inventory (based on Facter) and
 | 
				
			||||||
          provides real time information about hosts status based on
 | 
					          provides real time information about hosts status based on
 | 
				
			||||||
          Puppet reports.</li>
 | 
					          Puppet reports.</li>
 | 
				
			||||||
      </ul>
 | 
					 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="web">Web applications</a></h2>
 | 
					    <h2><a name="web">Web applications</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="http://www.abiquo.com/">AbiCloud</a></dt>
 | 
					      <dt><a href="http://community.abiquo.com/display/AbiCloud">AbiCloud</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        AbiCloud is an open source cloud platform manager which allows to
 | 
					        AbiCloud is an open source cloud platform manager which allows to
 | 
				
			||||||
        easily deploy a private cloud in your datacenter. One of the key
 | 
					        easily deploy a private cloud in your datacenter. One of the key
 | 
				
			||||||
@@ -406,74 +355,23 @@
 | 
				
			|||||||
        infrastructure. You can deploy a new service just dragging and
 | 
					        infrastructure. You can deploy a new service just dragging and
 | 
				
			||||||
        dropping a VM.
 | 
					        dropping a VM.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://kimchi-project.github.io/kimchi/">Kimchi</a></dt>
 | 
					      <dt><a href="http://ovirt.org/">oVirt</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>
 | 
					 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        oVirt provides the ability to manage large numbers of virtual
 | 
					        oVirt provides the ability to manage large numbers of virtual
 | 
				
			||||||
        machines across an entire data center of hosts. It integrates
 | 
					        machines across an entire data center of hosts. It integrates
 | 
				
			||||||
        with FreeIPA for Kerberos authentication, and in the future,
 | 
					        with FreeIPA for Kerberos authentication, and in the future,
 | 
				
			||||||
        certificate management.
 | 
					        certificate management.
 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
      <dt><a href="https://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
 | 
					 | 
				
			||||||
        building a cloud.  VMmanager can manage not only one server,
 | 
					 | 
				
			||||||
        but a large cluster of hypervisors.  It delivers a number of
 | 
					 | 
				
			||||||
        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>
 | 
					 | 
				
			||||||
      <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
 | 
					 | 
				
			||||||
        interface for all of your infrastructure (multiple public cloud
 | 
					 | 
				
			||||||
        providers, OpenStack based public/private clouds, Docker servers, bare
 | 
					 | 
				
			||||||
        metal servers and now KVM hypervisors).
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
      <dt><a href="https://ravada.upc.edu/">Ravada</a></dt>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        Ravada is an open source tool for managing Virtual Desktop
 | 
					 | 
				
			||||||
        Infrastructure (VDI). It is very easy to install and use. Following
 | 
					 | 
				
			||||||
        the documentation, you'll be ready to deploy virtual machines in
 | 
					 | 
				
			||||||
        minutes. The only requirements for the users are a Web browser and
 | 
					 | 
				
			||||||
        a lightweight remote viewer.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
      <dt><a href="https://github.com/cutelyst/Virtlyst">Virtlyst</a></dt>
 | 
					 | 
				
			||||||
      <dd>
 | 
					 | 
				
			||||||
        Virtlyst is an open source web application built with C++11, Cutelyst and Qt.
 | 
					 | 
				
			||||||
        It features:
 | 
					 | 
				
			||||||
        <ul>
 | 
					 | 
				
			||||||
          <li>Low memory usage (around 5 MiB of RAM)</li>
 | 
					 | 
				
			||||||
          <li>Look and feel easily customized with HTML templates that use the Django syntax</li>
 | 
					 | 
				
			||||||
          <li>VNC/Spice console directly in the browser using websockets on the same HTTP port</li>
 | 
					 | 
				
			||||||
          <li>Host and Domain statistics graphs (CPU, Memory, IO, Network)</li>
 | 
					 | 
				
			||||||
          <li>Connect to multiple libvirtd instances (over local Unix domain socket, SSH, TCP and TLS)</li>
 | 
					 | 
				
			||||||
          <li>Manage Storage Pools, Storage Volumes, Networks, Interfaces, and Secrets</li>
 | 
					 | 
				
			||||||
          <li>Create and launch VMs</li>
 | 
					 | 
				
			||||||
          <li>Configure VMs with easy panels or go pro and edit the VM's XML</li>
 | 
					 | 
				
			||||||
        </ul>
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="other">Other</a></h2>
 | 
					    <h2><a name="mobile">Mobile applications</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <dl>
 | 
					    <dl>
 | 
				
			||||||
      <dt><a href="https://cuckoosandbox.org/">Cuckoo Sandbox</a></dt>
 | 
					      <dt><a href="https://market.android.com/details?id=vm.manager">VM Manager</a></dt>
 | 
				
			||||||
      <dd>
 | 
					      <dd>
 | 
				
			||||||
        Cuckoo Sandbox is a malware analysis system.  You can throw
 | 
					        VM Manager is VM (libvirt) manager (over SSH) application. VM Manager
 | 
				
			||||||
        any suspicious file at it and in a matter of seconds Cuckoo
 | 
					        is an application for libvirt VM / Domain management over SSH.
 | 
				
			||||||
        will provide you back some detailed results outlining what
 | 
					        Please keep in mind that this software is under heavy development.
 | 
				
			||||||
        such file did when executed inside an isolated environment.
 | 
					 | 
				
			||||||
        And libvirt is one of the backends that can be used for the
 | 
					 | 
				
			||||||
        isolated environment.
 | 
					 | 
				
			||||||
      </dd>
 | 
					      </dd>
 | 
				
			||||||
    </dl>
 | 
					    </dl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								docs/archdomain.html.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								docs/archdomain.html.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <h1>Domain management architecture</h1>
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					<html>
 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1 >libvirt architecture</h1>
 | 
					    <h1 >libvirt architecture</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -13,38 +12,54 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					    <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
 | 
					    <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
 | 
					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
 | 
					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
 | 
					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).
 | 
					hypervisor, the kernels, the drivers and the xen daemon. Xend. The xen daemon
 | 
				
			||||||
libxl provides a set of APIs for creating and managing domains, which can be used
 | 
					supervise the control and execution of the sets of domains. The hypervisor,
 | 
				
			||||||
by applications such as the xl tool provided by Xen or libvirt. The hypervisor,
 | 
					 | 
				
			||||||
drivers, kernels and daemons communicate though a shared system bus
 | 
					drivers, kernels and daemons communicate though a shared system bus
 | 
				
			||||||
implemented in the hypervisor. The figure below tries to provide a view of
 | 
					implemented in the hypervisor. The figure below tries to provide a view of
 | 
				
			||||||
this environment:</p>
 | 
					this environment:</p>
 | 
				
			||||||
    <img src="architecture.gif" alt="The Xen architecture" />
 | 
					    <img src="architecture.gif" alt="The Xen architecture" />
 | 
				
			||||||
    <p>The library will interact with libxl for all management operations
 | 
					    <p>The library can be initialized in 2 ways depending on the level of
 | 
				
			||||||
on a Xen system.</p>
 | 
					privilege of the embedding program. If it runs with root access,
 | 
				
			||||||
    <p>Note that the libvirt libxl driver only supports root access.</p>
 | 
					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
 | 
					    <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
 | 
					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
 | 
					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
 | 
					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
 | 
					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
 | 
					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
 | 
					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>
 | 
					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>
 | 
					<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
 | 
					    <p>As the previous section explains, libvirt can communicate using different
 | 
				
			||||||
channels with the current hypervisor, and should also be able to use
 | 
					channels with the current hypervisor, and should also be able to use
 | 
				
			||||||
@@ -67,9 +82,9 @@ drivers present in driver.h:</p>
 | 
				
			|||||||
    is in the <code>proxy/</code> directory.</li>
 | 
					    is in the <code>proxy/</code> directory.</li>
 | 
				
			||||||
      <li>xm_internal: provide support for Xen defined but not running
 | 
					      <li>xm_internal: provide support for Xen defined but not running
 | 
				
			||||||
    domains.</li>
 | 
					    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
 | 
					    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
 | 
					      <li>test: this is a test driver useful for regression tests of the
 | 
				
			||||||
    front-end part of libvirt.</li>
 | 
					    front-end part of libvirt.</li>
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								docs/archnetwork.html.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								docs/archnetwork.html.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <h1>Network management architecture</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ul id="toc"></ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h2><a name="architecture">Architecture illustration</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					      The diagrams below illustrate some of the network configurations
 | 
				
			||||||
 | 
					      enabled by the libvirt networking APIs
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ul>
 | 
				
			||||||
 | 
					      <li><strong>VLAN 1</strong>. This virtual network has connectivity
 | 
				
			||||||
 | 
					        to <code>LAN 2</code> with traffic forwarded and NATed.
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					      <li><strong>VLAN 2</strong>. This virtual network is completely
 | 
				
			||||||
 | 
					        isolated from any physical LAN.
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					      <li><strong>Guest A</strong>. The first network interface is bridged
 | 
				
			||||||
 | 
					        to the physical <code>LAN 1</code>. The second interface is connected
 | 
				
			||||||
 | 
					        to a virtual network <code>VLAN 1</code>.
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					      <li><strong>Guest B</strong>. The first network interface is connected
 | 
				
			||||||
 | 
					        to a virtual network <code>VLAN 1</code>, giving it limited NAT
 | 
				
			||||||
 | 
					        based connectivity to LAN2. It has a second network interface
 | 
				
			||||||
 | 
					        connected to <code>VLAN 2</code>. It acts a router allowing limited
 | 
				
			||||||
 | 
					        traffic between the two VLANs, thus giving <code>Guest C</code>
 | 
				
			||||||
 | 
					        connectivity to the physical <code>LAN 2</code>.
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					      <li><strong>Guest C</strong>. The only network interface is connected
 | 
				
			||||||
 | 
					        to a virtual network <code>VLAN 2</code>. It has no direct connectivity
 | 
				
			||||||
 | 
					        to a physical LAN, relying on <code>Guest B</code> to route traffic
 | 
				
			||||||
 | 
					        on its behalf.
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h3><a name="logical">Logical diagram</a></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p class="image">
 | 
				
			||||||
 | 
					      <img src="libvirt-net-logical.png" alt="Logical network architecture"/>
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h3><a name="physical">Physical diagram</a></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p class="image">
 | 
				
			||||||
 | 
					      <img src="libvirt-net-physical.png" alt="Physical network architecture"/>
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										5
									
								
								docs/archnode.html.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								docs/archnode.html.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <h1>Node device management architecture</h1>
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										30
									
								
								docs/archstorage.html.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								docs/archstorage.html.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <h1>Storage management architecture</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					      The storage management APIs are based around 2 core concepts
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    <ol>
 | 
				
			||||||
 | 
					      <li>
 | 
				
			||||||
 | 
					        <strong>Volume</strong> - a single storage volume which can
 | 
				
			||||||
 | 
					        be assigned to a guest, or used for creating further pools. A
 | 
				
			||||||
 | 
					        volume is either a block device, a raw file, or a special format
 | 
				
			||||||
 | 
					        file.
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					      <li>
 | 
				
			||||||
 | 
					        <strong>Pool</strong> - provides a means for taking a chunk
 | 
				
			||||||
 | 
					        of storage and carving it up into volumes. A pool can be used to
 | 
				
			||||||
 | 
					        manage things such as a physical disk, a NFS server, a iSCSI target,
 | 
				
			||||||
 | 
					        a host adapter, an LVM group.
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					    </ol>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					      These two concepts are mapped through to two libvirt objects, a
 | 
				
			||||||
 | 
					      <code>virStorageVolPtr</code> and a <code>virStoragePoolPtr</code>,
 | 
				
			||||||
 | 
					      each with a collection of APIs for their management.
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
@@ -1,375 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					 | 
				
			||||||
    <h1>Audit log</h1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="intro">Introduction</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      A number of the libvirt virtualization drivers (QEMU/KVM and LXC) include
 | 
					 | 
				
			||||||
      support for logging details of important operations to the host's audit
 | 
					 | 
				
			||||||
      subsystem. This provides administrators / auditors with a canonical historical
 | 
					 | 
				
			||||||
      record of changes to virtual machines' / containers' lifecycle states and
 | 
					 | 
				
			||||||
      their configuration. On hosts which are running the Linux audit daemon,
 | 
					 | 
				
			||||||
      the logs will usually end up in <code>/var/log/audit/audit.log</code>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="config">Configuration</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The libvirt audit integration is enabled by default on any host which has
 | 
					 | 
				
			||||||
      the Linux audit subsystem active, and disabled otherwise. It is possible
 | 
					 | 
				
			||||||
      to alter this behaviour in the <code>/etc/libvirt/libvirtd.conf</code>
 | 
					 | 
				
			||||||
      configuration file, via the <code>audit_level</code> parameter
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul>
 | 
					 | 
				
			||||||
      <li><code>audit_level=0</code> - libvirt auditing is disabled regardless
 | 
					 | 
				
			||||||
        of host audit subsystem enablement.</li>
 | 
					 | 
				
			||||||
      <li><code>audit_level=1</code> - libvirt auditing is enabled if the host
 | 
					 | 
				
			||||||
        audit subsystem is enabled, otherwise it is disabled. This is the
 | 
					 | 
				
			||||||
        default behaviour.</li>
 | 
					 | 
				
			||||||
      <li><code>audit_level=2</code> - libvirt auditing is enabled regardless
 | 
					 | 
				
			||||||
        of host audit subsystem enablement. If the host audit subsystem is
 | 
					 | 
				
			||||||
        disabled, then libvirtd will refuse to complete startup and exit with
 | 
					 | 
				
			||||||
        an error.</li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      In addition to have formal messages sent to the audit subsystem it is
 | 
					 | 
				
			||||||
      possible to tell libvirt to inject messages into its own logging
 | 
					 | 
				
			||||||
      layer. This will result in messages ending up in the systemd journal
 | 
					 | 
				
			||||||
      or <code>/var/log/libvirt/libivrtd.log</code> on non-systemd hosts.
 | 
					 | 
				
			||||||
      This is disabled by default, but can be requested by setting the
 | 
					 | 
				
			||||||
      <code>audit_logging=1</code> configuration parameter in the same file
 | 
					 | 
				
			||||||
      mentioned above.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h2><a id="types">Message types</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Libvirt defines three core audit message types each of which will
 | 
					 | 
				
			||||||
      be described below. There are a number of common fields that will
 | 
					 | 
				
			||||||
      be reported for all message types.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>pid</code></dt>
 | 
					 | 
				
			||||||
      <dd>Process ID of the libvirtd daemon generating the audit record.</dd>
 | 
					 | 
				
			||||||
      <dt><code>uid</code></dt>
 | 
					 | 
				
			||||||
      <dd>User ID of the libvirtd daemon process generating the audit record.</dd>
 | 
					 | 
				
			||||||
      <dt><code>subj</code></dt>
 | 
					 | 
				
			||||||
      <dd>Security context of the libvirtd daemon process generating the audit record.</dd>
 | 
					 | 
				
			||||||
      <dt><code>msg</code></dt>
 | 
					 | 
				
			||||||
      <dd>String containing a list of key=value pairs specific to the type of audit record being reported.</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Some fields in the <code>msg</code> string are common to audit records
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>virt</code></dt>
 | 
					 | 
				
			||||||
      <dd>Type of virtualization driver used. One of <code>qemu</code> or <code>lxc</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>vm</code></dt>
 | 
					 | 
				
			||||||
      <dd>Host driver unique name of the guest</dd>
 | 
					 | 
				
			||||||
      <dt><code>uuid</code></dt>
 | 
					 | 
				
			||||||
      <dd>Globally unique identifier for the guest</dd>
 | 
					 | 
				
			||||||
      <dt><code>exe</code></dt>
 | 
					 | 
				
			||||||
      <dd>Path of the libvirtd daemon</dd>
 | 
					 | 
				
			||||||
      <dt><code>hostname</code></dt>
 | 
					 | 
				
			||||||
      <dd>Currently unused</dd>
 | 
					 | 
				
			||||||
      <dt><code>addr</code></dt>
 | 
					 | 
				
			||||||
      <dd>Currently unused</dd>
 | 
					 | 
				
			||||||
      <dt><code>terminal</code></dt>
 | 
					 | 
				
			||||||
      <dd>Currently unused</dd>
 | 
					 | 
				
			||||||
      <dt><code>res</code></dt>
 | 
					 | 
				
			||||||
      <dd>Result of the action, either <code>success</code> or <code>failed</code></dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="typecontrol">VIRT_CONTROL</a></h3>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Reports change in the lifecycle state of a virtual machine. The <code>msg</code>
 | 
					 | 
				
			||||||
      field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>op</code></dt>
 | 
					 | 
				
			||||||
      <dd>Type of operation performed. One of <code>start</code>, <code>stop</code> or <code>init</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the operation to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>vm-pid</code></dt>
 | 
					 | 
				
			||||||
      <dd>ID of the primary/leading process associated with the guest</dd>
 | 
					 | 
				
			||||||
      <dt><code>init-pid</code></dt>
 | 
					 | 
				
			||||||
      <dd>ID of the <code>init</code> process in a container. Only if <code>op=init</code> and <code>virt=lxc</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>pid-ns</code></dt>
 | 
					 | 
				
			||||||
      <dd>Namespace ID of the <code>init</code> process in a container. Only if <code>op=init</code> and <code>virt=lxc</code></dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="typemachine">VIRT_MACHINE_ID</a></h3>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Reports the association of a security context with a guest. The <code>msg</code>
 | 
					 | 
				
			||||||
      field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>model</code></dt>
 | 
					 | 
				
			||||||
      <dd>The security driver type. One of <code>selinux</code> or <code>apparmor</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>vm-ctx</code></dt>
 | 
					 | 
				
			||||||
      <dd>Security context for the guest process</dd>
 | 
					 | 
				
			||||||
      <dt><code>img-ctx</code></dt>
 | 
					 | 
				
			||||||
      <dd>Security context for the guest disk images and other assigned host resources</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3><a id="typeresource">VIRT_RESOURCE</a></h3>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Reports the usage of a host resource by a guest. The fields include will
 | 
					 | 
				
			||||||
      vary according to the type of device being reported. When the guest is
 | 
					 | 
				
			||||||
      initially booted records will be generated for all assigned resources.
 | 
					 | 
				
			||||||
      If any changes are made to the running guest configuration, for example
 | 
					 | 
				
			||||||
      hotplug devices, or adjust resources allocation, further records will
 | 
					 | 
				
			||||||
      be generated.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcevcpu">Virtual CPU</a></h4>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>vcpu</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-vcpu</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original vCPU count, or 0</dd>
 | 
					 | 
				
			||||||
      <dt><code>new-vcpu</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated vCPU count</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcemem">Memory</a></h4>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>mem</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-mem</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original memory size in bytes, or 0</dd>
 | 
					 | 
				
			||||||
      <dt><code>new-mem</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated memory size in bytes</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcedisk">Disk</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>disk</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-disk</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original host file or device path acting as the disk backing file</dd>
 | 
					 | 
				
			||||||
      <dt><code>new-disk</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated host file or device path acting as the disk backing file</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcenic">Network interface</a></h4>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>net</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-net</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original MAC address of the guest network interface</dd>
 | 
					 | 
				
			||||||
      <dt><code>new-net</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated MAC address of the guest network interface</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      If there is a host network interface associated with the guest NIC then
 | 
					 | 
				
			||||||
      further records may be generated
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>net</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>net</code></dt>
 | 
					 | 
				
			||||||
      <dd>MAC address of the host network interface</dd>
 | 
					 | 
				
			||||||
      <dt><code>rdev</code></dt>
 | 
					 | 
				
			||||||
      <dd>Name of the host network interface</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcefs">Filesystem</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>fs</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-fs</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original host directory, file or device path backing the filesystem </dd>
 | 
					 | 
				
			||||||
      <dt><code>new-fs</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated host directory, file or device path backing the filesystem</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcehost">Host device</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>hostdev</code> or <code>dev</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>dev</code></dt>
 | 
					 | 
				
			||||||
      <dd>The unique bus identifier of the USB, PCI or SCSI device, if <code>resrc=dev</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>disk</code></dt>
 | 
					 | 
				
			||||||
      <dd>The path of the block device assigned to the guest, if <code>resrc=hostdev</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>chardev</code></dt>
 | 
					 | 
				
			||||||
      <dd>The path of the character device assigned to the guest, if <code>resrc=hostdev</code></dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcetpm">TPM</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>tpm</code> or <code>tpm-emulator</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>device</code></dt>
 | 
					 | 
				
			||||||
      <dd>The path of the host TPM device assigned to the guest</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcerng">RNG</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>rng</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-rng</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original path of the host entropy source for the RNG</dd>
 | 
					 | 
				
			||||||
      <dt><code>new-rng</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated path of the host entropy source for the RNG</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcechardev">console/serial/parallel/channel</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>chardev</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-chardev</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original path of the backing character device for given emulated device</dd>
 | 
					 | 
				
			||||||
      <dt><code>new-chardev</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated path of the backing character device for given emulated device</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcesmartcard">smartcard</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>smartcard</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>old-smartcard</code></dt>
 | 
					 | 
				
			||||||
      <dd>Original path of the backing character device, certificate store or
 | 
					 | 
				
			||||||
          "nss-smartcard-device" for host smartcard passthrough.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
      <dt><code>new-smartcard</code></dt>
 | 
					 | 
				
			||||||
      <dd>Updated path of the backing character device, certificate store or
 | 
					 | 
				
			||||||
          "nss-smartcard-device" for host smartcard passthrough.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourceredir">Redirected device</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>redir</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>bus</code></dt>
 | 
					 | 
				
			||||||
      <dd>The bus type, only <code>usb</code> allowed</dd>
 | 
					 | 
				
			||||||
      <dt><code>device</code></dt>
 | 
					 | 
				
			||||||
      <dd>The device type, only <code>USB redir</code> allowed</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourcecgroup">Control group</a></h4>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>cgroup</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>cgroup</code></dt>
 | 
					 | 
				
			||||||
      <dd>The name of the cgroup controller</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h4><a id="typeresourceshmem">Shared memory</a></h4>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      The <code>msg</code> field will include the following sub-fields
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt><code>resrc</code></dt>
 | 
					 | 
				
			||||||
      <dd>The type of resource assigned. Set to <code>shmem</code></dd>
 | 
					 | 
				
			||||||
      <dt><code>reason</code></dt>
 | 
					 | 
				
			||||||
      <dd>The reason which caused the resource to be assigned to happen</dd>
 | 
					 | 
				
			||||||
      <dt><code>size</code></dt>
 | 
					 | 
				
			||||||
      <dd>The size of the shared memory region</dd>
 | 
					 | 
				
			||||||
      <dt><code>shmem</code></dt>
 | 
					 | 
				
			||||||
      <dd>Name of the shared memory region</dd>
 | 
					 | 
				
			||||||
      <dt><code>source</code></dt>
 | 
					 | 
				
			||||||
      <dd>Path of the backing character device for given emulated device</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  </body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
@@ -1,20 +1,17 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					<html>
 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1>Connection authentication</h1>
 | 
					    <h1 >Authentication & access control</h1>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      When connecting to libvirt, some connections may require client
 | 
					      When connecting to libvirt, some connections may require client
 | 
				
			||||||
      authentication before allowing use of the APIs. The set of possible
 | 
					      authentication before allowing use of the APIs. The set of possible
 | 
				
			||||||
      authentication mechanisms is administrator controlled, independent
 | 
					      authentication mechanisms is administrator controlled, independent
 | 
				
			||||||
      of applications using libvirt. Once authenticated, libvirt can apply
 | 
					      of applications using libvirt.
 | 
				
			||||||
      fine grained <a href="acl.html">access control</a> to the operations
 | 
					 | 
				
			||||||
      performed by a client.
 | 
					 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ul id="toc"></ul>
 | 
					    <ul id="toc"></ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="Auth_client_config">Client configuration</a></h2>
 | 
					    <h2><a name="Auth_client_config">Client configuration</a></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      When connecting to a remote hypervisor which requires authentication,
 | 
					      When connecting to a remote hypervisor which requires authentication,
 | 
				
			||||||
@@ -28,7 +25,7 @@ for the authentication file using the following sequence:
 | 
				
			|||||||
        variable.</li>
 | 
					        variable.</li>
 | 
				
			||||||
      <li>The file path specified by the "authfile=/some/file" URI
 | 
					      <li>The file path specified by the "authfile=/some/file" URI
 | 
				
			||||||
        query parameter</li>
 | 
					        query parameter</li>
 | 
				
			||||||
      <li>The file $XDG_CONFIG_HOME/libvirt/auth.conf</li>
 | 
					      <li>The file $XDG_CONFIG_DIR/libvirt/auth.conf</li>
 | 
				
			||||||
      <li>The file /etc/libvirt/auth.conf</li>
 | 
					      <li>The file /etc/libvirt/auth.conf</li>
 | 
				
			||||||
    </ol>
 | 
					    </ol>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,11 +73,7 @@ password=letmein
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[credentials-dev]
 | 
					[credentials-dev]
 | 
				
			||||||
username=joe
 | 
					username=joe
 | 
				
			||||||
password=hello
 | 
					password=hello</pre>
 | 
				
			||||||
 | 
					 | 
				
			||||||
[credentials-defgrp]
 | 
					 | 
				
			||||||
username=defuser
 | 
					 | 
				
			||||||
password=defpw</pre>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      The second set of groups provide mappings of credentials to
 | 
					      The second set of groups provide mappings of credentials to
 | 
				
			||||||
@@ -94,8 +87,7 @@ credentials=$CREDENTIALS</pre>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      For example, following the previous example, here is how to
 | 
					      For example, following the previous example, here is how to
 | 
				
			||||||
      map some machines. For convenience libvirt supports a default
 | 
					      list some machines
 | 
				
			||||||
      mapping of credentials to machines:
 | 
					 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <pre>
 | 
					    <pre>
 | 
				
			||||||
@@ -111,15 +103,8 @@ credentials=test
 | 
				
			|||||||
[auth-libvirt-prod1.example.com]
 | 
					[auth-libvirt-prod1.example.com]
 | 
				
			||||||
credentials=prod
 | 
					credentials=prod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[auth-libvirt-default]
 | 
					 | 
				
			||||||
credentials=defgrp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[auth-esx-dev1.example.com]
 | 
					[auth-esx-dev1.example.com]
 | 
				
			||||||
credentials=dev
 | 
					credentials=dev</pre>
 | 
				
			||||||
 | 
					 | 
				
			||||||
[auth-esx-default]
 | 
					 | 
				
			||||||
credentials=defgrp</pre>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      The following service types are known to libvirt
 | 
					      The following service types are known to libvirt
 | 
				
			||||||
@@ -142,7 +127,7 @@ credentials=defgrp</pre>
 | 
				
			|||||||
      to storage VNC or SPICE login credentials
 | 
					      to storage VNC or SPICE login credentials
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h2><a id="ACL_server_config">Server configuration</a></h2>
 | 
					    <h2><a name="ACL_server_config">Server configuration</a></h2>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
The libvirt daemon allows the administrator to choose the authentication
 | 
					The libvirt daemon allows the administrator to choose the authentication
 | 
				
			||||||
mechanisms used for client connections on each network socket independently.
 | 
					mechanisms used for client connections on each network socket independently.
 | 
				
			||||||
@@ -153,7 +138,7 @@ currently a choice of <code>none</code>, <code>polkit</code>, and <code>sasl</co
 | 
				
			|||||||
The SASL scheme can be further configured to choose between a large
 | 
					The SASL scheme can be further configured to choose between a large
 | 
				
			||||||
number of different mechanisms.
 | 
					number of different mechanisms.
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
    <h2><a id="ACL_server_unix_perms">UNIX socket permissions/group</a></h2>
 | 
					    <h2><a name="ACL_server_unix_perms">UNIX socket permissions/group</a></h2>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
If libvirt does not contain support for PolicyKit, then access control for
 | 
					If libvirt does not contain support for PolicyKit, then access control for
 | 
				
			||||||
the UNIX domain socket is done using traditional file user/group ownership
 | 
					the UNIX domain socket is done using traditional file user/group ownership
 | 
				
			||||||
@@ -170,10 +155,10 @@ parameter. For example, setting the former to mode <code>0770</code> and the
 | 
				
			|||||||
latter <code>wheel</code> would let any user in the wheel group connect to
 | 
					latter <code>wheel</code> would let any user in the wheel group connect to
 | 
				
			||||||
the libvirt daemon.
 | 
					the libvirt daemon.
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
    <h2><a id="ACL_server_polkit">UNIX socket PolicyKit auth</a></h2>
 | 
					    <h2><a name="ACL_server_polkit">UNIX socket PolicyKit auth</a></h2>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
If libvirt contains support for PolicyKit, then access control options are
 | 
					If libvirt contains support for PolicyKit, then access control options are
 | 
				
			||||||
more advanced. The <code>auth_unix_rw</code> parameter will default to
 | 
					more advanced. The <code>unix_sock_auth</code> parameter will default to
 | 
				
			||||||
<code>polkit</code>, and the file permissions will default to <code>0777</code>
 | 
					<code>polkit</code>, and the file permissions will default to <code>0777</code>
 | 
				
			||||||
even on the RW socket. Upon connecting to the socket, the client application
 | 
					even on the RW socket. Upon connecting to the socket, the client application
 | 
				
			||||||
will be required to identify itself with PolicyKit. The default policy for the
 | 
					will be required to identify itself with PolicyKit. The default policy for the
 | 
				
			||||||
@@ -184,29 +169,15 @@ Default policy will still allow any application to connect to the RO socket.
 | 
				
			|||||||
</p>
 | 
					</p>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
The default policy can be overridden by creating a new policy file in the
 | 
					The default policy can be overridden by creating a new policy file in the
 | 
				
			||||||
<code>/etc/polkit-1/rules.d</code> directory. Information on the options
 | 
					 | 
				
			||||||
available can be found by reading the <code>polkit(8)</code> man page. The
 | 
					 | 
				
			||||||
two libvirt actions are named <code>org.libvirt.unix.manage</code> for full
 | 
					 | 
				
			||||||
management access, and <code>org.libvirt.unix.monitor</code> for read-only
 | 
					 | 
				
			||||||
access.
 | 
					 | 
				
			||||||
</p>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
As an example, creating <code>/etc/polkit-1/rules.d/80-libvirt-manage.rules</code>
 | 
					 | 
				
			||||||
with the following gives the user <code>fred</code> full management access
 | 
					 | 
				
			||||||
when accessing from an active local session:
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
<pre>polkit.addRule(function(action, subject) {
 | 
					 | 
				
			||||||
  if (action.id == "org.libvirt.unix.manage" &&
 | 
					 | 
				
			||||||
      subject.local && subject.active && subject.user == "fred") {
 | 
					 | 
				
			||||||
      return polkit.Result.YES;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});</pre>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
Older versions of PolicyKit used policy files ending with .pkla in the
 | 
					 | 
				
			||||||
local override directory <code>/etc/polkit-1/localauthority/50-local.d/</code>.
 | 
					local override directory <code>/etc/polkit-1/localauthority/50-local.d/</code>.
 | 
				
			||||||
Compatibility with this older format is provided by <a
 | 
					Policy files should have a unique name ending with .pkla.  Using reverse DNS
 | 
				
			||||||
href="https://pagure.io/polkit-pkla-compat">polkit-pkla-compat</a>. As an
 | 
					naming works well. Information on the options available can be found by
 | 
				
			||||||
example, this gives the user <code>fred</code> full management access:
 | 
					reading the pklocalauthority man page. The two libvirt daemon actions
 | 
				
			||||||
 | 
					available are named <code>org.libvirt.unix.manage</code> for full management
 | 
				
			||||||
 | 
					access, and <code>org.libvirt.unix.monitor</code> for read-only access.
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					As an example, this gives the user <code>fred</code> full management access:
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
<pre>[Allow fred libvirt management permissions]
 | 
					<pre>[Allow fred libvirt management permissions]
 | 
				
			||||||
Identity=unix-user:fred
 | 
					Identity=unix-user:fred
 | 
				
			||||||
@@ -214,72 +185,20 @@ Action=org.libvirt.unix.manage
 | 
				
			|||||||
ResultAny=yes
 | 
					ResultAny=yes
 | 
				
			||||||
ResultInactive=yes
 | 
					ResultInactive=yes
 | 
				
			||||||
ResultActive=yes</pre>
 | 
					ResultActive=yes</pre>
 | 
				
			||||||
    <h2><a id="ACL_server_sasl">SASL pluggable authentication</a></h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
Libvirt integrates with the cyrus-sasl library to provide a pluggable authentication
 | 
					Further examples of PolicyKit setup can be found on the
 | 
				
			||||||
system using the SASL protocol. SASL can be used in combination with libvirtd's TLS
 | 
					<a href="http://wiki.libvirt.org/page/SSHPolicyKitSetup">wiki page</a>.
 | 
				
			||||||
or TCP socket listeners. When used with the TCP listener, the SASL mechanism is
 | 
					 | 
				
			||||||
rqeuired to provide session encryption in addition to authentication. Only a very
 | 
					 | 
				
			||||||
few SASL mechanisms are able to do this, and of those that can do it, only the
 | 
					 | 
				
			||||||
GSSAPI plugin is considered acceptably secure by modern standards:
 | 
					 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
 | 
					    <h2><a name="ACL_server_username">Username/password auth</a></h2>
 | 
				
			||||||
    <dl>
 | 
					 | 
				
			||||||
      <dt>GSSAPI</dt>
 | 
					 | 
				
			||||||
      <dd><strong>This is the current default mechanism to use with libvirtd</strong>.
 | 
					 | 
				
			||||||
        It uses the Kerberos v5 authentication protocol underneath, and assuming
 | 
					 | 
				
			||||||
        the Kerberos client/server are configured with modern ciphers (AES),
 | 
					 | 
				
			||||||
        it provides strong session encryption capabilities.</dd>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt>DIGEST-MD5</dt>
 | 
					 | 
				
			||||||
      <dd>This was previously set as the default mechanism to use with libvirtd.
 | 
					 | 
				
			||||||
        It provides a simple username/password based authentication mechanism
 | 
					 | 
				
			||||||
        that includes session encryption.
 | 
					 | 
				
			||||||
        <a href="https://tools.ietf.org/html/rfc6331">RFC 6331</a>, however,
 | 
					 | 
				
			||||||
        documents a number of serious security flaws with DIGEST-MD5 and as a
 | 
					 | 
				
			||||||
        result marks it as <code>OBSOLETE</code>. Specific concerns are that
 | 
					 | 
				
			||||||
        it is vulnerable to MITM attacks and the MD5 hash can be brute-forced
 | 
					 | 
				
			||||||
        to reveal the password. A replacement is provided via the SCRAM mechanism,
 | 
					 | 
				
			||||||
        however, note that this does not provide encryption, so the SCRAM
 | 
					 | 
				
			||||||
        mechanism can only be used on the libvirtd TLS listener.
 | 
					 | 
				
			||||||
      </dd>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt>PASSDSS-3DES-1</dt>
 | 
					 | 
				
			||||||
      <dd>This provides a simple username/password based authentication
 | 
					 | 
				
			||||||
        mechanism that includes session encryption. The current cyrus-sasl
 | 
					 | 
				
			||||||
        implementation does not provide a way to validate the server's
 | 
					 | 
				
			||||||
        public key identity, thus it is susceptible to a MITM attacker
 | 
					 | 
				
			||||||
        impersonating the server. It is also not enabled in many OS
 | 
					 | 
				
			||||||
        distros when building SASL libraries.</dd>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <dt>KERBEROS_V4</dt>
 | 
					 | 
				
			||||||
      <dd>This uses the obsolete Kerberos v4 protocol to provide both authentication
 | 
					 | 
				
			||||||
        and session encryption. Kerberos v4 protocol has been obsolete since the
 | 
					 | 
				
			||||||
        early 1990's and has known security vulnerabilities so this will never be
 | 
					 | 
				
			||||||
        used in practice.</dd>
 | 
					 | 
				
			||||||
    </dl>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      Other SASL mechanisms, not listed above, can only be used when the libvirtd
 | 
					The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
 | 
				
			||||||
      TLS or UNIX socket listeners.
 | 
					The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
 | 
				
			||||||
    </p>
 | 
					username+password style authentication. It also provides for encryption of the data
 | 
				
			||||||
 | 
					stream, so the security of the plain TCP socket is on a par with that of the TLS
 | 
				
			||||||
    <h3><a id="ACL_server_username">Username/password auth</a></h3>
 | 
					socket. If desired the UNIX socket and TLS socket can also have SASL enabled by
 | 
				
			||||||
    <p>
 | 
					setting the <code>auth_unix_ro</code>, <code>auth_unix_rw</code>, <code>auth_tls</code>
 | 
				
			||||||
As noted above, the DIGEST-MD5 mechanism is considered obsolete and should
 | 
					config params in <code>libvirt.conf</code>.
 | 
				
			||||||
not be used anymore. To provide a simple username/password auth scheme on
 | 
					</p>
 | 
				
			||||||
the libvirt UNIX socket or TLS listeners, however, it is possible to use
 | 
					 | 
				
			||||||
the SCRAM mechanism. The <code>auth_unix_ro</code>, <code>auth_unix_rw</code>,
 | 
					 | 
				
			||||||
<code>auth_tls</code> config params in <code>libvirt.conf</code> can be used
 | 
					 | 
				
			||||||
to turn on SASL auth in these listeners.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
Since the libvirt SASL config file defaults to using GSSAPI (Kerberos), a
 | 
					 | 
				
			||||||
config change is rquired to enable plain password auth. This is done by
 | 
					 | 
				
			||||||
editting <code>/etc/sasl2/libvirt.conf</code> to set the <code>mech_list</code>
 | 
					 | 
				
			||||||
parameter to <code>scram-sha-1</code>.
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
Out of the box, no user accounts are defined, so no clients will be able to authenticate
 | 
					Out of the box, no user accounts are defined, so no clients will be able to authenticate
 | 
				
			||||||
on the TCP socket. Adding users and setting their passwords is done with the <code>saslpasswd2</code>
 | 
					on the TCP socket. Adding users and setting their passwords is done with the <code>saslpasswd2</code>
 | 
				
			||||||
@@ -307,13 +226,17 @@ again:
 | 
				
			|||||||
    <pre>
 | 
					    <pre>
 | 
				
			||||||
# saslpasswd2 -a libvirt -d fred
 | 
					# saslpasswd2 -a libvirt -d fred
 | 
				
			||||||
</pre>
 | 
					</pre>
 | 
				
			||||||
    <h3><a id="ACL_server_kerberos">GSSAPI/Kerberos auth</a></h3>
 | 
					    <h2><a name="ACL_server_kerberos">Kerberos auth</a></h2>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
The plain TCP listener of the libvirt daemon defaults to using SASL for authentication.
 | 
					The plain TCP socket of the libvirt daemon defaults to using SASL for authentication.
 | 
				
			||||||
The libvirt SASL config also defaults to GSSAPI, so there is no need to edit the
 | 
					The SASL mechanism configured by default is DIGEST-MD5, which provides a basic
 | 
				
			||||||
SASL config when using GSSAPI. If the libvirtd TLS or UNIX listeners are used,
 | 
					username+password style authentication. To enable Kerberos single-sign-on instead,
 | 
				
			||||||
then the Kerberos session encryption will be disabled since it is not required
 | 
					the libvirt SASL configuration file must be changed. This is <code>/etc/sasl2/libvirt.conf</code>.
 | 
				
			||||||
in these scenarios - only the plain TCP listener needs encryption
 | 
					The <code>mech_list</code> parameter must first be changed to <code>gssapi</code>
 | 
				
			||||||
 | 
					instead of the default <code>digest-md5</code>, and keytab should be set to
 | 
				
			||||||
 | 
					<code>/etc/libvirt/krb5.tab</code> . If SASL is enabled on the UNIX
 | 
				
			||||||
 | 
					and/or TLS sockets, Kerberos will also be used for them. Like DIGEST-MD5, the Kerberos
 | 
				
			||||||
 | 
					mechanism provides data encryption of the session.
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
Some operating systems do not install the SASL kerberos plugin by default. It
 | 
					Some operating systems do not install the SASL kerberos plugin by default. It
 | 
				
			||||||
@@ -330,15 +253,13 @@ Plugin "gssapiv2" [loaded],     API version: 4
 | 
				
			|||||||
        features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN
 | 
					        features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN
 | 
				
			||||||
</pre>
 | 
					</pre>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
Next it is necessary for the administrator of the Kerberos realm to
 | 
					Next it is necessary for the administrator of the Kerberos realm to issue a principle
 | 
				
			||||||
issue a principal for the libvirt server. There needs to be one
 | 
					for the libvirt server. There needs to be one principle per host running the libvirt
 | 
				
			||||||
principal per host running the libvirt daemon. The principal should be
 | 
					daemon. The principle should be named <code>libvirt/full.hostname@KERBEROS.REALM</code>.
 | 
				
			||||||
named <code>libvirt/full.hostname@KERBEROS.REALM</code>.  This is
 | 
					This is typically done by running the <code>kadmin.local</code> command on the Kerberos
 | 
				
			||||||
typically done by running the <code>kadmin.local</code> command on the
 | 
					server, though some Kerberos servers have alternate ways of setting up service principles.
 | 
				
			||||||
Kerberos server, though some Kerberos servers have alternate ways of
 | 
					Once created, the principle should be exported to a keytab, copied to the host running
 | 
				
			||||||
setting up service principals.  Once created, the principal should be
 | 
					the libvirt daemon and placed in <code>/etc/libvirt/krb5.tab</code>
 | 
				
			||||||
exported to a keytab, copied to the host running the libvirt daemon
 | 
					 | 
				
			||||||
and placed in <code>/etc/libvirt/krb5.tab</code>
 | 
					 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
    <pre>
 | 
					    <pre>
 | 
				
			||||||
# kadmin.local
 | 
					# kadmin.local
 | 
				
			||||||
@@ -360,7 +281,7 @@ kadmin.local: quit
 | 
				
			|||||||
</pre>
 | 
					</pre>
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
Any client application wishing to connect to a Kerberos enabled libvirt server
 | 
					Any client application wishing to connect to a Kerberos enabled libvirt server
 | 
				
			||||||
merely needs to run <code>kinit</code> to gain a user principal. This may well
 | 
					merely needs to run <code>kinit</code> to gain a user principle. This may well
 | 
				
			||||||
be done automatically when a user logs into a desktop session, if PAM is setup
 | 
					be done automatically when a user logs into a desktop session, if PAM is setup
 | 
				
			||||||
to authenticate against Kerberos.
 | 
					to authenticate against Kerberos.
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,7 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<!DOCTYPE html>
 | 
					<html>
 | 
				
			||||||
<html xmlns="http://www.w3.org/1999/xhtml">
 | 
					 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <h1 >Bindings for other languages and integration API modules</h1>
 | 
					    <h1 >Bindings for other languages</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>
 | 
					    <p>
 | 
				
			||||||
      Libvirt supports C and C++ directly, and has bindings available
 | 
					      Libvirt supports C and C++ directly, and has bindings available
 | 
				
			||||||
@@ -14,17 +13,13 @@
 | 
				
			|||||||
        <strong>C#</strong>: Arnaud Champion develops
 | 
					        <strong>C#</strong>: Arnaud Champion develops
 | 
				
			||||||
        <a href="csharp.html">C# bindings</a>.
 | 
					        <a href="csharp.html">C# bindings</a>.
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
     <li>
 | 
					 | 
				
			||||||
        <strong>Go</strong>: Daniel Berrange develops
 | 
					 | 
				
			||||||
        <a href="https://godoc.org/github.com/libvirt/libvirt-go">Go bindings</a>.
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <strong>Java</strong>: Daniel Veillard develops
 | 
					        <strong>Java</strong>: Daniel Veillard develops
 | 
				
			||||||
        <a href="java.html">Java bindings</a>.
 | 
					        <a href="java.html">Java bindings</a>.
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <strong>OCaml</strong>: Richard Jones develops
 | 
					        <strong>OCaml</strong>: Richard Jones develops
 | 
				
			||||||
        <a href="https://libvirt.org/ocaml/">OCaml bindings</a>.
 | 
					        <a href="http://libvirt.org/ocaml/">OCaml bindings</a>.
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <strong>Perl</strong>: Daniel Berrange develops
 | 
					        <strong>Perl</strong>: Daniel Berrange develops
 | 
				
			||||||
@@ -33,7 +28,7 @@
 | 
				
			|||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <p>
 | 
					        <p>
 | 
				
			||||||
          <strong>PHP</strong>: Radek Hladik started developing
 | 
					          <strong>PHP</strong>: Radek Hladik started developing
 | 
				
			||||||
          <a href="https://libvirt.org/php">PHP bindings</a> in 2010.
 | 
					          <a href="http://libvirt.org/php">PHP bindings</a> in 2010.
 | 
				
			||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
        <p>
 | 
					        <p>
 | 
				
			||||||
          In February 2011 the binding development has been moved to the libvirt.org website as
 | 
					          In February 2011 the binding development has been moved to the libvirt.org website as
 | 
				
			||||||
@@ -43,15 +38,13 @@
 | 
				
			|||||||
          The project is now maintained by Michal Novotny and it's heavily based
 | 
					          The project is now maintained by Michal Novotny and it's heavily based
 | 
				
			||||||
          on Radek's version. For more information, including
 | 
					          on Radek's version. For more information, including
 | 
				
			||||||
          information on posting patches to libvirt-php, please refer
 | 
					          information on posting patches to libvirt-php, please refer
 | 
				
			||||||
          to the <a href="https://libvirt.org/php">PHP bindings</a> site.
 | 
					          to the <a href="http://libvirt.org/php">PHP bindings</a> site.
 | 
				
			||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <p>
 | 
					        <p>
 | 
				
			||||||
          <strong>Python</strong>: Libvirt's python bindings are split to a
 | 
					          <strong>Python</strong>: Libvirt comes with direct support for
 | 
				
			||||||
          separate <a href="https://libvirt.org/git/?p=libvirt-python.git">package</a>
 | 
					          the Python language.
 | 
				
			||||||
          since version 1.2.0, older versions came with direct support for the
 | 
					 | 
				
			||||||
          Python language.
 | 
					 | 
				
			||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
        <p>
 | 
					        <p>
 | 
				
			||||||
          If your libvirt is installed as packages, rather than compiled
 | 
					          If your libvirt is installed as packages, rather than compiled
 | 
				
			||||||
@@ -70,18 +63,7 @@
 | 
				
			|||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <strong>Ruby</strong>: Chris Lalancette develops
 | 
					        <strong>Ruby</strong>: Chris Lalancette develops
 | 
				
			||||||
        <a href="https://libvirt.org/ruby/">Ruby bindings</a>.
 | 
					        <a href="http://libvirt.org/ruby/">Ruby bindings</a>.
 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>
 | 
					 | 
				
			||||||
      Integration API modules:
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <strong>D-Bus</strong>: Pavel Hrdina develops
 | 
					 | 
				
			||||||
        <a href="dbus.html">D-Bus API</a>.
 | 
					 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user