mirror of
				git://sourceware.org/git/lvm2.git
				synced 2025-11-04 12:23:49 +03:00 
			
		
		
		
	Compare commits
	
		
			2368 Commits
		
	
	
		
			dev-mornfa
			...
			v1_02_22
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4d418dee0e | ||
| 
						 | 
					06fe319347 | ||
| 
						 | 
					9dd7e3fb24 | ||
| 
						 | 
					d5a46396b0 | ||
| 
						 | 
					5e84cb560d | ||
| 
						 | 
					756c6f8560 | ||
| 
						 | 
					6fa6ce35da | ||
| 
						 | 
					b14b97599d | ||
| 
						 | 
					db6f60d6fc | ||
| 
						 | 
					25c348d7c8 | ||
| 
						 | 
					2e4bf8b034 | ||
| 
						 | 
					c1490e2f7b | ||
| 
						 | 
					b004fe9556 | ||
| 
						 | 
					67142ad046 | ||
| 
						 | 
					3c3ec06b12 | ||
| 
						 | 
					5b5caa8a16 | ||
| 
						 | 
					b2cba098bb | ||
| 
						 | 
					1ec0d47f10 | ||
| 
						 | 
					f232606ec7 | ||
| 
						 | 
					fa28cea152 | ||
| 
						 | 
					c8da1647a1 | ||
| 
						 | 
					505a0a8718 | ||
| 
						 | 
					10d3496a17 | ||
| 
						 | 
					a13c755370 | ||
| 
						 | 
					62f9996fd7 | ||
| 
						 | 
					edbcd8a1b2 | ||
| 
						 | 
					a5308d1689 | ||
| 
						 | 
					cbfe6e8fcc | ||
| 
						 | 
					5571ff35d8 | ||
| 
						 | 
					2a4819f3c8 | ||
| 
						 | 
					7121866b13 | ||
| 
						 | 
					d6e05ad9e2 | ||
| 
						 | 
					993e30a7de | ||
| 
						 | 
					49cae61254 | ||
| 
						 | 
					1ea4b2ea91 | ||
| 
						 | 
					bc1d6e1f90 | ||
| 
						 | 
					9ec6e68d0c | ||
| 
						 | 
					341bdc93e2 | ||
| 
						 | 
					6fb3e1aa15 | ||
| 
						 | 
					f1f92eb2e2 | ||
| 
						 | 
					8c2369d40f | ||
| 
						 | 
					a6d9fc58eb | ||
| 
						 | 
					f7cd471548 | ||
| 
						 | 
					5f951faf32 | ||
| 
						 | 
					b228dfaf2c | ||
| 
						 | 
					764858fa12 | ||
| 
						 | 
					5ee976d276 | ||
| 
						 | 
					8b28b6f2d3 | ||
| 
						 | 
					fe16df2e6f | ||
| 
						 | 
					779047f8c9 | ||
| 
						 | 
					094e9fb45d | ||
| 
						 | 
					1458bd0e74 | ||
| 
						 | 
					d2cb05988d | ||
| 
						 | 
					6e056767b4 | ||
| 
						 | 
					a10afb1b98 | ||
| 
						 | 
					bb6d3b6cfd | ||
| 
						 | 
					c75d4af4bc | ||
| 
						 | 
					972dc39d00 | ||
| 
						 | 
					9daac5c178 | ||
| 
						 | 
					dd2a3f40e1 | ||
| 
						 | 
					78f76c1690 | ||
| 
						 | 
					4788066a5f | ||
| 
						 | 
					10e4254e7d | ||
| 
						 | 
					0106e4df9d | ||
| 
						 | 
					8ac718a3a2 | ||
| 
						 | 
					46d45273a1 | ||
| 
						 | 
					8da9ec3599 | ||
| 
						 | 
					01fdf84d69 | ||
| 
						 | 
					cc78386e75 | ||
| 
						 | 
					3755157c61 | ||
| 
						 | 
					80f8436f0a | ||
| 
						 | 
					f88a4b7760 | ||
| 
						 | 
					de229b8ab0 | ||
| 
						 | 
					a3ba37e45e | ||
| 
						 | 
					50c779b3c6 | ||
| 
						 | 
					192372e1c3 | ||
| 
						 | 
					f88fd88c38 | ||
| 
						 | 
					6e15145af1 | ||
| 
						 | 
					4b5fad4e48 | ||
| 
						 | 
					7a13e71c80 | ||
| 
						 | 
					3c10943900 | ||
| 
						 | 
					696b8811c2 | ||
| 
						 | 
					9fd2c8602a | ||
| 
						 | 
					a3636a5af4 | ||
| 
						 | 
					f2e5f07718 | ||
| 
						 | 
					16c6fdde60 | ||
| 
						 | 
					2155c93426 | ||
| 
						 | 
					c394631e4c | ||
| 
						 | 
					8b370b7cc1 | ||
| 
						 | 
					607db9971c | ||
| 
						 | 
					6768f64e2f | ||
| 
						 | 
					f1813b1cc6 | ||
| 
						 | 
					fb665bd0dd | ||
| 
						 | 
					65dda2ef3d | ||
| 
						 | 
					b162b992af | ||
| 
						 | 
					67a3a3d130 | ||
| 
						 | 
					92cd9bf7d2 | ||
| 
						 | 
					bf97034485 | ||
| 
						 | 
					1ded1fc509 | ||
| 
						 | 
					e0592c58b3 | ||
| 
						 | 
					5ead2706b4 | ||
| 
						 | 
					52ada4853c | ||
| 
						 | 
					c2b27a8298 | ||
| 
						 | 
					3934c1d437 | ||
| 
						 | 
					e366b68ad3 | ||
| 
						 | 
					fb94fb980a | ||
| 
						 | 
					b10cc18f53 | ||
| 
						 | 
					a249de3b72 | ||
| 
						 | 
					d04e972d65 | ||
| 
						 | 
					b9f5a18a76 | ||
| 
						 | 
					d3f157f08a | ||
| 
						 | 
					2294fdb496 | ||
| 
						 | 
					d7ba0e01a5 | ||
| 
						 | 
					b6172b53fd | ||
| 
						 | 
					477ec611d5 | ||
| 
						 | 
					b6194edd67 | ||
| 
						 | 
					dcdbbb3ecb | ||
| 
						 | 
					7ef99ee4e6 | ||
| 
						 | 
					1ac1418286 | ||
| 
						 | 
					8fc854f38e | ||
| 
						 | 
					1c2360b335 | ||
| 
						 | 
					dd4477406b | ||
| 
						 | 
					9d67bbb104 | ||
| 
						 | 
					d6c8e1df61 | ||
| 
						 | 
					5ec7c8fece | ||
| 
						 | 
					86b21eaf83 | ||
| 
						 | 
					228486a971 | ||
| 
						 | 
					88c0caab26 | ||
| 
						 | 
					5cd4679419 | ||
| 
						 | 
					eeed5e0d19 | ||
| 
						 | 
					369ab1e0b2 | ||
| 
						 | 
					2e21519a10 | ||
| 
						 | 
					ecc001ed08 | ||
| 
						 | 
					cd96852696 | ||
| 
						 | 
					b9f7f30158 | ||
| 
						 | 
					ca5e423331 | ||
| 
						 | 
					fa9407089c | ||
| 
						 | 
					66f28e193a | ||
| 
						 | 
					0d93f89f5c | ||
| 
						 | 
					154e9a2c47 | ||
| 
						 | 
					84574a1257 | ||
| 
						 | 
					bf83527b64 | ||
| 
						 | 
					12c53622a0 | ||
| 
						 | 
					d8f54cf891 | ||
| 
						 | 
					625a671189 | ||
| 
						 | 
					6ebdad3102 | ||
| 
						 | 
					9a8f21aa03 | ||
| 
						 | 
					291dd8edc2 | ||
| 
						 | 
					de4c1daf29 | ||
| 
						 | 
					0b55d7d0d8 | ||
| 
						 | 
					5d86fd8fdb | ||
| 
						 | 
					1b76eb1f59 | ||
| 
						 | 
					b05678d8bf | ||
| 
						 | 
					781f4971c6 | ||
| 
						 | 
					d02ac7b99a | ||
| 
						 | 
					b1b6c97f7c | ||
| 
						 | 
					baee28ab5c | ||
| 
						 | 
					83edf68ff9 | ||
| 
						 | 
					c7588f91dd | ||
| 
						 | 
					30b432adc5 | ||
| 
						 | 
					7c9733eb5d | ||
| 
						 | 
					a223c3fea3 | ||
| 
						 | 
					d5250f4901 | ||
| 
						 | 
					25f29f4712 | ||
| 
						 | 
					382af5563d | ||
| 
						 | 
					8cf3d165d3 | ||
| 
						 | 
					0fd6ce546f | ||
| 
						 | 
					b881c372bc | ||
| 
						 | 
					94c5e7deb0 | ||
| 
						 | 
					c344766f3c | ||
| 
						 | 
					67895de0bc | ||
| 
						 | 
					ff00cb6990 | ||
| 
						 | 
					2cc75c11ed | ||
| 
						 | 
					cd79e58eda | ||
| 
						 | 
					6fa801f3d8 | ||
| 
						 | 
					684eecba1d | ||
| 
						 | 
					da9cf7e5de | ||
| 
						 | 
					f57e7445fd | ||
| 
						 | 
					fba1388719 | ||
| 
						 | 
					80ed029c17 | ||
| 
						 | 
					34a74e81e3 | ||
| 
						 | 
					cb120ddb15 | ||
| 
						 | 
					f9ee4395b0 | ||
| 
						 | 
					71f06d51ed | ||
| 
						 | 
					217f70952f | ||
| 
						 | 
					f813d41a76 | ||
| 
						 | 
					d851289d8a | ||
| 
						 | 
					b115b8a2ea | ||
| 
						 | 
					d0f7067471 | ||
| 
						 | 
					be5b4c38a7 | ||
| 
						 | 
					d6d597e3dd | ||
| 
						 | 
					84e348fade | ||
| 
						 | 
					910054657e | ||
| 
						 | 
					8357a11249 | ||
| 
						 | 
					9b021ba057 | ||
| 
						 | 
					317e588efd | ||
| 
						 | 
					b1d32a03c7 | ||
| 
						 | 
					ee6e6529ee | ||
| 
						 | 
					9d944d6cf9 | ||
| 
						 | 
					13635d281a | ||
| 
						 | 
					2493c46970 | ||
| 
						 | 
					63e4217271 | ||
| 
						 | 
					f4bd12e8e9 | ||
| 
						 | 
					df15f46900 | ||
| 
						 | 
					fb3a732361 | ||
| 
						 | 
					2d74110feb | ||
| 
						 | 
					19d102082d | ||
| 
						 | 
					d2af2c9487 | ||
| 
						 | 
					82980149fa | ||
| 
						 | 
					a19bb7b909 | ||
| 
						 | 
					9d98c3278d | ||
| 
						 | 
					26376ac1c9 | ||
| 
						 | 
					8459f99341 | ||
| 
						 | 
					e5bdb0e0b5 | ||
| 
						 | 
					1106b7775a | ||
| 
						 | 
					ae2852156d | ||
| 
						 | 
					44c6c36c43 | ||
| 
						 | 
					a81926503d | ||
| 
						 | 
					af13ccddda | ||
| 
						 | 
					392e1bc2e8 | ||
| 
						 | 
					9268d92c70 | ||
| 
						 | 
					bb3366c07d | ||
| 
						 | 
					d24d563ebc | ||
| 
						 | 
					954bd9257b | ||
| 
						 | 
					5d51a56c02 | ||
| 
						 | 
					f48648552e | ||
| 
						 | 
					edb9c3cc9f | ||
| 
						 | 
					01dc83b936 | ||
| 
						 | 
					3a8dff3a62 | ||
| 
						 | 
					13b234ccba | ||
| 
						 | 
					e451e93664 | ||
| 
						 | 
					b4f9531475 | ||
| 
						 | 
					3184ff75c4 | ||
| 
						 | 
					43243f4d30 | ||
| 
						 | 
					c975a100b1 | ||
| 
						 | 
					02bf389425 | ||
| 
						 | 
					bcb9a3dd04 | ||
| 
						 | 
					cce3baa275 | ||
| 
						 | 
					2b48fad426 | ||
| 
						 | 
					d554b2bc94 | ||
| 
						 | 
					f66943de43 | ||
| 
						 | 
					9d1e9bc2fb | ||
| 
						 | 
					2d6a014920 | ||
| 
						 | 
					c1952bf257 | ||
| 
						 | 
					a10227eb03 | ||
| 
						 | 
					475ae29b85 | ||
| 
						 | 
					0b9cfc278b | ||
| 
						 | 
					b57b6b4fba | ||
| 
						 | 
					7d948f7bc5 | ||
| 
						 | 
					459023d171 | ||
| 
						 | 
					fd6570720a | ||
| 
						 | 
					7831665417 | ||
| 
						 | 
					7c9920d982 | ||
| 
						 | 
					cbdccf0a9c | ||
| 
						 | 
					64fa83ec3f | ||
| 
						 | 
					faff865cfd | ||
| 
						 | 
					742ab55a9a | ||
| 
						 | 
					66e623fb2a | ||
| 
						 | 
					4ab17ee965 | ||
| 
						 | 
					7f48ca5132 | ||
| 
						 | 
					da983848b4 | ||
| 
						 | 
					bc03f7bad3 | ||
| 
						 | 
					a1c8bd3846 | ||
| 
						 | 
					404bc284e0 | ||
| 
						 | 
					9dee30ff0e | ||
| 
						 | 
					f91aadbea8 | ||
| 
						 | 
					aa15a10c91 | ||
| 
						 | 
					5b03e36351 | ||
| 
						 | 
					b9ba9ffad2 | ||
| 
						 | 
					642be5d16c | ||
| 
						 | 
					ee68d715bf | ||
| 
						 | 
					224084f056 | ||
| 
						 | 
					1cd8c849b8 | ||
| 
						 | 
					169f68bfcd | ||
| 
						 | 
					d2b7cfa2d1 | ||
| 
						 | 
					a40c7dff5d | ||
| 
						 | 
					e8e00630d3 | ||
| 
						 | 
					e33720c854 | ||
| 
						 | 
					bd8a4e0d17 | ||
| 
						 | 
					586a2aef76 | ||
| 
						 | 
					ce1d8f6754 | ||
| 
						 | 
					7b0f401065 | ||
| 
						 | 
					8387016eef | ||
| 
						 | 
					4e1342b641 | ||
| 
						 | 
					e45a184d90 | ||
| 
						 | 
					979e1012d2 | ||
| 
						 | 
					fe10a50e23 | ||
| 
						 | 
					8ab6d72519 | ||
| 
						 | 
					3aada6dd1d | ||
| 
						 | 
					0933036366 | ||
| 
						 | 
					05f5abdc06 | ||
| 
						 | 
					fb875e0709 | ||
| 
						 | 
					9acdc2f6bf | ||
| 
						 | 
					028ce4bff6 | ||
| 
						 | 
					3f245ad6db | ||
| 
						 | 
					23115f4116 | ||
| 
						 | 
					cf5f48e6cc | ||
| 
						 | 
					997fa756ad | ||
| 
						 | 
					e23f75b1cc | ||
| 
						 | 
					6531e88761 | ||
| 
						 | 
					e76a9c2618 | ||
| 
						 | 
					45be8a836b | ||
| 
						 | 
					954b6032e7 | ||
| 
						 | 
					bd95416f27 | ||
| 
						 | 
					df2577ace2 | ||
| 
						 | 
					720e6558c9 | ||
| 
						 | 
					c239f15d8a | ||
| 
						 | 
					dfa1f80a57 | ||
| 
						 | 
					15dfb93b17 | ||
| 
						 | 
					0ec8488c2b | ||
| 
						 | 
					94b2e29cb1 | ||
| 
						 | 
					fefa8e9b4d | ||
| 
						 | 
					32c4c44812 | ||
| 
						 | 
					05195e2b1d | ||
| 
						 | 
					4c2ff675b8 | ||
| 
						 | 
					e5692a4721 | ||
| 
						 | 
					312e6a0d31 | ||
| 
						 | 
					5bb8efa41f | ||
| 
						 | 
					949a835f4a | ||
| 
						 | 
					85e6042941 | ||
| 
						 | 
					3cd2f28975 | ||
| 
						 | 
					2179a72c3a | ||
| 
						 | 
					a5f282f156 | ||
| 
						 | 
					40e8631f63 | ||
| 
						 | 
					9ded05bb97 | ||
| 
						 | 
					ec8efa35a1 | ||
| 
						 | 
					f72bf20482 | ||
| 
						 | 
					ebde2002e8 | ||
| 
						 | 
					352a66f46f | ||
| 
						 | 
					d84c5391f7 | ||
| 
						 | 
					f4c582472b | ||
| 
						 | 
					1485586f7e | ||
| 
						 | 
					d5c9024335 | ||
| 
						 | 
					860cf80703 | ||
| 
						 | 
					897ff3161f | ||
| 
						 | 
					b356b2e501 | ||
| 
						 | 
					1d2733c893 | ||
| 
						 | 
					32d9126094 | ||
| 
						 | 
					db43314e50 | ||
| 
						 | 
					68d2baeb65 | ||
| 
						 | 
					1fd5f562d3 | ||
| 
						 | 
					48e02f2086 | ||
| 
						 | 
					eab7b2b581 | ||
| 
						 | 
					45abade7fc | ||
| 
						 | 
					5372fc4b43 | ||
| 
						 | 
					4e2f240c98 | ||
| 
						 | 
					bb3605518d | ||
| 
						 | 
					3ef6d37f27 | ||
| 
						 | 
					88e9f2f7f4 | ||
| 
						 | 
					704a447df9 | ||
| 
						 | 
					a5fcb26a33 | ||
| 
						 | 
					2491a61481 | ||
| 
						 | 
					91831d51ed | ||
| 
						 | 
					174f0c19f7 | ||
| 
						 | 
					de6fadfb4f | ||
| 
						 | 
					f946db3e00 | ||
| 
						 | 
					8d05e5bc31 | ||
| 
						 | 
					cfb46820e4 | ||
| 
						 | 
					081f1cbcc2 | ||
| 
						 | 
					7bc6da326f | ||
| 
						 | 
					cd95a0df7b | ||
| 
						 | 
					82fa497c16 | ||
| 
						 | 
					44fd345206 | ||
| 
						 | 
					088e1c9db4 | ||
| 
						 | 
					d4f16e666e | ||
| 
						 | 
					8233cfd371 | ||
| 
						 | 
					ff05e2e30d | ||
| 
						 | 
					a8ea7dd3fb | ||
| 
						 | 
					96f70a5303 | ||
| 
						 | 
					f1604c3e69 | ||
| 
						 | 
					c42c8c5192 | ||
| 
						 | 
					5facb53a41 | ||
| 
						 | 
					d039ce89af | ||
| 
						 | 
					bc7605103f | ||
| 
						 | 
					d305d655d4 | ||
| 
						 | 
					4ef1220b16 | ||
| 
						 | 
					a4fef143cd | ||
| 
						 | 
					74ecb724a9 | ||
| 
						 | 
					af235897ab | ||
| 
						 | 
					5ec4e458b5 | ||
| 
						 | 
					2dae63ce21 | ||
| 
						 | 
					be748fe33b | ||
| 
						 | 
					7408340b6a | ||
| 
						 | 
					29eb92446e | ||
| 
						 | 
					ae6918742e | ||
| 
						 | 
					863484bb65 | ||
| 
						 | 
					1cd7ebce4c | ||
| 
						 | 
					eef8c7862e | ||
| 
						 | 
					b52375d446 | ||
| 
						 | 
					6e2babc2ce | ||
| 
						 | 
					08e253bed1 | ||
| 
						 | 
					c6661477a2 | ||
| 
						 | 
					415cfd99a0 | ||
| 
						 | 
					8c2e37381a | ||
| 
						 | 
					45df79feba | ||
| 
						 | 
					5824f992b7 | ||
| 
						 | 
					b0b60fafd5 | ||
| 
						 | 
					8d98b02ba2 | ||
| 
						 | 
					a93fe79bc4 | ||
| 
						 | 
					4aebd7be37 | ||
| 
						 | 
					3170a5db32 | ||
| 
						 | 
					3605b9eef6 | ||
| 
						 | 
					a945f1fde2 | ||
| 
						 | 
					461a997b5b | ||
| 
						 | 
					a80afd7b4e | ||
| 
						 | 
					aad2b51d85 | ||
| 
						 | 
					36a9a81ff1 | ||
| 
						 | 
					42c88546ae | ||
| 
						 | 
					0f0e86ef9b | ||
| 
						 | 
					98efd9a857 | ||
| 
						 | 
					a0c27d95b7 | ||
| 
						 | 
					984651d99d | ||
| 
						 | 
					c6f7370b30 | ||
| 
						 | 
					3e4b8e8985 | ||
| 
						 | 
					73f08b98d2 | ||
| 
						 | 
					8607a74206 | ||
| 
						 | 
					8339f3ceb3 | ||
| 
						 | 
					c0c9f3cc19 | ||
| 
						 | 
					81f4813c29 | ||
| 
						 | 
					94f57745b9 | ||
| 
						 | 
					54fb2ebbe0 | ||
| 
						 | 
					02d122b65b | ||
| 
						 | 
					df0a5561a1 | ||
| 
						 | 
					f7c55da7d0 | ||
| 
						 | 
					b385f701ce | ||
| 
						 | 
					05dd42f443 | ||
| 
						 | 
					36d816d5cb | ||
| 
						 | 
					92a6746e70 | ||
| 
						 | 
					1728848a39 | ||
| 
						 | 
					f9eb4e7487 | ||
| 
						 | 
					d0b9f33aeb | ||
| 
						 | 
					718583b241 | ||
| 
						 | 
					6737127e9a | ||
| 
						 | 
					19a7b4479b | ||
| 
						 | 
					c340647502 | ||
| 
						 | 
					0f987d2982 | ||
| 
						 | 
					52bcaed169 | ||
| 
						 | 
					177bd565ac | ||
| 
						 | 
					c801c32fc5 | ||
| 
						 | 
					d090cf3058 | ||
| 
						 | 
					1e4b82cc94 | ||
| 
						 | 
					3426f31184 | ||
| 
						 | 
					b4fb7af1df | ||
| 
						 | 
					b36647598b | ||
| 
						 | 
					fd6b94f20e | ||
| 
						 | 
					296dc0ed8a | ||
| 
						 | 
					4f869e14d6 | ||
| 
						 | 
					5704270e9d | ||
| 
						 | 
					505b381e85 | ||
| 
						 | 
					da6cb15393 | ||
| 
						 | 
					16843f6cc8 | ||
| 
						 | 
					64f3ad1fd4 | ||
| 
						 | 
					ff4c4f99b3 | ||
| 
						 | 
					f5d2e09569 | ||
| 
						 | 
					f2bdbe0d4d | ||
| 
						 | 
					c51a13caa6 | ||
| 
						 | 
					7840c78a23 | ||
| 
						 | 
					c706f3246b | ||
| 
						 | 
					608eedf88d | ||
| 
						 | 
					a564ca82be | ||
| 
						 | 
					c868b1fee2 | ||
| 
						 | 
					22374f718f | ||
| 
						 | 
					abe3cfcf41 | ||
| 
						 | 
					59db4b50cd | ||
| 
						 | 
					bdae38765d | ||
| 
						 | 
					66d3ceeb61 | ||
| 
						 | 
					445dd17db3 | ||
| 
						 | 
					cff78a2577 | ||
| 
						 | 
					6a09e64195 | ||
| 
						 | 
					22eabe5eab | ||
| 
						 | 
					b69ba36c2d | ||
| 
						 | 
					5240aad22b | ||
| 
						 | 
					2897eb3cb3 | ||
| 
						 | 
					d3f2f00c25 | ||
| 
						 | 
					bacfb913a0 | ||
| 
						 | 
					c99d0236a0 | ||
| 
						 | 
					aac2b655f7 | ||
| 
						 | 
					126c41e73a | ||
| 
						 | 
					359ee54f0d | ||
| 
						 | 
					28ab560907 | ||
| 
						 | 
					ead252fee4 | ||
| 
						 | 
					abf67914c4 | ||
| 
						 | 
					127884e9dd | ||
| 
						 | 
					654f5049eb | ||
| 
						 | 
					979ca34259 | ||
| 
						 | 
					4dd1086805 | ||
| 
						 | 
					3503d4b72c | ||
| 
						 | 
					b8d32a0d33 | ||
| 
						 | 
					45dca55fc8 | ||
| 
						 | 
					445d8ecd9f | ||
| 
						 | 
					c980add503 | ||
| 
						 | 
					133842392a | ||
| 
						 | 
					8baf2ef155 | ||
| 
						 | 
					20b71340bc | ||
| 
						 | 
					61d8baf8b1 | ||
| 
						 | 
					56a9645aa5 | ||
| 
						 | 
					85877000a6 | ||
| 
						 | 
					2f7d2477b6 | ||
| 
						 | 
					21ea3f05f4 | ||
| 
						 | 
					79d3492e90 | ||
| 
						 | 
					5972777abe | ||
| 
						 | 
					8e373ff868 | ||
| 
						 | 
					a4db92da3a | ||
| 
						 | 
					9b777eb281 | ||
| 
						 | 
					bd3c652184 | ||
| 
						 | 
					800f747570 | ||
| 
						 | 
					2b8423437e | ||
| 
						 | 
					8b4b6945f8 | ||
| 
						 | 
					e5ecfec5c4 | ||
| 
						 | 
					f95dbff71f | ||
| 
						 | 
					098f6830a6 | ||
| 
						 | 
					d1ecebdb52 | ||
| 
						 | 
					590b654251 | ||
| 
						 | 
					3bf190c8ab | ||
| 
						 | 
					dcca7638e0 | ||
| 
						 | 
					70e45ad37b | ||
| 
						 | 
					db88210289 | ||
| 
						 | 
					d2e0d96cc3 | ||
| 
						 | 
					3feba82ccc | ||
| 
						 | 
					db924da231 | ||
| 
						 | 
					fc55ae7e6d | ||
| 
						 | 
					86e757a6ad | ||
| 
						 | 
					4790715cd3 | ||
| 
						 | 
					e7e9c60042 | ||
| 
						 | 
					1c3bc52cc4 | ||
| 
						 | 
					5227dff0e1 | ||
| 
						 | 
					33f0b5b7c2 | ||
| 
						 | 
					0a02968303 | ||
| 
						 | 
					f7bf658c07 | ||
| 
						 | 
					8d16a0abad | ||
| 
						 | 
					c974b97ca3 | ||
| 
						 | 
					b8025bfebd | ||
| 
						 | 
					30323b253f | ||
| 
						 | 
					535c3ede96 | ||
| 
						 | 
					89fed8ca33 | ||
| 
						 | 
					f43c77aaed | ||
| 
						 | 
					96c676b371 | ||
| 
						 | 
					113047e1a2 | ||
| 
						 | 
					abed57cb53 | ||
| 
						 | 
					c01a800a6b | ||
| 
						 | 
					d648832a2d | ||
| 
						 | 
					f06833fbd2 | ||
| 
						 | 
					c561addc94 | ||
| 
						 | 
					702f5f1f4c | ||
| 
						 | 
					1273f179e8 | ||
| 
						 | 
					5d02f60bde | ||
| 
						 | 
					4cf7a108e8 | ||
| 
						 | 
					42635c3938 | ||
| 
						 | 
					ed43dc842b | ||
| 
						 | 
					49d4db6cd2 | ||
| 
						 | 
					ea80ab2cae | ||
| 
						 | 
					382e808b8d | ||
| 
						 | 
					846befa7e0 | ||
| 
						 | 
					74dd29f843 | ||
| 
						 | 
					b0473bffcb | ||
| 
						 | 
					24dd9ab1a7 | ||
| 
						 | 
					49d3037e87 | ||
| 
						 | 
					37ad2bd4e8 | ||
| 
						 | 
					7d7b332b02 | ||
| 
						 | 
					ac033b8612 | ||
| 
						 | 
					a7b98dfe25 | ||
| 
						 | 
					7fb7c86c46 | ||
| 
						 | 
					ed036598a9 | ||
| 
						 | 
					160bb70cdf | ||
| 
						 | 
					c2e61f3c21 | ||
| 
						 | 
					18218467f3 | ||
| 
						 | 
					17e298ad2a | ||
| 
						 | 
					d031a374f9 | ||
| 
						 | 
					55f69c98cb | ||
| 
						 | 
					71f2e4306d | ||
| 
						 | 
					f8af23a025 | ||
| 
						 | 
					4ef55a6cd3 | ||
| 
						 | 
					312f866723 | ||
| 
						 | 
					0ebe1f6dec | ||
| 
						 | 
					2ad92e0e6e | ||
| 
						 | 
					ac8823cdcf | ||
| 
						 | 
					77565f7ee4 | ||
| 
						 | 
					d656d90fa8 | ||
| 
						 | 
					175b3b0834 | ||
| 
						 | 
					7477e6b714 | ||
| 
						 | 
					cd6568db69 | ||
| 
						 | 
					6aff325fb2 | ||
| 
						 | 
					0d603cfe9c | ||
| 
						 | 
					34a1f14a17 | ||
| 
						 | 
					efe1c8a070 | ||
| 
						 | 
					1575844344 | ||
| 
						 | 
					221ac1c208 | ||
| 
						 | 
					57442db759 | ||
| 
						 | 
					5fdb3e7cd6 | ||
| 
						 | 
					96f259726c | ||
| 
						 | 
					4936efba5e | ||
| 
						 | 
					d5a3559a2f | ||
| 
						 | 
					114a1c7f52 | ||
| 
						 | 
					ce5265c203 | ||
| 
						 | 
					1a575d926f | ||
| 
						 | 
					85c818a39e | ||
| 
						 | 
					4ffa2defe4 | ||
| 
						 | 
					8825157fbb | ||
| 
						 | 
					966d608dc5 | ||
| 
						 | 
					b808c89471 | ||
| 
						 | 
					75d4e6490f | ||
| 
						 | 
					a82775f544 | ||
| 
						 | 
					6a22ad0171 | ||
| 
						 | 
					c854e88186 | ||
| 
						 | 
					d02203060c | ||
| 
						 | 
					cf703b0433 | ||
| 
						 | 
					c0197a72d3 | ||
| 
						 | 
					e5a543e283 | ||
| 
						 | 
					b8b029b7d3 | ||
| 
						 | 
					370f368b1a | ||
| 
						 | 
					8288b45b4f | ||
| 
						 | 
					fe529faf8e | ||
| 
						 | 
					ab931b177d | ||
| 
						 | 
					9aa3465513 | ||
| 
						 | 
					6c70fc1a6c | ||
| 
						 | 
					1ccc39962a | ||
| 
						 | 
					99c941fc85 | ||
| 
						 | 
					19729fdcc2 | ||
| 
						 | 
					02e17998ce | ||
| 
						 | 
					459e00c67a | ||
| 
						 | 
					292f665650 | ||
| 
						 | 
					93bbb79569 | ||
| 
						 | 
					273e724f2b | ||
| 
						 | 
					5d2615c56f | ||
| 
						 | 
					bfaaf21330 | ||
| 
						 | 
					dcb8415b7a | ||
| 
						 | 
					699e1c75ce | ||
| 
						 | 
					465b6e613e | ||
| 
						 | 
					05fa105855 | ||
| 
						 | 
					d7a0cdebe5 | ||
| 
						 | 
					b049ab31eb | ||
| 
						 | 
					6db4dcff7a | ||
| 
						 | 
					3eeaef00ec | ||
| 
						 | 
					8bf4c38a00 | ||
| 
						 | 
					3a32b09ad1 | ||
| 
						 | 
					6315982752 | ||
| 
						 | 
					374a171e82 | ||
| 
						 | 
					fc5d801f91 | ||
| 
						 | 
					5146641848 | ||
| 
						 | 
					cdd0ac42cf | ||
| 
						 | 
					e5895500a2 | ||
| 
						 | 
					9cb4dde3fa | ||
| 
						 | 
					3c2a4370a5 | ||
| 
						 | 
					e7a360dd6f | ||
| 
						 | 
					c814c2fd35 | ||
| 
						 | 
					fefa7fe262 | ||
| 
						 | 
					26f01a29d1 | ||
| 
						 | 
					169d4090ab | ||
| 
						 | 
					0b43754d60 | ||
| 
						 | 
					8b3b26b813 | ||
| 
						 | 
					5426af4f81 | ||
| 
						 | 
					4e2c3a579d | ||
| 
						 | 
					5ae2693241 | ||
| 
						 | 
					41c86b0d19 | ||
| 
						 | 
					40788e8c3d | ||
| 
						 | 
					0d29120033 | ||
| 
						 | 
					4be598f865 | ||
| 
						 | 
					558a6d509e | ||
| 
						 | 
					75cd02aad2 | ||
| 
						 | 
					e4c4451482 | ||
| 
						 | 
					0671632477 | ||
| 
						 | 
					54c230c264 | ||
| 
						 | 
					64ba878eda | ||
| 
						 | 
					01acd6dd76 | ||
| 
						 | 
					9d819b52d3 | ||
| 
						 | 
					37bac5cdc9 | ||
| 
						 | 
					78c718c591 | ||
| 
						 | 
					284b8bf6ca | ||
| 
						 | 
					5a5084b837 | ||
| 
						 | 
					3b8058e1f1 | ||
| 
						 | 
					2a3168e0d6 | ||
| 
						 | 
					a8ac6e4a15 | ||
| 
						 | 
					6172cf9fba | ||
| 
						 | 
					b728ec3909 | ||
| 
						 | 
					61a53bbcff | ||
| 
						 | 
					17d13dd084 | ||
| 
						 | 
					edcb28d591 | ||
| 
						 | 
					ad101119a7 | ||
| 
						 | 
					bc36676d31 | ||
| 
						 | 
					d76fe120ab | ||
| 
						 | 
					2e95949b80 | ||
| 
						 | 
					ae14d85e24 | ||
| 
						 | 
					fad6304c60 | ||
| 
						 | 
					a4dd3c8ce9 | ||
| 
						 | 
					6d1a5d45e2 | ||
| 
						 | 
					a6c7043e03 | ||
| 
						 | 
					bcc400dafa | ||
| 
						 | 
					8fbedf3441 | ||
| 
						 | 
					2e8a9c9874 | ||
| 
						 | 
					44fc41b3e5 | ||
| 
						 | 
					7212c20a1b | ||
| 
						 | 
					7ff142de1c | ||
| 
						 | 
					e67efb199d | ||
| 
						 | 
					20128bd04b | ||
| 
						 | 
					c0fefdde28 | ||
| 
						 | 
					f6ee160e66 | ||
| 
						 | 
					06acc2004f | ||
| 
						 | 
					43ac2ce4c8 | ||
| 
						 | 
					b32bf72b5f | ||
| 
						 | 
					c6880c957e | ||
| 
						 | 
					095b71ed96 | ||
| 
						 | 
					9160e496bc | ||
| 
						 | 
					2a7ac78f02 | ||
| 
						 | 
					64efa4627d | ||
| 
						 | 
					f7e35569ce | ||
| 
						 | 
					e8af32ec2b | ||
| 
						 | 
					e092ce51f6 | ||
| 
						 | 
					7b78edb1b7 | ||
| 
						 | 
					b332e7090e | ||
| 
						 | 
					67eb7723d6 | ||
| 
						 | 
					251d138474 | ||
| 
						 | 
					1170dfac05 | ||
| 
						 | 
					4157f141c7 | ||
| 
						 | 
					f569abd28a | ||
| 
						 | 
					088f9687c0 | ||
| 
						 | 
					e23df1f07a | ||
| 
						 | 
					c818540dfd | ||
| 
						 | 
					21365cbe1a | ||
| 
						 | 
					5471a80a96 | ||
| 
						 | 
					d7b6fa9cd0 | ||
| 
						 | 
					dfdc2e02ef | ||
| 
						 | 
					893ec9a302 | ||
| 
						 | 
					05f65c38e6 | ||
| 
						 | 
					2e9d062ec0 | ||
| 
						 | 
					6b0b394e61 | ||
| 
						 | 
					25621396c9 | ||
| 
						 | 
					82aa0271f3 | ||
| 
						 | 
					653cab13f8 | ||
| 
						 | 
					b526f86b49 | ||
| 
						 | 
					53c0f00888 | ||
| 
						 | 
					f0c4d9de40 | ||
| 
						 | 
					03ef8cec83 | ||
| 
						 | 
					85f2a2e8c2 | ||
| 
						 | 
					584b3e6642 | ||
| 
						 | 
					39b7ef841d | ||
| 
						 | 
					aa16a9098d | ||
| 
						 | 
					7b8c2707bc | ||
| 
						 | 
					60e26a31a7 | ||
| 
						 | 
					3473c25c14 | ||
| 
						 | 
					e52f022026 | ||
| 
						 | 
					b1a7df8e43 | ||
| 
						 | 
					0fd2479b7c | ||
| 
						 | 
					273857f914 | ||
| 
						 | 
					a08b85dbc8 | ||
| 
						 | 
					a0aedf299a | ||
| 
						 | 
					3c61426844 | ||
| 
						 | 
					786f228076 | ||
| 
						 | 
					004da28792 | ||
| 
						 | 
					6e2be6efb6 | ||
| 
						 | 
					a994dfcfbc | ||
| 
						 | 
					7a8ea2ac93 | ||
| 
						 | 
					0da3965d19 | ||
| 
						 | 
					885fd7bb46 | ||
| 
						 | 
					08771f9c89 | ||
| 
						 | 
					8be48195a5 | ||
| 
						 | 
					98ce2d650e | ||
| 
						 | 
					3af327116a | ||
| 
						 | 
					b75434db93 | ||
| 
						 | 
					04e912aacd | ||
| 
						 | 
					d7be352f87 | ||
| 
						 | 
					96be3ec22c | ||
| 
						 | 
					32e7e0d790 | ||
| 
						 | 
					becc320e62 | ||
| 
						 | 
					7666ed57d1 | ||
| 
						 | 
					5e61d0955e | ||
| 
						 | 
					e8a4662ae7 | ||
| 
						 | 
					a48da3bd3b | ||
| 
						 | 
					5f1a5d7b99 | ||
| 
						 | 
					3e28a9db8f | ||
| 
						 | 
					ebf6071d77 | ||
| 
						 | 
					47a35fb9fb | ||
| 
						 | 
					48e88aba44 | ||
| 
						 | 
					b85f99c140 | ||
| 
						 | 
					0a5e0e1f71 | ||
| 
						 | 
					85dc22ebb7 | ||
| 
						 | 
					5c21526009 | ||
| 
						 | 
					14dff1cefc | ||
| 
						 | 
					39fbb844f9 | ||
| 
						 | 
					ca4e0c973a | ||
| 
						 | 
					ecb42bee80 | ||
| 
						 | 
					674ed2a9f3 | ||
| 
						 | 
					252daf9717 | ||
| 
						 | 
					196b8eaad3 | ||
| 
						 | 
					8e526ba1bf | ||
| 
						 | 
					19225828d9 | ||
| 
						 | 
					7e594126be | ||
| 
						 | 
					d2529e6334 | ||
| 
						 | 
					97344f18e2 | ||
| 
						 | 
					33934db629 | ||
| 
						 | 
					6c6165c9f5 | ||
| 
						 | 
					853460b20d | ||
| 
						 | 
					cc4d9676c5 | ||
| 
						 | 
					1cf1b819f4 | ||
| 
						 | 
					f916c66d2b | ||
| 
						 | 
					550aa86b45 | ||
| 
						 | 
					014e764758 | ||
| 
						 | 
					d1fc28432b | ||
| 
						 | 
					879576f0a2 | ||
| 
						 | 
					69098210be | ||
| 
						 | 
					99df4f892d | ||
| 
						 | 
					7bc04fbad3 | ||
| 
						 | 
					8a74ce578d | ||
| 
						 | 
					0805e4e5de | ||
| 
						 | 
					f1060fc88e | ||
| 
						 | 
					7d3d3d0a3a | ||
| 
						 | 
					40377032e3 | ||
| 
						 | 
					b2971edd7d | ||
| 
						 | 
					c37d723692 | ||
| 
						 | 
					30f9026e1d | ||
| 
						 | 
					332286072e | ||
| 
						 | 
					d6da172a2a | ||
| 
						 | 
					ebfe584afc | ||
| 
						 | 
					6250023583 | ||
| 
						 | 
					6b4f3d63b8 | ||
| 
						 | 
					56db773a09 | ||
| 
						 | 
					fc6c472401 | ||
| 
						 | 
					2cd42a6866 | ||
| 
						 | 
					36a90c345c | ||
| 
						 | 
					ef1e82c72c | ||
| 
						 | 
					88f9534685 | ||
| 
						 | 
					68254a052a | ||
| 
						 | 
					2425b3a166 | ||
| 
						 | 
					5524ed753b | ||
| 
						 | 
					89711723da | ||
| 
						 | 
					bed2740ffd | ||
| 
						 | 
					751d633c3d | ||
| 
						 | 
					45952cbdf2 | ||
| 
						 | 
					b355dd7b23 | ||
| 
						 | 
					48a186f172 | ||
| 
						 | 
					39dc7ec2ab | ||
| 
						 | 
					2fedabd3b9 | ||
| 
						 | 
					6d719e9480 | ||
| 
						 | 
					05e278afda | ||
| 
						 | 
					87dbf462cb | ||
| 
						 | 
					40e896bc5b | ||
| 
						 | 
					3e940f80c7 | ||
| 
						 | 
					dbf2888d43 | ||
| 
						 | 
					d412355324 | ||
| 
						 | 
					178732217f | ||
| 
						 | 
					de17b95c3d | ||
| 
						 | 
					d14e774525 | ||
| 
						 | 
					ca5402a7fa | ||
| 
						 | 
					7a6fa7c5b4 | ||
| 
						 | 
					da36c286a6 | ||
| 
						 | 
					d3901bcf2e | ||
| 
						 | 
					94c8d4fdfb | ||
| 
						 | 
					ab8bdc18bb | ||
| 
						 | 
					c9dcd7442a | ||
| 
						 | 
					34c8f13346 | ||
| 
						 | 
					7a8ccda95c | ||
| 
						 | 
					44a1448542 | ||
| 
						 | 
					c87d89ffaf | ||
| 
						 | 
					0868749d42 | ||
| 
						 | 
					1d40ee23f0 | ||
| 
						 | 
					8893f32603 | ||
| 
						 | 
					adcf7e8dc3 | ||
| 
						 | 
					901f7c5c36 | ||
| 
						 | 
					775bb413b3 | ||
| 
						 | 
					64cd5b5a46 | ||
| 
						 | 
					ae356609b1 | ||
| 
						 | 
					6102a5d2b0 | ||
| 
						 | 
					f8782ee2d7 | ||
| 
						 | 
					6181ec4c77 | ||
| 
						 | 
					e0e7a685ef | ||
| 
						 | 
					ae1f8cdad2 | ||
| 
						 | 
					a4cf792e6d | ||
| 
						 | 
					89109ded53 | ||
| 
						 | 
					e20e52a4b2 | ||
| 
						 | 
					20c4b1cbec | ||
| 
						 | 
					5238b0241d | ||
| 
						 | 
					9cdf6c203d | ||
| 
						 | 
					839335cae6 | ||
| 
						 | 
					a99b2ce167 | ||
| 
						 | 
					b695141d87 | ||
| 
						 | 
					92d5c9f866 | ||
| 
						 | 
					7f18a1ffe0 | ||
| 
						 | 
					8c3fdaaa62 | ||
| 
						 | 
					5ac1c69710 | ||
| 
						 | 
					de2d5fba63 | ||
| 
						 | 
					33d516748f | ||
| 
						 | 
					de17f6f0fd | ||
| 
						 | 
					756731fc02 | ||
| 
						 | 
					e46be0415f | ||
| 
						 | 
					aa02fb50bf | ||
| 
						 | 
					8b6cd9c772 | ||
| 
						 | 
					cdd0d3351a | ||
| 
						 | 
					8b6d584529 | ||
| 
						 | 
					f49fdd4141 | ||
| 
						 | 
					b26e1be81a | ||
| 
						 | 
					bacab38d7f | ||
| 
						 | 
					701c05ce96 | ||
| 
						 | 
					438c452585 | ||
| 
						 | 
					0a7a1eff3f | ||
| 
						 | 
					87e743e381 | ||
| 
						 | 
					a03f1b3d55 | ||
| 
						 | 
					2d8dc3d243 | ||
| 
						 | 
					b982232cc5 | ||
| 
						 | 
					61c8d728ac | ||
| 
						 | 
					851a2bf855 | ||
| 
						 | 
					e0bdde3630 | ||
| 
						 | 
					6a0dcd7f0e | ||
| 
						 | 
					75f0b4c879 | ||
| 
						 | 
					db536a9504 | ||
| 
						 | 
					0fb114dede | ||
| 
						 | 
					e703342179 | ||
| 
						 | 
					35c8f4a611 | ||
| 
						 | 
					7c89ae44a9 | ||
| 
						 | 
					84fe06da22 | ||
| 
						 | 
					806318c8b3 | ||
| 
						 | 
					3aac2e1822 | ||
| 
						 | 
					168baef433 | ||
| 
						 | 
					6dba6cd78d | ||
| 
						 | 
					502250d08f | ||
| 
						 | 
					7395f0e680 | ||
| 
						 | 
					494d3fdaca | ||
| 
						 | 
					7b86a157de | ||
| 
						 | 
					0988c41785 | ||
| 
						 | 
					522db1bf01 | ||
| 
						 | 
					06f066f90d | ||
| 
						 | 
					f37b20677b | ||
| 
						 | 
					cd2eac1032 | ||
| 
						 | 
					8ac38d58d7 | ||
| 
						 | 
					4c80cc313a | ||
| 
						 | 
					1c65fee9b4 | ||
| 
						 | 
					90dda7edc1 | ||
| 
						 | 
					da054fae20 | ||
| 
						 | 
					bdb6611e30 | ||
| 
						 | 
					9284f973f1 | ||
| 
						 | 
					2bfd64c3c9 | ||
| 
						 | 
					939d24cce5 | ||
| 
						 | 
					27b0183c46 | ||
| 
						 | 
					d14efacac7 | ||
| 
						 | 
					150a002c40 | ||
| 
						 | 
					ce0def3bd8 | ||
| 
						 | 
					ee20fa97c2 | ||
| 
						 | 
					7403b7d700 | ||
| 
						 | 
					87ef173e0a | ||
| 
						 | 
					52a3fb6bc7 | ||
| 
						 | 
					92e2a257a6 | ||
| 
						 | 
					32e175752c | ||
| 
						 | 
					d43f7180dc | ||
| 
						 | 
					0129c2b0fc | ||
| 
						 | 
					4ed1990001 | ||
| 
						 | 
					5bd6ab27ae | ||
| 
						 | 
					f3593b89fa | ||
| 
						 | 
					23d84b2310 | ||
| 
						 | 
					fdc49402ec | ||
| 
						 | 
					5457c133e1 | ||
| 
						 | 
					292e588ee3 | ||
| 
						 | 
					243494c25e | ||
| 
						 | 
					e4365f3706 | ||
| 
						 | 
					310f3038d3 | ||
| 
						 | 
					4e6033273d | ||
| 
						 | 
					73718586d3 | ||
| 
						 | 
					011abe61e8 | ||
| 
						 | 
					fe3a37f89d | ||
| 
						 | 
					8aea44e77b | ||
| 
						 | 
					5529aec0d6 | ||
| 
						 | 
					369549d23f | ||
| 
						 | 
					181ea9a381 | ||
| 
						 | 
					76b8f2854e | ||
| 
						 | 
					320e5198f9 | ||
| 
						 | 
					e522539e2d | ||
| 
						 | 
					7c996b83d2 | ||
| 
						 | 
					3dd354d7aa | ||
| 
						 | 
					f4ad6e2157 | ||
| 
						 | 
					8b170dc2bf | ||
| 
						 | 
					dcb9d779bf | ||
| 
						 | 
					80f736d670 | ||
| 
						 | 
					8502c6da3c | ||
| 
						 | 
					b131449422 | ||
| 
						 | 
					6eebc4a620 | ||
| 
						 | 
					4661ab1179 | ||
| 
						 | 
					86046445ed | ||
| 
						 | 
					baea9bf944 | ||
| 
						 | 
					0951ee9e63 | ||
| 
						 | 
					5492528287 | ||
| 
						 | 
					14dbd220c2 | ||
| 
						 | 
					babc890c59 | ||
| 
						 | 
					6f7b47ff40 | ||
| 
						 | 
					3991f03202 | ||
| 
						 | 
					27271d5da7 | ||
| 
						 | 
					627312e1de | ||
| 
						 | 
					bfc9550e4e | ||
| 
						 | 
					2b9c21268b | ||
| 
						 | 
					3dce4ed6f1 | ||
| 
						 | 
					0f16c2ea87 | ||
| 
						 | 
					9a635f0686 | ||
| 
						 | 
					6a0d4b2baa | ||
| 
						 | 
					ac017098ad | ||
| 
						 | 
					98fef2640d | ||
| 
						 | 
					8bb66e133a | ||
| 
						 | 
					68a582901d | ||
| 
						 | 
					c094f4c06e | ||
| 
						 | 
					f7ca545544 | ||
| 
						 | 
					69b4716894 | ||
| 
						 | 
					7e44dcc5bf | ||
| 
						 | 
					ab9843e183 | ||
| 
						 | 
					01af706ade | ||
| 
						 | 
					9ebdb08e99 | ||
| 
						 | 
					a74ffe25d9 | ||
| 
						 | 
					7f95e27707 | ||
| 
						 | 
					1facf5bba3 | ||
| 
						 | 
					03d77009eb | ||
| 
						 | 
					8afd6812b5 | ||
| 
						 | 
					ec9ad78fcf | ||
| 
						 | 
					6f4e93dc90 | ||
| 
						 | 
					a38e43862d | ||
| 
						 | 
					39294bb037 | ||
| 
						 | 
					edc5e59b78 | ||
| 
						 | 
					c00fd9fd37 | ||
| 
						 | 
					b3e621dd9f | ||
| 
						 | 
					6e8c49b978 | ||
| 
						 | 
					398d57133d | ||
| 
						 | 
					16521a6feb | ||
| 
						 | 
					3ca0b37a3e | ||
| 
						 | 
					cf2ec1229d | ||
| 
						 | 
					fe9b1e5f9b | ||
| 
						 | 
					f5b96ddf01 | ||
| 
						 | 
					2fe076fb27 | ||
| 
						 | 
					99249cff04 | ||
| 
						 | 
					0cdf7b0613 | ||
| 
						 | 
					90bcf4f157 | ||
| 
						 | 
					03c3ec4e12 | ||
| 
						 | 
					ca9bb20d64 | ||
| 
						 | 
					c6bc078fd9 | ||
| 
						 | 
					2f4bd6e52c | ||
| 
						 | 
					2affe53727 | ||
| 
						 | 
					09654d7dd8 | ||
| 
						 | 
					90a4e37815 | ||
| 
						 | 
					60889c0c79 | ||
| 
						 | 
					20f3408d96 | ||
| 
						 | 
					e9d86789db | ||
| 
						 | 
					5152b7c66c | ||
| 
						 | 
					c494c4e12c | ||
| 
						 | 
					54d58ccb7e | ||
| 
						 | 
					714a77bfbe | ||
| 
						 | 
					d48f8bf5cc | ||
| 
						 | 
					99d97754a6 | ||
| 
						 | 
					b9d437de2a | ||
| 
						 | 
					11403f2019 | ||
| 
						 | 
					1ca102d639 | ||
| 
						 | 
					339ba55111 | ||
| 
						 | 
					14ae59885a | ||
| 
						 | 
					e3ef54f99b | ||
| 
						 | 
					001901f9a9 | ||
| 
						 | 
					6a98f60e2e | ||
| 
						 | 
					6f2e24c47d | ||
| 
						 | 
					aafa368923 | ||
| 
						 | 
					eb783cab4c | ||
| 
						 | 
					6533aa865a | ||
| 
						 | 
					f1a1e1bc07 | ||
| 
						 | 
					953f4838dd | ||
| 
						 | 
					130b892d34 | ||
| 
						 | 
					6ad525c77e | ||
| 
						 | 
					d0ca74ad27 | ||
| 
						 | 
					9806f69b4d | ||
| 
						 | 
					34d9b5e3d7 | ||
| 
						 | 
					3bf5189d86 | ||
| 
						 | 
					12e5b0681b | ||
| 
						 | 
					8c0285d608 | ||
| 
						 | 
					36558fa3b8 | ||
| 
						 | 
					235f940cde | ||
| 
						 | 
					803d61fcbc | ||
| 
						 | 
					ffbd7d8de4 | ||
| 
						 | 
					4ed924d7c7 | ||
| 
						 | 
					798dc9948b | ||
| 
						 | 
					13515f7ee4 | ||
| 
						 | 
					ef80824c26 | ||
| 
						 | 
					c8503fd65e | ||
| 
						 | 
					b3c454fb1c | ||
| 
						 | 
					1d7723e873 | ||
| 
						 | 
					77100b2365 | ||
| 
						 | 
					259a788134 | ||
| 
						 | 
					39511455cb | ||
| 
						 | 
					b04c16178e | ||
| 
						 | 
					49a959c06e | ||
| 
						 | 
					096a8932b4 | ||
| 
						 | 
					e39e66df93 | ||
| 
						 | 
					513633f49a | ||
| 
						 | 
					eb3740daaf | ||
| 
						 | 
					f7947b148a | ||
| 
						 | 
					9a2a702f3f | ||
| 
						 | 
					c65d95bf29 | ||
| 
						 | 
					753a5edc4f | ||
| 
						 | 
					0b3f853c2d | ||
| 
						 | 
					3527fcf1d5 | ||
| 
						 | 
					4544a89c7a | ||
| 
						 | 
					ffeae9005e | ||
| 
						 | 
					47217bcfb7 | ||
| 
						 | 
					80ff58b57a | ||
| 
						 | 
					d15dd368f1 | ||
| 
						 | 
					8a2ec32bd8 | ||
| 
						 | 
					410496ed52 | ||
| 
						 | 
					b7b07552e5 | ||
| 
						 | 
					44486e80d9 | ||
| 
						 | 
					7890c527d8 | ||
| 
						 | 
					2c82ab79a7 | ||
| 
						 | 
					e3ebe5fc53 | ||
| 
						 | 
					0ac430892e | ||
| 
						 | 
					a7739c942c | ||
| 
						 | 
					24581482d0 | ||
| 
						 | 
					0571c3b453 | ||
| 
						 | 
					73e7f5a0b0 | ||
| 
						 | 
					20c0adb961 | ||
| 
						 | 
					a01e03562f | ||
| 
						 | 
					d184ed0130 | ||
| 
						 | 
					089e1c2aee | ||
| 
						 | 
					ebab0e91ee | ||
| 
						 | 
					858a2b1b88 | ||
| 
						 | 
					02bd59827c | ||
| 
						 | 
					4991428510 | ||
| 
						 | 
					3b245f5dc1 | ||
| 
						 | 
					c9c81da901 | ||
| 
						 | 
					4919cdc3fb | ||
| 
						 | 
					e90e1f577d | ||
| 
						 | 
					afd4284403 | ||
| 
						 | 
					150b350d31 | ||
| 
						 | 
					2818520bd1 | ||
| 
						 | 
					2819952292 | ||
| 
						 | 
					5af71af51c | ||
| 
						 | 
					07a55b51df | ||
| 
						 | 
					66dd68b49d | ||
| 
						 | 
					9812657777 | ||
| 
						 | 
					0b09312fc6 | ||
| 
						 | 
					d0a7ac6b74 | ||
| 
						 | 
					ff9a238fbd | ||
| 
						 | 
					359fffa5f1 | ||
| 
						 | 
					5bf92ced1a | ||
| 
						 | 
					340bcc7b45 | ||
| 
						 | 
					ef03742bd4 | ||
| 
						 | 
					20431ec16d | ||
| 
						 | 
					becba8157b | ||
| 
						 | 
					51fd3bb0eb | ||
| 
						 | 
					4bbd3acb4e | ||
| 
						 | 
					3bc930ea7b | ||
| 
						 | 
					d1b26f8e86 | ||
| 
						 | 
					fdf15caaff | ||
| 
						 | 
					c7b4a53c0b | ||
| 
						 | 
					af78dc0308 | ||
| 
						 | 
					5ad39493c4 | ||
| 
						 | 
					61f597b408 | ||
| 
						 | 
					2162825240 | ||
| 
						 | 
					2b780e70d1 | ||
| 
						 | 
					a3823f818e | ||
| 
						 | 
					1f7c47bcaf | ||
| 
						 | 
					ec53c365a2 | ||
| 
						 | 
					793ad1f2d4 | ||
| 
						 | 
					9bc733b76c | ||
| 
						 | 
					21b28f0217 | ||
| 
						 | 
					d3e23caa52 | ||
| 
						 | 
					9e7518de67 | ||
| 
						 | 
					679f0047aa | ||
| 
						 | 
					d77d5ce14b | ||
| 
						 | 
					33ec22a2af | ||
| 
						 | 
					353053225f | ||
| 
						 | 
					b7f3d6f7f7 | ||
| 
						 | 
					e34577499d | ||
| 
						 | 
					4cf8960c0c | ||
| 
						 | 
					1f93ea0675 | ||
| 
						 | 
					25b705c3a8 | ||
| 
						 | 
					0725588731 | ||
| 
						 | 
					fc5c61cc8b | ||
| 
						 | 
					ac282e63c6 | ||
| 
						 | 
					c3941941ce | ||
| 
						 | 
					46cdd53323 | ||
| 
						 | 
					3ff3e302c3 | ||
| 
						 | 
					f2ceecf95c | ||
| 
						 | 
					9314c7c881 | ||
| 
						 | 
					54abb2c572 | ||
| 
						 | 
					8fa3bdd025 | ||
| 
						 | 
					5e7a308528 | ||
| 
						 | 
					7952177786 | ||
| 
						 | 
					9afbe49c84 | ||
| 
						 | 
					9f06ba2db3 | ||
| 
						 | 
					fe55bfddcf | ||
| 
						 | 
					c0842e6444 | ||
| 
						 | 
					3fed20d06a | ||
| 
						 | 
					5e8f2e2c04 | ||
| 
						 | 
					e4df99ea84 | ||
| 
						 | 
					b3276f5f11 | ||
| 
						 | 
					32667ca256 | ||
| 
						 | 
					bed122a170 | ||
| 
						 | 
					14adc9b875 | ||
| 
						 | 
					a8778bbc5a | ||
| 
						 | 
					a54e641f44 | ||
| 
						 | 
					5c99efe87a | ||
| 
						 | 
					7da1d731ff | ||
| 
						 | 
					af9828e819 | ||
| 
						 | 
					7a27136142 | ||
| 
						 | 
					012ad2d423 | ||
| 
						 | 
					ef3bdbf4da | ||
| 
						 | 
					b3bb698f7b | ||
| 
						 | 
					1ed5d1e4c1 | ||
| 
						 | 
					bdee01a03d | ||
| 
						 | 
					458f7376d7 | ||
| 
						 | 
					cb3a00e027 | ||
| 
						 | 
					482eb1f3fb | ||
| 
						 | 
					6e0f638f5e | ||
| 
						 | 
					bab349047d | ||
| 
						 | 
					28ea6b8de8 | ||
| 
						 | 
					9d51bbdae8 | ||
| 
						 | 
					d622f79533 | ||
| 
						 | 
					04c8515ad1 | ||
| 
						 | 
					53bc4251d1 | ||
| 
						 | 
					a5a751f02f | ||
| 
						 | 
					66ed5f82c4 | ||
| 
						 | 
					c802a9e6aa | ||
| 
						 | 
					880f210946 | ||
| 
						 | 
					4f9f7eb6a6 | ||
| 
						 | 
					f910c4a8e7 | ||
| 
						 | 
					529686d965 | ||
| 
						 | 
					84dfd1536f | ||
| 
						 | 
					85dedc324c | ||
| 
						 | 
					d639237411 | ||
| 
						 | 
					449aaf75f1 | ||
| 
						 | 
					b1fda66caa | ||
| 
						 | 
					66a8e90fd9 | ||
| 
						 | 
					37b487d191 | ||
| 
						 | 
					6c59fe3577 | ||
| 
						 | 
					1cbb70c992 | ||
| 
						 | 
					e06b39f882 | ||
| 
						 | 
					2602b1493e | ||
| 
						 | 
					989d14502d | ||
| 
						 | 
					f78a550282 | ||
| 
						 | 
					54a1abb284 | ||
| 
						 | 
					97b492a8e2 | ||
| 
						 | 
					0873bd14a9 | ||
| 
						 | 
					eff6ba429a | ||
| 
						 | 
					8c18064be4 | ||
| 
						 | 
					44a1ac0cf3 | ||
| 
						 | 
					28dc8d88dd | ||
| 
						 | 
					2c0c2b64ba | ||
| 
						 | 
					bd3e0f5248 | ||
| 
						 | 
					cd52d98938 | ||
| 
						 | 
					894c70e7f8 | ||
| 
						 | 
					51d70c2edd | ||
| 
						 | 
					7d4b355240 | ||
| 
						 | 
					3b56193b98 | ||
| 
						 | 
					b16045b57d | ||
| 
						 | 
					9e8b0fca5b | ||
| 
						 | 
					35cf1b3b5b | ||
| 
						 | 
					83f788af57 | ||
| 
						 | 
					2ffe378d3f | ||
| 
						 | 
					38b33a4a5e | ||
| 
						 | 
					60bf9ed0a0 | ||
| 
						 | 
					16adf4de1b | ||
| 
						 | 
					80de983023 | ||
| 
						 | 
					8703ca623f | ||
| 
						 | 
					286253a73f | ||
| 
						 | 
					bd806a41df | ||
| 
						 | 
					b89c4e9002 | ||
| 
						 | 
					6dbf31c0c3 | ||
| 
						 | 
					060c45d8a1 | ||
| 
						 | 
					33d3e82e4d | ||
| 
						 | 
					4bb074514d | ||
| 
						 | 
					e3f8892003 | ||
| 
						 | 
					9d00ad5f18 | ||
| 
						 | 
					dae4344850 | ||
| 
						 | 
					aa7f3fabe2 | ||
| 
						 | 
					f93434a8ce | ||
| 
						 | 
					25dee56be9 | ||
| 
						 | 
					ce9a3f3797 | ||
| 
						 | 
					11e384920a | ||
| 
						 | 
					a0a1f1e536 | ||
| 
						 | 
					3b3d0ea9eb | ||
| 
						 | 
					2f4d78286d | ||
| 
						 | 
					677dc6f985 | ||
| 
						 | 
					d52057e732 | ||
| 
						 | 
					fa2a1cb1fb | ||
| 
						 | 
					19a0fb04ad | ||
| 
						 | 
					947352f2fe | ||
| 
						 | 
					adcbedb686 | ||
| 
						 | 
					7732f92acd | ||
| 
						 | 
					ad8a001688 | ||
| 
						 | 
					9121eada08 | ||
| 
						 | 
					49bd4d25a2 | ||
| 
						 | 
					d80b4129c6 | ||
| 
						 | 
					7edb4172d5 | ||
| 
						 | 
					c3a4677990 | ||
| 
						 | 
					5cbb893a3b | ||
| 
						 | 
					f28a2a432b | ||
| 
						 | 
					03b75a2d27 | ||
| 
						 | 
					859fe69083 | ||
| 
						 | 
					f6f2205ddb | ||
| 
						 | 
					0f9a03ef61 | ||
| 
						 | 
					9aa417c084 | ||
| 
						 | 
					7b70952f5d | ||
| 
						 | 
					edd3d07b49 | ||
| 
						 | 
					5293d0a4ec | ||
| 
						 | 
					3c8c7beae1 | ||
| 
						 | 
					9c3ba9fdcd | ||
| 
						 | 
					fb1748fb0f | ||
| 
						 | 
					0a109fbd03 | ||
| 
						 | 
					5cf64db74e | ||
| 
						 | 
					488cc94f36 | ||
| 
						 | 
					e15846bf79 | ||
| 
						 | 
					752bd00674 | ||
| 
						 | 
					7fadfcbe32 | ||
| 
						 | 
					41141e75bb | ||
| 
						 | 
					50f641e627 | ||
| 
						 | 
					c7883fd093 | ||
| 
						 | 
					4fcb24b2b1 | ||
| 
						 | 
					5003557935 | ||
| 
						 | 
					bdf1ba84da | ||
| 
						 | 
					b0b4def983 | ||
| 
						 | 
					cc184bbe9e | ||
| 
						 | 
					ad30c830aa | ||
| 
						 | 
					1d791a8af4 | ||
| 
						 | 
					e63c51cd97 | ||
| 
						 | 
					f202e32908 | ||
| 
						 | 
					26e1a08e82 | ||
| 
						 | 
					4d5119d435 | ||
| 
						 | 
					75e34ea62e | ||
| 
						 | 
					0a183d6274 | ||
| 
						 | 
					21d8060aea | ||
| 
						 | 
					9cbe906f60 | ||
| 
						 | 
					8ce4137399 | ||
| 
						 | 
					5f8a139347 | ||
| 
						 | 
					9bb009a3fe | ||
| 
						 | 
					726d65923f | ||
| 
						 | 
					8a6be4cb2d | ||
| 
						 | 
					10b06beb8e | ||
| 
						 | 
					81318c7968 | ||
| 
						 | 
					47a2c1c6e5 | ||
| 
						 | 
					39cee65c6b | ||
| 
						 | 
					8582ec724e | ||
| 
						 | 
					b0139682e8 | ||
| 
						 | 
					d39c475a6d | ||
| 
						 | 
					48f38354c6 | ||
| 
						 | 
					cd5a920ed5 | ||
| 
						 | 
					71bc1f378d | ||
| 
						 | 
					0ee6c31cff | ||
| 
						 | 
					af89a9971e | ||
| 
						 | 
					c718a8ef72 | ||
| 
						 | 
					8c8ad0faf0 | ||
| 
						 | 
					314d5bbb7f | ||
| 
						 | 
					102255757a | ||
| 
						 | 
					914067a0d0 | ||
| 
						 | 
					06e3ae2536 | ||
| 
						 | 
					7f9b252556 | ||
| 
						 | 
					3d700e243f | ||
| 
						 | 
					bcfc78ce11 | ||
| 
						 | 
					09241765d5 | ||
| 
						 | 
					671c83c265 | ||
| 
						 | 
					772d28b766 | ||
| 
						 | 
					c26fcea58d | ||
| 
						 | 
					1e5e26dbff | ||
| 
						 | 
					742fc54864 | ||
| 
						 | 
					49738f43c0 | ||
| 
						 | 
					9f85f61010 | ||
| 
						 | 
					239f422039 | ||
| 
						 | 
					67af3c37be | ||
| 
						 | 
					a9442385c4 | ||
| 
						 | 
					8c9cd10b8b | ||
| 
						 | 
					72542059dd | ||
| 
						 | 
					a843fc6d40 | ||
| 
						 | 
					4beed60c08 | ||
| 
						 | 
					4049c1e480 | ||
| 
						 | 
					8449314da2 | ||
| 
						 | 
					63ad057028 | ||
| 
						 | 
					e720464330 | ||
| 
						 | 
					24036afef9 | ||
| 
						 | 
					c78fa1a1bc | ||
| 
						 | 
					faa8b9022c | ||
| 
						 | 
					729bafef7a | ||
| 
						 | 
					590b028632 | ||
| 
						 | 
					8150d00f36 | ||
| 
						 | 
					060065926f | ||
| 
						 | 
					70babe8a28 | ||
| 
						 | 
					c36e09664f | ||
| 
						 | 
					a9672246f3 | ||
| 
						 | 
					ff571884e9 | ||
| 
						 | 
					475138bceb | ||
| 
						 | 
					4a8af199c2 | ||
| 
						 | 
					bdabf5db72 | ||
| 
						 | 
					6a5f21b34e | ||
| 
						 | 
					d608be103c | ||
| 
						 | 
					374bb5d18a | ||
| 
						 | 
					031d6c25ff | ||
| 
						 | 
					223fb7b075 | ||
| 
						 | 
					a746741971 | ||
| 
						 | 
					120faf2a58 | ||
| 
						 | 
					990bca0dc6 | ||
| 
						 | 
					3406472db7 | ||
| 
						 | 
					1bd733c9f6 | ||
| 
						 | 
					238c7f982e | ||
| 
						 | 
					fcb81147cb | ||
| 
						 | 
					1915b73783 | ||
| 
						 | 
					ee79e621fb | ||
| 
						 | 
					d203275a3b | ||
| 
						 | 
					9e8a996222 | ||
| 
						 | 
					0126b0b3ed | ||
| 
						 | 
					458928612c | ||
| 
						 | 
					e33f88e28d | ||
| 
						 | 
					be570bbf9e | ||
| 
						 | 
					f59b4be110 | ||
| 
						 | 
					37336e41be | ||
| 
						 | 
					d24a1a3f0a | ||
| 
						 | 
					f7258955bd | ||
| 
						 | 
					2a1eae5d6f | ||
| 
						 | 
					50ee0a4adb | ||
| 
						 | 
					955a26584e | ||
| 
						 | 
					1d3e407c8f | ||
| 
						 | 
					cb809c4596 | ||
| 
						 | 
					53bbe2888e | ||
| 
						 | 
					7246f476a5 | ||
| 
						 | 
					0785d1c390 | ||
| 
						 | 
					85d2c49d14 | ||
| 
						 | 
					8b77d62b7f | ||
| 
						 | 
					373058a32a | ||
| 
						 | 
					e6293c2c8c | ||
| 
						 | 
					eff181c959 | ||
| 
						 | 
					54752c2305 | ||
| 
						 | 
					b4753c044f | ||
| 
						 | 
					26493424ae | ||
| 
						 | 
					0282fd1332 | ||
| 
						 | 
					b9a019a08b | ||
| 
						 | 
					66f6a0e687 | ||
| 
						 | 
					2dd1b9f97d | ||
| 
						 | 
					89615f3045 | ||
| 
						 | 
					7e46192f67 | ||
| 
						 | 
					e78d985cdf | ||
| 
						 | 
					e8c4bf56fe | ||
| 
						 | 
					e6aa7d323d | ||
| 
						 | 
					fca8e25929 | ||
| 
						 | 
					8e8ac286b4 | ||
| 
						 | 
					7d9770b9a2 | ||
| 
						 | 
					1996230460 | ||
| 
						 | 
					de7897a864 | ||
| 
						 | 
					e2884dcdb7 | ||
| 
						 | 
					544a53a42b | ||
| 
						 | 
					2e4787bfc8 | ||
| 
						 | 
					1829eeb171 | ||
| 
						 | 
					c7488e3c4a | ||
| 
						 | 
					3bf9606383 | ||
| 
						 | 
					4f43f18f0a | ||
| 
						 | 
					5b7f197397 | ||
| 
						 | 
					018141c97f | ||
| 
						 | 
					4d7813e57c | ||
| 
						 | 
					605c60208f | ||
| 
						 | 
					884fafcc30 | ||
| 
						 | 
					56baa90320 | ||
| 
						 | 
					6bb20ee09e | ||
| 
						 | 
					541356430c | ||
| 
						 | 
					2f4d91fd69 | ||
| 
						 | 
					f58c5e6b30 | ||
| 
						 | 
					0311d0132c | ||
| 
						 | 
					c946c97402 | ||
| 
						 | 
					84a6f51318 | ||
| 
						 | 
					24a1501b0d | ||
| 
						 | 
					383b6f5fcc | ||
| 
						 | 
					633dd7ff9b | ||
| 
						 | 
					580624fad6 | ||
| 
						 | 
					a8190f7efa | ||
| 
						 | 
					dd2157534b | ||
| 
						 | 
					38a90e7669 | ||
| 
						 | 
					6bfc526dcd | ||
| 
						 | 
					aadb8a7405 | ||
| 
						 | 
					27082bf77e | ||
| 
						 | 
					a2903c80cd | ||
| 
						 | 
					9a77c5369c | ||
| 
						 | 
					3c30741a19 | ||
| 
						 | 
					7028ad4ec0 | ||
| 
						 | 
					8de750c6aa | ||
| 
						 | 
					04f98de9ee | ||
| 
						 | 
					a1a019784b | ||
| 
						 | 
					4aeeae77bd | ||
| 
						 | 
					651cfc2b78 | ||
| 
						 | 
					2ef8af25e2 | ||
| 
						 | 
					0b13852a5b | ||
| 
						 | 
					13427578c9 | ||
| 
						 | 
					d89ca2087e | ||
| 
						 | 
					8b0ea9fba6 | ||
| 
						 | 
					9f0b653d5a | ||
| 
						 | 
					659a339233 | ||
| 
						 | 
					4c29f177a0 | ||
| 
						 | 
					d664e63d55 | ||
| 
						 | 
					2493509dbe | ||
| 
						 | 
					1c8b27f554 | ||
| 
						 | 
					68297b7186 | ||
| 
						 | 
					34dd8d0a91 | ||
| 
						 | 
					81c44790d5 | ||
| 
						 | 
					d557b335cf | ||
| 
						 | 
					e2adc28cff | ||
| 
						 | 
					0fef6a6ecc | ||
| 
						 | 
					f2fd4b8a1f | ||
| 
						 | 
					95bd5605a8 | ||
| 
						 | 
					497cca7eca | ||
| 
						 | 
					54f78feedd | ||
| 
						 | 
					76408e53ae | ||
| 
						 | 
					be19e74d30 | ||
| 
						 | 
					dac578a775 | ||
| 
						 | 
					04732ce74b | ||
| 
						 | 
					a6c95a2374 | ||
| 
						 | 
					f68622abe9 | ||
| 
						 | 
					83a9a7bdb2 | ||
| 
						 | 
					6500afc0ca | ||
| 
						 | 
					c69b7ecc96 | ||
| 
						 | 
					615ef1e2d2 | ||
| 
						 | 
					cf69a0cd7f | ||
| 
						 | 
					06e892fb33 | ||
| 
						 | 
					e6c5dd6865 | ||
| 
						 | 
					247efdebdb | ||
| 
						 | 
					76f3792287 | ||
| 
						 | 
					64d8e2c727 | ||
| 
						 | 
					ead0bd9cb0 | ||
| 
						 | 
					66fc13b2ec | ||
| 
						 | 
					f3af4128b0 | ||
| 
						 | 
					0e43107c87 | ||
| 
						 | 
					1ee3e7997e | ||
| 
						 | 
					50fd61d91f | ||
| 
						 | 
					e4cdc051a9 | ||
| 
						 | 
					778e846e96 | ||
| 
						 | 
					a27759b647 | ||
| 
						 | 
					b75eceab41 | ||
| 
						 | 
					e748a5d5f4 | ||
| 
						 | 
					99c5a3ae46 | ||
| 
						 | 
					51da710f5a | ||
| 
						 | 
					569d69b3d2 | ||
| 
						 | 
					059a6b1d90 | ||
| 
						 | 
					990af7548a | ||
| 
						 | 
					a38aefdfc8 | ||
| 
						 | 
					3bcb12e7d1 | ||
| 
						 | 
					7904ecb462 | ||
| 
						 | 
					9ba4d45109 | ||
| 
						 | 
					56b8afe19d | ||
| 
						 | 
					f7aed9a94c | ||
| 
						 | 
					e12a7e881d | ||
| 
						 | 
					5afb65325d | ||
| 
						 | 
					135f520f32 | ||
| 
						 | 
					bc251f4ff6 | ||
| 
						 | 
					b8769751f6 | ||
| 
						 | 
					eff96d839e | ||
| 
						 | 
					aa34c23807 | ||
| 
						 | 
					195acdac8c | ||
| 
						 | 
					903e03c56c | ||
| 
						 | 
					0892767b8a | ||
| 
						 | 
					83ebfa772c | ||
| 
						 | 
					1583641322 | ||
| 
						 | 
					9510e2c256 | ||
| 
						 | 
					a9dbabe07e | ||
| 
						 | 
					12884008fa | ||
| 
						 | 
					02543bad1c | ||
| 
						 | 
					a8c56a5251 | ||
| 
						 | 
					4e5a855f3f | ||
| 
						 | 
					7e497a951e | ||
| 
						 | 
					cd08eabbfa | ||
| 
						 | 
					f7e62d9f81 | ||
| 
						 | 
					9a3761e86e | ||
| 
						 | 
					3619a68693 | ||
| 
						 | 
					efaf3c3bf9 | ||
| 
						 | 
					0e4e6a6f67 | ||
| 
						 | 
					42458e6278 | ||
| 
						 | 
					41ec995377 | ||
| 
						 | 
					4f37599326 | ||
| 
						 | 
					4144520e5c | ||
| 
						 | 
					6c4800546c | ||
| 
						 | 
					733733c8a7 | ||
| 
						 | 
					2aa67cc946 | ||
| 
						 | 
					9385981a9d | ||
| 
						 | 
					fff780035d | ||
| 
						 | 
					46127e673d | ||
| 
						 | 
					70df59b224 | ||
| 
						 | 
					0fdbaa803f | ||
| 
						 | 
					6af1830eff | ||
| 
						 | 
					6f860e2bd5 | ||
| 
						 | 
					20a492f7ee | ||
| 
						 | 
					63875e7591 | ||
| 
						 | 
					0ad98cabde | ||
| 
						 | 
					668879d2e1 | ||
| 
						 | 
					2e09783302 | ||
| 
						 | 
					49734114b3 | ||
| 
						 | 
					950d9d6ee7 | ||
| 
						 | 
					f7974aee2e | ||
| 
						 | 
					c870a82621 | ||
| 
						 | 
					984929a001 | ||
| 
						 | 
					7f9e2c1db8 | ||
| 
						 | 
					324e8389dc | ||
| 
						 | 
					6f448c5a38 | ||
| 
						 | 
					ec43efbb20 | ||
| 
						 | 
					3ed065de37 | ||
| 
						 | 
					8152f0d72c | ||
| 
						 | 
					f8047f4736 | ||
| 
						 | 
					b93c66dc2d | ||
| 
						 | 
					ac877b3065 | ||
| 
						 | 
					dee8abfdde | ||
| 
						 | 
					cef3841d73 | ||
| 
						 | 
					3cd5e8a041 | ||
| 
						 | 
					515b5f866e | ||
| 
						 | 
					321f62bf92 | ||
| 
						 | 
					f94fa47b52 | ||
| 
						 | 
					c502f8a722 | ||
| 
						 | 
					59b4868ac3 | ||
| 
						 | 
					3634e12cce | ||
| 
						 | 
					6d45445391 | ||
| 
						 | 
					4f47e268cc | ||
| 
						 | 
					0035b31cdb | ||
| 
						 | 
					f2565aee03 | ||
| 
						 | 
					5bd85668dd | ||
| 
						 | 
					20f990b6ce | ||
| 
						 | 
					6821379586 | ||
| 
						 | 
					73b040eb49 | ||
| 
						 | 
					49aa4b2e1e | ||
| 
						 | 
					972241c74c | ||
| 
						 | 
					680750e3c2 | ||
| 
						 | 
					5e7d4d9d15 | ||
| 
						 | 
					1e57e60613 | ||
| 
						 | 
					3ac7ce605a | ||
| 
						 | 
					b720dea9f0 | ||
| 
						 | 
					c80722aefe | ||
| 
						 | 
					a84fa69f28 | ||
| 
						 | 
					e33781e59f | ||
| 
						 | 
					8824bc7ece | ||
| 
						 | 
					c2e3b0e448 | ||
| 
						 | 
					f61a38e85a | ||
| 
						 | 
					d23e948216 | ||
| 
						 | 
					58bdaa31f0 | ||
| 
						 | 
					b6491d88a6 | ||
| 
						 | 
					f6061ba62e | ||
| 
						 | 
					427899ddce | ||
| 
						 | 
					c4ab7d2dbd | ||
| 
						 | 
					0fd2ba033f | ||
| 
						 | 
					ed38939a93 | ||
| 
						 | 
					c7ee26ce5a | ||
| 
						 | 
					909b8cb303 | ||
| 
						 | 
					b0277370cf | ||
| 
						 | 
					2ec8656bea | ||
| 
						 | 
					b2ef256910 | ||
| 
						 | 
					63d6ce95db | ||
| 
						 | 
					a9532b189c | ||
| 
						 | 
					844545411f | ||
| 
						 | 
					4e23a2b9b8 | ||
| 
						 | 
					5deba027eb | ||
| 
						 | 
					fc8b7efc6f | ||
| 
						 | 
					a1c2d9c0f3 | ||
| 
						 | 
					4ca49a0501 | ||
| 
						 | 
					493c53d090 | ||
| 
						 | 
					b27e956d35 | ||
| 
						 | 
					35ebed75c6 | ||
| 
						 | 
					7bfdb5f77f | ||
| 
						 | 
					8d8c02317f | ||
| 
						 | 
					a34482feab | ||
| 
						 | 
					cbdc8fd4a6 | ||
| 
						 | 
					8d3afaa53c | ||
| 
						 | 
					7ced9ef3df | ||
| 
						 | 
					e8a9ae7e80 | ||
| 
						 | 
					73a88ab3d3 | ||
| 
						 | 
					aaed82738a | ||
| 
						 | 
					de7f7b96db | ||
| 
						 | 
					1a669b3e68 | ||
| 
						 | 
					333af9b13a | ||
| 
						 | 
					a5bca5e240 | ||
| 
						 | 
					c885633e02 | ||
| 
						 | 
					ca7e20b7ca | ||
| 
						 | 
					545e11a3d7 | ||
| 
						 | 
					44f5287664 | ||
| 
						 | 
					cf510897f1 | ||
| 
						 | 
					1d171345f8 | ||
| 
						 | 
					4fa7e1cd49 | ||
| 
						 | 
					acd008298e | ||
| 
						 | 
					83a8021515 | ||
| 
						 | 
					cf88dfb1db | ||
| 
						 | 
					8937c4b481 | ||
| 
						 | 
					cc6af10a4d | ||
| 
						 | 
					6d94578955 | ||
| 
						 | 
					08442ab71e | ||
| 
						 | 
					10d91d213f | ||
| 
						 | 
					b7a3b06994 | ||
| 
						 | 
					5f12c37f23 | ||
| 
						 | 
					585edebccd | ||
| 
						 | 
					9921c62234 | ||
| 
						 | 
					1ac76d2e16 | ||
| 
						 | 
					6e983bf400 | ||
| 
						 | 
					6a8fd4fa6e | ||
| 
						 | 
					3698eaa2d2 | ||
| 
						 | 
					8d97ca433c | ||
| 
						 | 
					23cc65e537 | ||
| 
						 | 
					2f5a3c2bbe | ||
| 
						 | 
					f6485616cd | ||
| 
						 | 
					6544fb43d9 | ||
| 
						 | 
					a954b32dcc | ||
| 
						 | 
					426dc7836c | ||
| 
						 | 
					ff941ffc16 | ||
| 
						 | 
					a063c201df | ||
| 
						 | 
					e2be3fa0aa | ||
| 
						 | 
					609da6fb50 | ||
| 
						 | 
					fc9f3ccec3 | ||
| 
						 | 
					f7baa67a0a | ||
| 
						 | 
					e8d78c2cdb | ||
| 
						 | 
					9d33366092 | ||
| 
						 | 
					f5d61515c2 | ||
| 
						 | 
					711a04a972 | ||
| 
						 | 
					e5b470a3f1 | ||
| 
						 | 
					31820e1e22 | ||
| 
						 | 
					4849e8cd6d | ||
| 
						 | 
					77e3b460aa | ||
| 
						 | 
					b5321001f8 | ||
| 
						 | 
					38eba9f5ea | ||
| 
						 | 
					ea6f399454 | ||
| 
						 | 
					f8bf2d7b7d | ||
| 
						 | 
					c4856caebb | ||
| 
						 | 
					fc1030bb22 | ||
| 
						 | 
					9eb6cad8dc | ||
| 
						 | 
					0fa2a78dce | ||
| 
						 | 
					a56fa1558b | ||
| 
						 | 
					261c73a997 | ||
| 
						 | 
					929c1333ca | ||
| 
						 | 
					286a79d94d | ||
| 
						 | 
					8b951f99da | ||
| 
						 | 
					abb449bca0 | ||
| 
						 | 
					bd084028d1 | ||
| 
						 | 
					138a27570b | ||
| 
						 | 
					c2ed40a74f | ||
| 
						 | 
					a7e7a00cab | ||
| 
						 | 
					64a31ab3cd | ||
| 
						 | 
					71958bc0f1 | ||
| 
						 | 
					366ec35612 | ||
| 
						 | 
					3738f6e8ae | ||
| 
						 | 
					051a8e2af1 | ||
| 
						 | 
					2f43f28d5e | ||
| 
						 | 
					b64769754b | ||
| 
						 | 
					a97daa18d1 | ||
| 
						 | 
					b6556dce8b | ||
| 
						 | 
					aa8d8bc8b5 | ||
| 
						 | 
					0800dcfdc4 | ||
| 
						 | 
					12b0101e94 | ||
| 
						 | 
					021b391a02 | ||
| 
						 | 
					d11e2b6057 | ||
| 
						 | 
					264d90e7e5 | ||
| 
						 | 
					f9f3da9e78 | ||
| 
						 | 
					6435b49153 | ||
| 
						 | 
					f9aa2941cf | ||
| 
						 | 
					5a933d4bee | ||
| 
						 | 
					5536aea0df | ||
| 
						 | 
					976666d216 | ||
| 
						 | 
					9a5bcd4392 | ||
| 
						 | 
					812060a118 | ||
| 
						 | 
					089b5052e6 | ||
| 
						 | 
					874e5d72f4 | ||
| 
						 | 
					6b11de1329 | ||
| 
						 | 
					2245a7ad8d | ||
| 
						 | 
					ee5ec1b870 | ||
| 
						 | 
					74ccfe851b | ||
| 
						 | 
					e1c24bd5a2 | ||
| 
						 | 
					1349b79728 | ||
| 
						 | 
					d294d7604c | ||
| 
						 | 
					01df2cf464 | ||
| 
						 | 
					45b7322488 | ||
| 
						 | 
					b3055e992f | ||
| 
						 | 
					3da548565c | ||
| 
						 | 
					a975e85548 | ||
| 
						 | 
					c4b5ade752 | ||
| 
						 | 
					a4b61b0794 | ||
| 
						 | 
					f6011184b8 | ||
| 
						 | 
					74de118c6e | ||
| 
						 | 
					9c25e77c17 | ||
| 
						 | 
					440113e67e | ||
| 
						 | 
					a11b60c445 | ||
| 
						 | 
					a6052681ad | ||
| 
						 | 
					482d50536a | ||
| 
						 | 
					25c79a4fcd | ||
| 
						 | 
					02946144ac | ||
| 
						 | 
					71a360e9a3 | ||
| 
						 | 
					f7912d88b1 | ||
| 
						 | 
					975101d7d2 | ||
| 
						 | 
					ef58c5ff55 | ||
| 
						 | 
					e10221804a | ||
| 
						 | 
					284ed9ee0e | ||
| 
						 | 
					5d7b961997 | ||
| 
						 | 
					c699a5c4b4 | ||
| 
						 | 
					1f4ceb89cf | ||
| 
						 | 
					0934ca0040 | ||
| 
						 | 
					4738f892c2 | ||
| 
						 | 
					33004fcf33 | ||
| 
						 | 
					34d214c166 | ||
| 
						 | 
					a56cd92a1e | ||
| 
						 | 
					7251348507 | ||
| 
						 | 
					01cd5c84d6 | ||
| 
						 | 
					e210599fa6 | ||
| 
						 | 
					dbe7cee7e9 | ||
| 
						 | 
					7370d88ceb | ||
| 
						 | 
					34458e0c57 | ||
| 
						 | 
					05c8c3abf2 | ||
| 
						 | 
					e9d464b4d3 | ||
| 
						 | 
					6968c3ab9b | ||
| 
						 | 
					131a8a9650 | ||
| 
						 | 
					379ecbf9a9 | ||
| 
						 | 
					7b9dfa9a28 | ||
| 
						 | 
					fbd0f5eed2 | ||
| 
						 | 
					5970f904ae | ||
| 
						 | 
					8cbcb2868d | ||
| 
						 | 
					8ff2a4b026 | ||
| 
						 | 
					ae14d205a5 | ||
| 
						 | 
					ec5d560ec5 | ||
| 
						 | 
					fb543b53c0 | ||
| 
						 | 
					39c16422e2 | ||
| 
						 | 
					4d5b273ebe | ||
| 
						 | 
					ed6a860fad | ||
| 
						 | 
					423e579292 | ||
| 
						 | 
					ee11aa9e75 | ||
| 
						 | 
					c46d20fa92 | ||
| 
						 | 
					dc8d17574c | ||
| 
						 | 
					5c17cd04c8 | ||
| 
						 | 
					67ada02076 | ||
| 
						 | 
					32d94c2eaf | ||
| 
						 | 
					687b39a12a | ||
| 
						 | 
					705af407bf | ||
| 
						 | 
					080052da2e | ||
| 
						 | 
					ef735fd92a | ||
| 
						 | 
					17c16dcafc | ||
| 
						 | 
					a89b3018fb | ||
| 
						 | 
					851e2ebd32 | ||
| 
						 | 
					1225ce7fe8 | ||
| 
						 | 
					7e77a31b96 | ||
| 
						 | 
					d146b9002f | ||
| 
						 | 
					1f9d567b23 | ||
| 
						 | 
					ed1b3a023c | ||
| 
						 | 
					1ca18f501a | ||
| 
						 | 
					49588ccd98 | ||
| 
						 | 
					098dedc092 | ||
| 
						 | 
					b06f6b9545 | ||
| 
						 | 
					ba3cb94999 | ||
| 
						 | 
					74c67fbf4b | ||
| 
						 | 
					32b46e4910 | ||
| 
						 | 
					ecf5539ed2 | ||
| 
						 | 
					ac9db4e4d5 | ||
| 
						 | 
					0eb96094b0 | ||
| 
						 | 
					30b3ac7dc5 | ||
| 
						 | 
					0092790c7d | ||
| 
						 | 
					28909d8a51 | ||
| 
						 | 
					b20cfbb7b6 | ||
| 
						 | 
					97639bd0a8 | ||
| 
						 | 
					161ec73c96 | ||
| 
						 | 
					957d6bea15 | ||
| 
						 | 
					f8b6e5b414 | ||
| 
						 | 
					1ab450870e | ||
| 
						 | 
					de45f4884c | ||
| 
						 | 
					5da1f3e7c8 | ||
| 
						 | 
					983014952b | ||
| 
						 | 
					55298019a3 | ||
| 
						 | 
					a1ffc3f271 | ||
| 
						 | 
					2fb60aa997 | ||
| 
						 | 
					f5ec76537a | ||
| 
						 | 
					728491fd2b | ||
| 
						 | 
					d9d3f2b9e4 | ||
| 
						 | 
					3fe4864f65 | ||
| 
						 | 
					0b156f22a4 | ||
| 
						 | 
					35b1d93813 | ||
| 
						 | 
					d770851ac0 | ||
| 
						 | 
					989e7b1033 | ||
| 
						 | 
					c4e0eb7b49 | ||
| 
						 | 
					71f5d0dac7 | ||
| 
						 | 
					561b0c4381 | ||
| 
						 | 
					995fbc7330 | ||
| 
						 | 
					10ab8949c4 | ||
| 
						 | 
					c441202fea | ||
| 
						 | 
					ca261b0bee | ||
| 
						 | 
					52f3709f67 | ||
| 
						 | 
					c2ca6187fe | ||
| 
						 | 
					671a13d295 | ||
| 
						 | 
					14c3e2eccf | ||
| 
						 | 
					08e5b852c2 | ||
| 
						 | 
					1c9606c824 | ||
| 
						 | 
					3cd47b5c9b | ||
| 
						 | 
					aedc729087 | ||
| 
						 | 
					5f7cfa3fa9 | ||
| 
						 | 
					0083f30af5 | ||
| 
						 | 
					4a06f05ef5 | ||
| 
						 | 
					8f37cadce8 | ||
| 
						 | 
					a11603ca6c | ||
| 
						 | 
					86274842e9 | ||
| 
						 | 
					cf9c955a44 | ||
| 
						 | 
					55d828c35f | ||
| 
						 | 
					cdff28aca6 | ||
| 
						 | 
					b9da39274f | ||
| 
						 | 
					c379aa5782 | ||
| 
						 | 
					9dcabac9dd | ||
| 
						 | 
					794f3a2b9f | ||
| 
						 | 
					2066121b7c | ||
| 
						 | 
					0c4067f143 | ||
| 
						 | 
					8aa69243b7 | ||
| 
						 | 
					8697263bde | ||
| 
						 | 
					ea25c4f65c | ||
| 
						 | 
					82ac3ebd7e | ||
| 
						 | 
					13cb94909c | ||
| 
						 | 
					b57ca2a763 | ||
| 
						 | 
					83c49e9745 | ||
| 
						 | 
					e15771d78d | ||
| 
						 | 
					6edc4920ba | ||
| 
						 | 
					302bb1bd93 | ||
| 
						 | 
					529b1bceee | ||
| 
						 | 
					42cd47d32e | ||
| 
						 | 
					711d884c2e | ||
| 
						 | 
					183d1c4674 | ||
| 
						 | 
					faed63a0bb | ||
| 
						 | 
					53bff262f8 | ||
| 
						 | 
					3251a708e4 | ||
| 
						 | 
					b5dbdbf7b2 | ||
| 
						 | 
					a9649e92c9 | ||
| 
						 | 
					b561f1fa8b | ||
| 
						 | 
					cecd7491b5 | ||
| 
						 | 
					55a66322b5 | ||
| 
						 | 
					155c31a2d7 | ||
| 
						 | 
					a89ce91089 | ||
| 
						 | 
					b897fe6700 | ||
| 
						 | 
					548a351b06 | ||
| 
						 | 
					4b1da57ca1 | ||
| 
						 | 
					529aec7f25 | ||
| 
						 | 
					1661e545cb | ||
| 
						 | 
					ec71d08878 | ||
| 
						 | 
					ac258b7dd7 | ||
| 
						 | 
					0f57876233 | ||
| 
						 | 
					1d25a3693d | ||
| 
						 | 
					45fa428bf1 | ||
| 
						 | 
					177fa80f1a | ||
| 
						 | 
					3261261bfe | ||
| 
						 | 
					d4de7934f8 | ||
| 
						 | 
					c3475af809 | ||
| 
						 | 
					b12f707812 | ||
| 
						 | 
					22c0c34d60 | ||
| 
						 | 
					a60b66f230 | ||
| 
						 | 
					83f6e93628 | ||
| 
						 | 
					222b5f0229 | ||
| 
						 | 
					30aa383e26 | ||
| 
						 | 
					676b401294 | ||
| 
						 | 
					ebf57159de | ||
| 
						 | 
					199d2aafec | ||
| 
						 | 
					81952f56fd | ||
| 
						 | 
					c5bac82b43 | ||
| 
						 | 
					081b86109c | ||
| 
						 | 
					8ac2028a75 | ||
| 
						 | 
					264fed1c9f | ||
| 
						 | 
					dd59f7b2c7 | ||
| 
						 | 
					9245a760db | ||
| 
						 | 
					b61b32bbc3 | ||
| 
						 | 
					09b3914f5d | ||
| 
						 | 
					fe644e4c9e | ||
| 
						 | 
					7b09bf2156 | ||
| 
						 | 
					987d0aae66 | ||
| 
						 | 
					9cbcbc1c22 | ||
| 
						 | 
					cfc4e2bc60 | ||
| 
						 | 
					a03405fa81 | ||
| 
						 | 
					d5c9ccbe6e | ||
| 
						 | 
					e52772d65f | ||
| 
						 | 
					1e3259e728 | ||
| 
						 | 
					e905a20a60 | ||
| 
						 | 
					88e2be7a33 | ||
| 
						 | 
					8939131600 | ||
| 
						 | 
					ba37ebff8b | ||
| 
						 | 
					28f4cb7e07 | ||
| 
						 | 
					db1e7102cd | ||
| 
						 | 
					07eb7a5830 | ||
| 
						 | 
					b7c6c685fa | ||
| 
						 | 
					212134df70 | ||
| 
						 | 
					6eeb5528f5 | ||
| 
						 | 
					54fad845c9 | ||
| 
						 | 
					d6c0de6fc7 | ||
| 
						 | 
					649c8649f7 | ||
| 
						 | 
					da2f53d1b1 | ||
| 
						 | 
					405139e3b8 | ||
| 
						 | 
					4f8d347171 | ||
| 
						 | 
					bf0db4876c | ||
| 
						 | 
					47a14884d6 | ||
| 
						 | 
					3a7bbc8b08 | ||
| 
						 | 
					1b1d65372c | ||
| 
						 | 
					fd2faaa16e | ||
| 
						 | 
					0609cdb9ea | ||
| 
						 | 
					d3bb140f89 | ||
| 
						 | 
					b31dc66628 | ||
| 
						 | 
					09476171a6 | ||
| 
						 | 
					33dee813b5 | ||
| 
						 | 
					bb4e73c40b | ||
| 
						 | 
					b1f23ffa94 | ||
| 
						 | 
					b0e8cec1e7 | ||
| 
						 | 
					5077ae19bc | ||
| 
						 | 
					0d8447bf59 | ||
| 
						 | 
					c6cf08a274 | ||
| 
						 | 
					dc49ae519e | ||
| 
						 | 
					904539476a | ||
| 
						 | 
					3fbf02dc82 | ||
| 
						 | 
					c9392a840d | ||
| 
						 | 
					d164e8ab72 | ||
| 
						 | 
					6dc62c9fb6 | ||
| 
						 | 
					87a9684d66 | ||
| 
						 | 
					94525e2f44 | ||
| 
						 | 
					b408b1b3b9 | ||
| 
						 | 
					27c2f09e32 | ||
| 
						 | 
					19bc4d3349 | ||
| 
						 | 
					f2b6c424d6 | ||
| 
						 | 
					a49d4453e9 | ||
| 
						 | 
					65e50087b9 | ||
| 
						 | 
					2d90f759d9 | ||
| 
						 | 
					4230ac7674 | ||
| 
						 | 
					d96e9182e9 | ||
| 
						 | 
					68c87b9616 | ||
| 
						 | 
					7f8e9a0b6d | ||
| 
						 | 
					81a229f2a5 | ||
| 
						 | 
					8be7ae2733 | ||
| 
						 | 
					846bca4cb1 | ||
| 
						 | 
					f36f353789 | ||
| 
						 | 
					939a2731ed | ||
| 
						 | 
					835dab97ff | ||
| 
						 | 
					fa904b53be | ||
| 
						 | 
					0ec52dddce | ||
| 
						 | 
					c289355a3a | ||
| 
						 | 
					02a13a5a18 | ||
| 
						 | 
					6cf2a0281b | ||
| 
						 | 
					120d35f9af | ||
| 
						 | 
					2b15d5e7b3 | ||
| 
						 | 
					fc167bd3f0 | ||
| 
						 | 
					91b04abf05 | ||
| 
						 | 
					77faac8740 | ||
| 
						 | 
					43b3d54855 | ||
| 
						 | 
					69e9b85700 | ||
| 
						 | 
					0b6d132759 | ||
| 
						 | 
					7c233c6c0c | ||
| 
						 | 
					c35b290fa4 | ||
| 
						 | 
					3d95cfb367 | ||
| 
						 | 
					b90fc3a56e | ||
| 
						 | 
					1ef3fdccf5 | ||
| 
						 | 
					02b7f77bd8 | ||
| 
						 | 
					0ac7ead922 | ||
| 
						 | 
					da9d0e03ce | ||
| 
						 | 
					120f65f672 | ||
| 
						 | 
					200a14caa4 | ||
| 
						 | 
					35bf6da8e2 | ||
| 
						 | 
					f08f70276c | ||
| 
						 | 
					1ae50fd95b | ||
| 
						 | 
					40512beb47 | ||
| 
						 | 
					0d7f9b2c94 | ||
| 
						 | 
					52f42140a7 | ||
| 
						 | 
					3f6c50297f | ||
| 
						 | 
					f72d80afc5 | ||
| 
						 | 
					7c5cb13b22 | ||
| 
						 | 
					d728750eb2 | ||
| 
						 | 
					02a70e5667 | ||
| 
						 | 
					44e51ea5fa | ||
| 
						 | 
					87e201460a | ||
| 
						 | 
					039bd945e2 | ||
| 
						 | 
					e9e52d2b4b | ||
| 
						 | 
					2bf92e7399 | ||
| 
						 | 
					5b0df241f0 | ||
| 
						 | 
					76f5b05eff | ||
| 
						 | 
					40fb6c998f | ||
| 
						 | 
					33f50a342d | ||
| 
						 | 
					81523ab68a | ||
| 
						 | 
					2bf8cc62cf | ||
| 
						 | 
					1ae8247af3 | ||
| 
						 | 
					5ef32227ec | ||
| 
						 | 
					6456e773bd | ||
| 
						 | 
					234fe53ca3 | ||
| 
						 | 
					7c93e7a7b3 | ||
| 
						 | 
					8afc6c7f4b | ||
| 
						 | 
					4609d0fa3a | ||
| 
						 | 
					d452c035c6 | ||
| 
						 | 
					45113c8f5a | ||
| 
						 | 
					0acdd3c62b | ||
| 
						 | 
					96d7d0a33e | ||
| 
						 | 
					b6b280267b | ||
| 
						 | 
					6e6d253b1a | ||
| 
						 | 
					d92c105db2 | ||
| 
						 | 
					906db728d6 | ||
| 
						 | 
					c4b7411565 | ||
| 
						 | 
					de06396046 | ||
| 
						 | 
					ee6bfeb8e3 | ||
| 
						 | 
					058347321f | ||
| 
						 | 
					feefe49324 | ||
| 
						 | 
					187381a9a2 | ||
| 
						 | 
					993dfa4368 | ||
| 
						 | 
					7e35a16440 | ||
| 
						 | 
					e4eeb15926 | ||
| 
						 | 
					634e0db26d | ||
| 
						 | 
					56855c23e1 | ||
| 
						 | 
					0b00f742e3 | ||
| 
						 | 
					b7ab3f673c | ||
| 
						 | 
					be04ea1e35 | ||
| 
						 | 
					1f8e695802 | ||
| 
						 | 
					2d82b2c64f | ||
| 
						 | 
					d076caf473 | ||
| 
						 | 
					c7abdefa31 | ||
| 
						 | 
					ba772c0bca | ||
| 
						 | 
					5bad234119 | ||
| 
						 | 
					c7e7baaf23 | ||
| 
						 | 
					36658a671b | ||
| 
						 | 
					045f2e10ba | ||
| 
						 | 
					fb5a7db66d | ||
| 
						 | 
					ba7d33982e | ||
| 
						 | 
					c62279a755 | ||
| 
						 | 
					17fa1a7ffb | ||
| 
						 | 
					e89ceac351 | ||
| 
						 | 
					0b8c30c109 | ||
| 
						 | 
					9ab0f463cc | ||
| 
						 | 
					6433dda7b8 | ||
| 
						 | 
					fa7a2f4be4 | ||
| 
						 | 
					ba90e16505 | ||
| 
						 | 
					008f710203 | ||
| 
						 | 
					df2740f126 | ||
| 
						 | 
					2db89d143e | ||
| 
						 | 
					0525d49da3 | ||
| 
						 | 
					e2b0745882 | ||
| 
						 | 
					92e804fc50 | ||
| 
						 | 
					67abf45576 | ||
| 
						 | 
					d2c9c814e7 | ||
| 
						 | 
					22f8881a64 | ||
| 
						 | 
					4ab20322fe | ||
| 
						 | 
					5370eeecea | ||
| 
						 | 
					ba71cb5dd7 | ||
| 
						 | 
					9aad6c2c52 | ||
| 
						 | 
					4d9627f20c | ||
| 
						 | 
					c142492e91 | ||
| 
						 | 
					6bf8d9e207 | ||
| 
						 | 
					4f9a6168c1 | ||
| 
						 | 
					38397f99aa | ||
| 
						 | 
					f8686d0e75 | ||
| 
						 | 
					549e3c8f9d | ||
| 
						 | 
					bb56225b95 | ||
| 
						 | 
					f00be261ba | ||
| 
						 | 
					9cd94f26d0 | ||
| 
						 | 
					4d8f5c80a7 | ||
| 
						 | 
					24a23acc3d | ||
| 
						 | 
					ca8703cfd8 | ||
| 
						 | 
					6dcbb5b2f8 | ||
| 
						 | 
					a84fdddb2a | ||
| 
						 | 
					38bb2f8ceb | ||
| 
						 | 
					23f5ef4345 | ||
| 
						 | 
					ef8a2a9054 | ||
| 
						 | 
					96103d0e36 | ||
| 
						 | 
					ff5f6748df | ||
| 
						 | 
					1c1fd6c366 | ||
| 
						 | 
					32d37d00cb | ||
| 
						 | 
					82f6cda966 | ||
| 
						 | 
					f1ff8ff0d0 | ||
| 
						 | 
					756c72902f | ||
| 
						 | 
					73f8f0bbd0 | ||
| 
						 | 
					18ed528f5d | ||
| 
						 | 
					8fd2f136bc | ||
| 
						 | 
					0524b1bf67 | ||
| 
						 | 
					15716f65ce | ||
| 
						 | 
					d46bdba332 | ||
| 
						 | 
					760728110a | ||
| 
						 | 
					12d0a194ca | ||
| 
						 | 
					4104543508 | ||
| 
						 | 
					5c211db015 | ||
| 
						 | 
					2dc6180f8d | ||
| 
						 | 
					e222a34b69 | ||
| 
						 | 
					ef17d95063 | ||
| 
						 | 
					853502e5d7 | ||
| 
						 | 
					c18e297e77 | ||
| 
						 | 
					c5a49599ba | ||
| 
						 | 
					df9da9edf5 | ||
| 
						 | 
					e2200fd050 | ||
| 
						 | 
					c6207f5d9c | ||
| 
						 | 
					4302b7ff6b | ||
| 
						 | 
					50a7923438 | ||
| 
						 | 
					ab416445c8 | ||
| 
						 | 
					a54698d43c | ||
| 
						 | 
					c5a77cc1c0 | ||
| 
						 | 
					a9ffa811fc | ||
| 
						 | 
					080a2608e0 | ||
| 
						 | 
					57f2e83d6a | ||
| 
						 | 
					5b030139d3 | ||
| 
						 | 
					0da1ff42d1 | ||
| 
						 | 
					2c599b7baa | ||
| 
						 | 
					5c8af8d21a | ||
| 
						 | 
					026f3cfde2 | ||
| 
						 | 
					f6349180e8 | ||
| 
						 | 
					aa6421921c | ||
| 
						 | 
					7d41d2dab2 | ||
| 
						 | 
					f0b4d18f93 | ||
| 
						 | 
					6750f06e10 | ||
| 
						 | 
					b2bd38fa9e | ||
| 
						 | 
					3482a01e22 | ||
| 
						 | 
					6335467552 | ||
| 
						 | 
					4a39e65b62 | ||
| 
						 | 
					c50a23e918 | ||
| 
						 | 
					1e76b72b98 | ||
| 
						 | 
					b94cf39eef | ||
| 
						 | 
					fef254ffff | ||
| 
						 | 
					e5495863a2 | ||
| 
						 | 
					3b4df2abf0 | ||
| 
						 | 
					aef2aee6a4 | ||
| 
						 | 
					d0d9519149 | ||
| 
						 | 
					685df1d2c5 | ||
| 
						 | 
					08e6b6f2e7 | ||
| 
						 | 
					66c887d0f3 | ||
| 
						 | 
					22e9960697 | ||
| 
						 | 
					64aa6e1f2d | ||
| 
						 | 
					7a93ed9d04 | ||
| 
						 | 
					a905e922e9 | ||
| 
						 | 
					f9f08fc720 | ||
| 
						 | 
					8d402d76d0 | ||
| 
						 | 
					46fda6281c | ||
| 
						 | 
					a14dbe1ea6 | ||
| 
						 | 
					18810a4c16 | ||
| 
						 | 
					147bc80dba | ||
| 
						 | 
					c7a484195a | ||
| 
						 | 
					4968eb6503 | ||
| 
						 | 
					a6f2d698a9 | ||
| 
						 | 
					ea5ed93ea5 | ||
| 
						 | 
					e1140134c6 | ||
| 
						 | 
					5ed11e012e | ||
| 
						 | 
					5380bd39ca | ||
| 
						 | 
					2ee2685688 | ||
| 
						 | 
					782002245b | ||
| 
						 | 
					7fc0905843 | ||
| 
						 | 
					72ecb99e54 | ||
| 
						 | 
					c863507d08 | ||
| 
						 | 
					cff86c9093 | ||
| 
						 | 
					0479dfcc54 | ||
| 
						 | 
					68dd67f21c | ||
| 
						 | 
					540f6858b5 | ||
| 
						 | 
					b61e791a4f | ||
| 
						 | 
					d0986f9482 | ||
| 
						 | 
					112cb0dc28 | ||
| 
						 | 
					0d3d7fdcf2 | ||
| 
						 | 
					5d6b89ef3b | ||
| 
						 | 
					ed0b26c09e | ||
| 
						 | 
					ae292bd920 | ||
| 
						 | 
					6c85a90723 | ||
| 
						 | 
					852592066c | ||
| 
						 | 
					96e1bc9b44 | ||
| 
						 | 
					b41d81ed31 | ||
| 
						 | 
					e241ec2244 | ||
| 
						 | 
					16e1f1a94c | ||
| 
						 | 
					7a68c42b26 | ||
| 
						 | 
					37ccc2e118 | ||
| 
						 | 
					4192fe1ab2 | ||
| 
						 | 
					d5c743d7bb | ||
| 
						 | 
					11814d63e8 | ||
| 
						 | 
					b753656d50 | ||
| 
						 | 
					f7e87611fc | ||
| 
						 | 
					1fb0e1900e | ||
| 
						 | 
					954a9731e0 | ||
| 
						 | 
					65c3364ad8 | ||
| 
						 | 
					3d72b7dccc | ||
| 
						 | 
					13ee569f06 | ||
| 
						 | 
					d79ef23a75 | ||
| 
						 | 
					5d0797d4ba | ||
| 
						 | 
					47a8d7475f | ||
| 
						 | 
					4939053121 | ||
| 
						 | 
					b525bf554e | ||
| 
						 | 
					f00285d2b2 | ||
| 
						 | 
					040f8d6eda | ||
| 
						 | 
					66d905325c | ||
| 
						 | 
					8b0cd95e73 | ||
| 
						 | 
					d867cca6d9 | ||
| 
						 | 
					a28f736369 | ||
| 
						 | 
					5c3a71cc59 | ||
| 
						 | 
					cef6dadb08 | ||
| 
						 | 
					36be817a3e | ||
| 
						 | 
					02f571f081 | ||
| 
						 | 
					157159e487 | ||
| 
						 | 
					02ada9f800 | ||
| 
						 | 
					6fcf9a97bb | ||
| 
						 | 
					17a5d8799f | ||
| 
						 | 
					31f3fe7a22 | ||
| 
						 | 
					89e46d3d83 | ||
| 
						 | 
					885795e67d | ||
| 
						 | 
					92bfb53dd4 | ||
| 
						 | 
					4cecbeb115 | ||
| 
						 | 
					5971480f55 | ||
| 
						 | 
					05bebea511 | ||
| 
						 | 
					76fa6c5cfb | ||
| 
						 | 
					633b68b518 | ||
| 
						 | 
					6913d8e995 | ||
| 
						 | 
					f3654e6f8d | ||
| 
						 | 
					d685dbcf22 | ||
| 
						 | 
					6a57fa079e | ||
| 
						 | 
					0a91d145ba | ||
| 
						 | 
					c2866e799d | ||
| 
						 | 
					d8cffcaae7 | ||
| 
						 | 
					30abca7be2 | ||
| 
						 | 
					edce87f3fb | ||
| 
						 | 
					66bac98fc2 | ||
| 
						 | 
					59156de92b | ||
| 
						 | 
					e0d7d10600 | ||
| 
						 | 
					daaf862257 | ||
| 
						 | 
					9de53d4b59 | ||
| 
						 | 
					f1571e2d46 | ||
| 
						 | 
					bd28d06298 | ||
| 
						 | 
					a24e4655eb | ||
| 
						 | 
					20a6c8d8e5 | ||
| 
						 | 
					98d264faf4 | ||
| 
						 | 
					321902a9b5 | ||
| 
						 | 
					8df5d06f9a | ||
| 
						 | 
					e69ea529cc | ||
| 
						 | 
					15405b1119 | ||
| 
						 | 
					d2f97ce2da | ||
| 
						 | 
					543ca631e9 | ||
| 
						 | 
					f184886db1 | ||
| 
						 | 
					8432ab4324 | ||
| 
						 | 
					6c05b37ca3 | ||
| 
						 | 
					35f4beeb47 | ||
| 
						 | 
					cbad7caa68 | ||
| 
						 | 
					b0388a4012 | ||
| 
						 | 
					df3fab4d55 | ||
| 
						 | 
					da49f88a03 | ||
| 
						 | 
					e28feceb06 | ||
| 
						 | 
					50496a164d | ||
| 
						 | 
					6f1dce1572 | ||
| 
						 | 
					6847776ae7 | ||
| 
						 | 
					67bd53bdd8 | ||
| 
						 | 
					e735abfdfd | ||
| 
						 | 
					1de93a2d6d | ||
| 
						 | 
					36f9e7c742 | ||
| 
						 | 
					9462763bbb | ||
| 
						 | 
					4ae0880ea6 | ||
| 
						 | 
					6ae2b6c835 | ||
| 
						 | 
					a0f180fd48 | ||
| 
						 | 
					bf1cf89914 | ||
| 
						 | 
					297a047fb4 | ||
| 
						 | 
					52ffc15ffc | ||
| 
						 | 
					e478c9c693 | ||
| 
						 | 
					d004f28074 | ||
| 
						 | 
					bc68ed8b1d | ||
| 
						 | 
					04555ae650 | ||
| 
						 | 
					e8f62085be | ||
| 
						 | 
					f430bffe2a | ||
| 
						 | 
					1f0520634f | ||
| 
						 | 
					902d4c31fb | ||
| 
						 | 
					17364ac09f | ||
| 
						 | 
					0b889f8f81 | ||
| 
						 | 
					40e349ff35 | ||
| 
						 | 
					c943b1b1df | ||
| 
						 | 
					912bc1d4e1 | ||
| 
						 | 
					cacb1533a3 | ||
| 
						 | 
					f0feaca9d7 | ||
| 
						 | 
					b6656f171b | ||
| 
						 | 
					6206ab3931 | ||
| 
						 | 
					c35fc58b1f | ||
| 
						 | 
					deed8abed7 | ||
| 
						 | 
					7151ad23f0 | ||
| 
						 | 
					0166d938af | ||
| 
						 | 
					6194aeddb0 | ||
| 
						 | 
					903dbf2c30 | ||
| 
						 | 
					9380f9ff57 | ||
| 
						 | 
					259ed95486 | ||
| 
						 | 
					2ebc92681e | ||
| 
						 | 
					195a1ffe13 | ||
| 
						 | 
					a8c2978185 | ||
| 
						 | 
					140f97a457 | ||
| 
						 | 
					7f94445a1e | ||
| 
						 | 
					82a89aec65 | ||
| 
						 | 
					7e95110232 | ||
| 
						 | 
					ec4aaaad89 | ||
| 
						 | 
					1b790fde24 | ||
| 
						 | 
					aaccea731e | ||
| 
						 | 
					29e31d7610 | ||
| 
						 | 
					aa51f4a98f | ||
| 
						 | 
					e6ccd12f00 | ||
| 
						 | 
					b134315df1 | ||
| 
						 | 
					7f34dffa13 | ||
| 
						 | 
					fa239e78c9 | ||
| 
						 | 
					707a6c4d6a | ||
| 
						 | 
					e5da303b43 | ||
| 
						 | 
					84ccd66331 | ||
| 
						 | 
					ad8cc2baea | ||
| 
						 | 
					7c4cf70309 | ||
| 
						 | 
					c3211e9b4f | ||
| 
						 | 
					268d94c983 | ||
| 
						 | 
					0bcacbba58 | ||
| 
						 | 
					8cdc26add9 | ||
| 
						 | 
					e0b2238886 | ||
| 
						 | 
					369a2e4029 | ||
| 
						 | 
					c4089e3b51 | ||
| 
						 | 
					9e2e9bc5b8 | ||
| 
						 | 
					a9e44426ed | 
							
								
								
									
										27
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,27 +0,0 @@
 | 
			
		||||
*.5
 | 
			
		||||
*.8
 | 
			
		||||
*.a
 | 
			
		||||
*.d
 | 
			
		||||
*.o
 | 
			
		||||
*.pc
 | 
			
		||||
*.pot
 | 
			
		||||
*.so
 | 
			
		||||
*.so.*
 | 
			
		||||
*.swp
 | 
			
		||||
*~
 | 
			
		||||
 | 
			
		||||
.export.sym
 | 
			
		||||
.exported_symbols_generated
 | 
			
		||||
.gdb_history
 | 
			
		||||
 | 
			
		||||
Makefile
 | 
			
		||||
make.tmpl
 | 
			
		||||
 | 
			
		||||
configure.h
 | 
			
		||||
version.h
 | 
			
		||||
 | 
			
		||||
/autom4te.cache/
 | 
			
		||||
/config.log
 | 
			
		||||
/config.status
 | 
			
		||||
/cscope.out
 | 
			
		||||
/tmp/
 | 
			
		||||
							
								
								
									
										203
									
								
								COPYING.LIB
									
									
									
									
									
								
							
							
						
						
									
										203
									
								
								COPYING.LIB
									
									
									
									
									
								
							@@ -1,14 +1,14 @@
 | 
			
		||||
		  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
 | 
			
		||||
		  GNU LIBRARY GENERAL PUBLIC LICENSE
 | 
			
		||||
		       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1991 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.]
 | 
			
		||||
[This is the first released version of the library GPL.  It is
 | 
			
		||||
 numbered 2 because it goes with version 2 of the ordinary GPL.]
 | 
			
		||||
 | 
			
		||||
			    Preamble
 | 
			
		||||
 | 
			
		||||
@@ -17,109 +17,97 @@ 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.
 | 
			
		||||
  This license, the Library General Public License, applies to some
 | 
			
		||||
specially designated Free Software Foundation software, and to any
 | 
			
		||||
other libraries whose authors decide to use it.  You can use it for
 | 
			
		||||
your libraries, too.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
  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
 | 
			
		||||
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.
 | 
			
		||||
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 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
 | 
			
		||||
code.  If you link a program 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
 | 
			
		||||
  Our method of protecting your rights has two steps: (1) copyright
 | 
			
		||||
the library, and (2) 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.
 | 
			
		||||
  Also, for each distributor's protection, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
library.  If the library is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original
 | 
			
		||||
version, so that any problems introduced by others will not reflect on
 | 
			
		||||
the original authors' reputations.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that companies distributing free
 | 
			
		||||
software will individually obtain patent licenses, thus in effect
 | 
			
		||||
transforming the program into proprietary software.  To prevent this,
 | 
			
		||||
we have made it clear that any patent must be licensed for everyone's
 | 
			
		||||
free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
  Most GNU software, including some libraries, is covered by the ordinary
 | 
			
		||||
GNU General Public License, which was designed for utility programs.  This
 | 
			
		||||
license, the GNU Library General Public License, applies to certain
 | 
			
		||||
designated libraries.  This license is quite different from the ordinary
 | 
			
		||||
one; be sure to read it in full, and don't assume that anything in it is
 | 
			
		||||
the same as in the ordinary license.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
  The reason we have a separate public license for some libraries is that
 | 
			
		||||
they blur the distinction we usually make between modifying or adding to a
 | 
			
		||||
program and simply using it.  Linking a program with a library, without
 | 
			
		||||
changing the library, is in some sense simply using the library, and is
 | 
			
		||||
analogous to running a utility program or application program.  However, in
 | 
			
		||||
a textual and legal sense, the linked executable is a combined work, a
 | 
			
		||||
derivative of the original library, and the ordinary General Public License
 | 
			
		||||
treats it as such.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
  Because of this blurred distinction, using the ordinary General
 | 
			
		||||
Public License for libraries did not effectively promote software
 | 
			
		||||
sharing, because most developers did not use the libraries.  We
 | 
			
		||||
concluded that weaker conditions might promote sharing better.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
  However, unrestricted linking of non-free programs would deprive the
 | 
			
		||||
users of those programs of all benefit from the free status of the
 | 
			
		||||
libraries themselves.  This Library General Public License is intended to
 | 
			
		||||
permit developers of non-free programs to use free libraries, while
 | 
			
		||||
preserving your freedom as a user of such programs to change the free
 | 
			
		||||
libraries that are incorporated in them.  (We have not seen how to achieve
 | 
			
		||||
this as regards changes in header files, but we have achieved it as regards
 | 
			
		||||
changes in the actual functions of the Library.)  The hope is that this
 | 
			
		||||
will lead to faster development of free libraries.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
former contains code derived from the library, while the latter only
 | 
			
		||||
works together with the library.
 | 
			
		||||
 | 
			
		||||
  Note that it is possible for a library to be covered by the ordinary
 | 
			
		||||
General Public License rather than by this special one.
 | 
			
		||||
 | 
			
		||||
		  GNU LESSER GENERAL PUBLIC LICENSE
 | 
			
		||||
		  GNU LIBRARY 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".
 | 
			
		||||
  0. This License Agreement applies to any software library which
 | 
			
		||||
contains a notice placed by the copyright holder or other authorized
 | 
			
		||||
party saying it may be distributed under the terms of this Library
 | 
			
		||||
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
 | 
			
		||||
@@ -268,7 +256,7 @@ 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
 | 
			
		||||
  6. As an exception to the Sections above, you may also compile 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
 | 
			
		||||
@@ -295,31 +283,23 @@ of these things:
 | 
			
		||||
    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
 | 
			
		||||
    b) 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
 | 
			
		||||
    c) 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
 | 
			
		||||
    d) 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
 | 
			
		||||
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.
 | 
			
		||||
@@ -368,7 +348,7 @@ 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
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  11. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
@@ -411,7 +391,7 @@ 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.
 | 
			
		||||
versions of the Library 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.
 | 
			
		||||
 | 
			
		||||
@@ -457,7 +437,7 @@ DAMAGES.
 | 
			
		||||
 | 
			
		||||
		     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
           How to Apply These Terms to Your New Libraries
 | 
			
		||||
     Appendix: 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
 | 
			
		||||
@@ -474,18 +454,19 @@ convey the exclusion of warranty; and each file should have at least the
 | 
			
		||||
    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
 | 
			
		||||
    modify it under the terms of the GNU Library General Public
 | 
			
		||||
    License as published by the Free Software Foundation; either
 | 
			
		||||
    version 2.1 of the License, or (at your option) any later version.
 | 
			
		||||
    version 2 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.
 | 
			
		||||
    Library 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
 | 
			
		||||
    You should have received a copy of the GNU Library 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.
 | 
			
		||||
 | 
			
		||||
@@ -500,5 +481,3 @@ necessary.  Here is a sample; alter the names:
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
That's all there is to it!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								INSTALL
									
									
									
									
									
								
							@@ -1,30 +1,44 @@
 | 
			
		||||
Installation
 | 
			
		||||
============
 | 
			
		||||
LVM2 installation
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
1) Generate custom makefiles.
 | 
			
		||||
1) Install device-mapper
 | 
			
		||||
 | 
			
		||||
   Ensure the device-mapper has been installed on the machine.
 | 
			
		||||
 | 
			
		||||
   The device-mapper should be in the kernel (look for 'device-mapper'
 | 
			
		||||
   messages in the kernel logs) and /usr/include/libdevmapper.h 
 | 
			
		||||
   and libdevmapper.so should be present.
 | 
			
		||||
 | 
			
		||||
   The device-mapper is available from:
 | 
			
		||||
     ftp://ftp.sistina.com/pub/LVM2/device-mapper/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
2) Generate custom makefiles.
 | 
			
		||||
 | 
			
		||||
   Run the 'configure' script from the top directory.
 | 
			
		||||
 | 
			
		||||
   If you wish to use the built-in LVM2 shell and have GNU readline 
 | 
			
		||||
   installed (http://www.gnu.org/directory/readline.html) use:
 | 
			
		||||
     ./configure --enable-readline
 | 
			
		||||
 | 
			
		||||
   If you don't want to include the LVM1 backwards-compatibility code use:
 | 
			
		||||
     ./configure --with-lvm1=none 
 | 
			
		||||
 | 
			
		||||
   To separate the LVM1 support into a shared library loaded by lvm.conf use:
 | 
			
		||||
     ./configure --with-lvm1=shared
 | 
			
		||||
 | 
			
		||||
   Use ./configure --help to see other options.
 | 
			
		||||
 | 
			
		||||
2) Build and install.
 | 
			
		||||
3) Build and install LVM2.
 | 
			
		||||
 | 
			
		||||
   Run 'make' from the top directory to build everything you configured.
 | 
			
		||||
   Run 'make install' to build and install everything you configured.
 | 
			
		||||
   Run 'make install' from the top directory.
 | 
			
		||||
 | 
			
		||||
   If you only want the device-mapper libraries and tools use
 | 
			
		||||
   'make device-mapper' or 'make install_device-mapper'.
 | 
			
		||||
 | 
			
		||||
3) If using LVM2, create a configuration file.
 | 
			
		||||
4) Create a configuration file
 | 
			
		||||
 | 
			
		||||
   The tools will work fine without a configuration file being
 | 
			
		||||
   present, but you ought to review the example file in doc/example.conf.
 | 
			
		||||
   For example, specifying the devices that LVM2 is to use can
 | 
			
		||||
   make the tools run more efficiently - and avoid scanning /dev/cdrom!
 | 
			
		||||
 | 
			
		||||
Please also refer to the WHATS_NEW file and the manual pages for the 
 | 
			
		||||
individual commands.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										184
									
								
								Makefile.in
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								Makefile.in
									
									
									
									
									
								
							@@ -1,8 +1,8 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
@@ -14,181 +14,57 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
 | 
			
		||||
 | 
			
		||||
ifeq ("@UDEV_RULES@", "yes")
 | 
			
		||||
  SUBDIRS += udev
 | 
			
		||||
endif
 | 
			
		||||
SUBDIRS = doc include man scripts
 | 
			
		||||
 | 
			
		||||
ifeq ("@INTL@", "yes")
 | 
			
		||||
  SUBDIRS += po
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@APPLIB@", "yes")
 | 
			
		||||
  SUBDIRS += liblvm
 | 
			
		||||
SUBDIRS += lib tools daemons
 | 
			
		||||
 | 
			
		||||
ifeq ("@DMEVENTD@", "yes")
 | 
			
		||||
  SUBDIRS += dmeventd
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@PYTHON_BINDINGS@", "yes")
 | 
			
		||||
  SUBDIRS += python
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),clean)
 | 
			
		||||
  SUBDIRS += test
 | 
			
		||||
endif
 | 
			
		||||
# FIXME Should use intermediate Makefiles here!
 | 
			
		||||
ifeq ($(MAKECMDGOALS),distclean)
 | 
			
		||||
  SUBDIRS = conf include man test scripts \
 | 
			
		||||
    libdaemon lib tools daemons libdm \
 | 
			
		||||
    udev po liblvm python \
 | 
			
		||||
    unit-tests/datastruct unit-tests/mm unit-tests/regex
 | 
			
		||||
tools.distclean: test.distclean
 | 
			
		||||
  SUBDIRS += daemons/clvmd \
 | 
			
		||||
	     dmeventd \
 | 
			
		||||
	     lib/format1 \
 | 
			
		||||
	     lib/format_pool \
 | 
			
		||||
	     lib/locking \
 | 
			
		||||
	     lib/mirror \
 | 
			
		||||
	     lib/snapshot \
 | 
			
		||||
	     po \
 | 
			
		||||
	     test/mm test/device test/format1 test/regex test/filters
 | 
			
		||||
  DISTCLEAN_TARGETS += lib/misc/configure.h
 | 
			
		||||
endif
 | 
			
		||||
DISTCLEAN_DIRS += lcov_reports*
 | 
			
		||||
DISTCLEAN_TARGETS += config.cache config.log config.status make.tmpl
 | 
			
		||||
 | 
			
		||||
include make.tmpl
 | 
			
		||||
 | 
			
		||||
libdm: include
 | 
			
		||||
libdaemon: include
 | 
			
		||||
lib: libdm libdaemon
 | 
			
		||||
liblvm: lib
 | 
			
		||||
daemons: lib libdaemon tools
 | 
			
		||||
tools: lib libdaemon device-mapper
 | 
			
		||||
po: tools daemons
 | 
			
		||||
scripts: liblvm libdm
 | 
			
		||||
 | 
			
		||||
lib.device-mapper: include.device-mapper
 | 
			
		||||
libdm.device-mapper: include.device-mapper
 | 
			
		||||
liblvm.device-mapper: include.device-mapper
 | 
			
		||||
daemons.device-mapper: libdm.device-mapper
 | 
			
		||||
tools.device-mapper: libdm.device-mapper
 | 
			
		||||
scripts.device-mapper: include.device-mapper
 | 
			
		||||
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
 | 
			
		||||
daemons: lib
 | 
			
		||||
lib: include
 | 
			
		||||
tools: lib
 | 
			
		||||
dmeventd: tools
 | 
			
		||||
po: tools daemons dmeventd
 | 
			
		||||
 | 
			
		||||
ifeq ("@INTL@", "yes")
 | 
			
		||||
lib.pofile: include.pofile
 | 
			
		||||
tools.pofile: lib.pofile
 | 
			
		||||
daemons.pofile: lib.pofile
 | 
			
		||||
po.pofile: tools.pofile daemons.pofile
 | 
			
		||||
dmeventd.pofile: tools.pofile
 | 
			
		||||
po.pofile: tools.pofile daemons.pofile dmeventd.pofile
 | 
			
		||||
pofile: po.pofile
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@PYTHON_BINDINGS@", "yes")
 | 
			
		||||
python: liblvm
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ("$(CFLOW_CMD)", "")
 | 
			
		||||
tools.cflow: libdm.cflow lib.cflow
 | 
			
		||||
daemons.cflow: tools.cflow
 | 
			
		||||
cflow: include.cflow
 | 
			
		||||
ifneq ("@CFLOW_CMD@", "")
 | 
			
		||||
tools.cflow: lib.cflow
 | 
			
		||||
cflow: tools.cflow
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ("@CSCOPE_CMD@", "")
 | 
			
		||||
cscope.out:
 | 
			
		||||
	@CSCOPE_CMD@ -b -R -s$(top_srcdir)
 | 
			
		||||
cscope.out: tools
 | 
			
		||||
	@CSCOPE_CMD@ -b -R
 | 
			
		||||
all: cscope.out
 | 
			
		||||
endif
 | 
			
		||||
DISTCLEAN_TARGETS += cscope.out
 | 
			
		||||
 | 
			
		||||
check check_system check_cluster check_local check_lvmetad unit: all
 | 
			
		||||
	$(MAKE) -C test $(@)
 | 
			
		||||
 | 
			
		||||
conf.generate: tools
 | 
			
		||||
 | 
			
		||||
generate: conf.generate
 | 
			
		||||
	$(MAKE) -C conf generate
 | 
			
		||||
 | 
			
		||||
install_system_dirs:
 | 
			
		||||
	$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
 | 
			
		||||
	$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
 | 
			
		||||
	$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR)
 | 
			
		||||
	$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR)
 | 
			
		||||
	$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_LOCK_DIR)
 | 
			
		||||
	$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_RUN_DIR)
 | 
			
		||||
	$(INSTALL_ROOT_DATA) /dev/null $(DESTDIR)$(DEFAULT_CACHE_DIR)/.cache
 | 
			
		||||
 | 
			
		||||
install_initscripts: 
 | 
			
		||||
	$(MAKE) -C scripts install_initscripts
 | 
			
		||||
 | 
			
		||||
install_systemd_generators:
 | 
			
		||||
	$(MAKE) -C scripts install_systemd_generators
 | 
			
		||||
	$(MAKE) -C man install_systemd_generators
 | 
			
		||||
 | 
			
		||||
install_systemd_units:
 | 
			
		||||
	$(MAKE) -C scripts install_systemd_units
 | 
			
		||||
 | 
			
		||||
ifeq ("@PYTHON_BINDINGS@", "yes")
 | 
			
		||||
install_python_bindings:
 | 
			
		||||
	$(MAKE) -C liblvm/python install_python_bindings
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
install_tmpfiles_configuration:
 | 
			
		||||
	$(MAKE) -C scripts install_tmpfiles_configuration
 | 
			
		||||
 | 
			
		||||
LCOV_TRACES = libdm.info lib.info liblvm.info tools.info \
 | 
			
		||||
	libdaemon/client.info libdaemon/server.info \
 | 
			
		||||
	daemons/clvmd.info daemons/dmeventd.info \
 | 
			
		||||
	daemons/lvmetad.info
 | 
			
		||||
 | 
			
		||||
CLEAN_TARGETS += $(LCOV_TRACES)
 | 
			
		||||
 | 
			
		||||
ifneq ("$(LCOV)", "")
 | 
			
		||||
.PHONY: lcov-reset lcov lcov-dated $(LCOV_TRACES)
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),lcov-dated)
 | 
			
		||||
LCOV_REPORTS_DIR := lcov_reports-$(shell date +%Y%m%d%k%M%S)
 | 
			
		||||
lcov-dated: lcov
 | 
			
		||||
else
 | 
			
		||||
LCOV_REPORTS_DIR := lcov_reports
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
lcov-reset:
 | 
			
		||||
	$(LCOV) --zerocounters $(addprefix -d , $(basename $(LCOV_TRACES)))
 | 
			
		||||
 | 
			
		||||
# maybe use subdirs processing to create tracefiles...
 | 
			
		||||
$(LCOV_TRACES):
 | 
			
		||||
	$(LCOV) -b $(basename $@) -d $(basename $@) \
 | 
			
		||||
		--ignore-errors source -c -o - | $(SED) \
 | 
			
		||||
		-e "s/\(dmeventd_lvm.[ch]\)/plugins\/lvm2\/\1/" \
 | 
			
		||||
		-e "s/dmeventd_\(mirror\|snapshot\|thin\|raid\)\.c/plugins\/\1\/dmeventd_\1\.c/" \
 | 
			
		||||
		>$@
 | 
			
		||||
 | 
			
		||||
ifneq ("$(GENHTML)", "")
 | 
			
		||||
lcov: $(LCOV_TRACES)
 | 
			
		||||
	$(RM) -r $(LCOV_REPORTS_DIR)
 | 
			
		||||
	$(MKDIR_P) $(LCOV_REPORTS_DIR)
 | 
			
		||||
	for i in $(LCOV_TRACES); do \
 | 
			
		||||
		test -s $$i -a $$(wc -w <$$i) -ge 100 && lc="$$lc $$i"; \
 | 
			
		||||
	done; \
 | 
			
		||||
	test -z "$$lc" || $(GENHTML) -p @abs_top_builddir@ \
 | 
			
		||||
		-o $(LCOV_REPORTS_DIR) $$lc
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("$(TESTING)", "yes")
 | 
			
		||||
# testing and report generation
 | 
			
		||||
RUBY=ruby1.9 -Ireport-generators/lib -Ireport-generators/test
 | 
			
		||||
 | 
			
		||||
.PHONY: unit-test ruby-test test-programs
 | 
			
		||||
 | 
			
		||||
# FIXME: put dependencies on libdm and liblvm
 | 
			
		||||
# FIXME: Should be handled by Makefiles in subdirs, not here at top level.
 | 
			
		||||
test-programs:
 | 
			
		||||
	cd unit-tests/regex && $(MAKE)
 | 
			
		||||
	cd unit-tests/datastruct && $(MAKE)
 | 
			
		||||
	cd unit-tests/mm && $(MAKE)
 | 
			
		||||
 | 
			
		||||
unit-test: test-programs
 | 
			
		||||
	$(RUBY) report-generators/unit_test.rb $(shell find . -name TESTS)
 | 
			
		||||
	$(RUBY) report-generators/title_page.rb
 | 
			
		||||
 | 
			
		||||
memcheck: test-programs
 | 
			
		||||
	$(RUBY) report-generators/memcheck.rb $(shell find . -name TESTS)
 | 
			
		||||
	$(RUBY) report-generators/title_page.rb
 | 
			
		||||
 | 
			
		||||
ruby-test:
 | 
			
		||||
	$(RUBY) report-generators/test/ts.rb
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								README
									
									
									
									
									
								
							@@ -1,33 +1,23 @@
 | 
			
		||||
This tree contains the LVM2 and device-mapper tools and libraries.
 | 
			
		||||
This directory contains LVM2, the new version of the userland LVM
 | 
			
		||||
tools designed for the new device-mapper for the Linux kernel.
 | 
			
		||||
 | 
			
		||||
For more information about LVM2 read the changelog in the WHATS_NEW file.
 | 
			
		||||
The device-mapper needs to be installed before compiling these LVM2 tools.
 | 
			
		||||
 | 
			
		||||
For more information about LVM2 read the WHATS_NEW file.
 | 
			
		||||
Installation instructions are in INSTALL.
 | 
			
		||||
 | 
			
		||||
There is no warranty - see COPYING and COPYING.LIB.
 | 
			
		||||
 | 
			
		||||
Tarballs are available from:
 | 
			
		||||
  ftp://sources.redhat.com/pub/lvm2/
 | 
			
		||||
  ftp://sources.redhat.com/pub/dm/
 | 
			
		||||
 | 
			
		||||
The source code is stored in git:
 | 
			
		||||
  http://git.fedorahosted.org/git/lvm2.git
 | 
			
		||||
  git clone git://git.fedorahosted.org/git/lvm2.git
 | 
			
		||||
To access the CVS tree use:
 | 
			
		||||
  cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login
 | 
			
		||||
  CVS password: cvs
 | 
			
		||||
  cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 co LVM2
 | 
			
		||||
 | 
			
		||||
Mailing list for general discussion related to LVM2:
 | 
			
		||||
Mailing list for discussion/bug reports etc.
 | 
			
		||||
  linux-lvm@redhat.com
 | 
			
		||||
  Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
 | 
			
		||||
 | 
			
		||||
Mailing lists for LVM2 development, patches and commits:
 | 
			
		||||
  lvm-devel@redhat.com
 | 
			
		||||
  Subscribe from https://www.redhat.com/mailman/listinfo/lvm-devel
 | 
			
		||||
 | 
			
		||||
  lvm2-commits@lists.fedorahosted.org (Read-only archive of commits)
 | 
			
		||||
  Subscribe from https://fedorahosted.org/mailman/listinfo/lvm2-commits
 | 
			
		||||
 | 
			
		||||
Mailing list for device-mapper development, including kernel patches
 | 
			
		||||
and multipath-tools:
 | 
			
		||||
  dm-devel@redhat.com
 | 
			
		||||
  Subscribe from https://www.redhat.com/mailman/listinfo/dm-devel
 | 
			
		||||
 | 
			
		||||
The source code repository used until 7th June 2012 is accessible here:
 | 
			
		||||
  http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/?cvsroot=lvm2.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
1.02.96-git (2015-03-24)
 | 
			
		||||
							
								
								
									
										724
									
								
								WHATS_NEW_DM
									
									
									
									
									
								
							
							
						
						
									
										724
									
								
								WHATS_NEW_DM
									
									
									
									
									
								
							@@ -1,724 +1,15 @@
 | 
			
		||||
Version 1.02.96 - 
 | 
			
		||||
=================================
 | 
			
		||||
  Fix selection to not match if using reserved value in criteria with >,<,>=,<.
 | 
			
		||||
  Fix selection to not match reserved values for size fields if using >,<,>=,<.
 | 
			
		||||
  Include uuid or device number in log message after ioctl failure.
 | 
			
		||||
  Add DM_INTERNAL_SUSPEND_FLAG to dm-ioctl.h.
 | 
			
		||||
  Install blkdeactivate script and its man page with make install_device-mapper.
 | 
			
		||||
 | 
			
		||||
Version 1.02.95 - 15th March 2015
 | 
			
		||||
=================================
 | 
			
		||||
  Makefile regenerated.
 | 
			
		||||
 | 
			
		||||
Version 1.02.94 - 4th March 2015
 | 
			
		||||
Version 1.02.22 - 
 | 
			
		||||
================================
 | 
			
		||||
  Add dm_report_object_is_selected for generalized interface for report/select.
 | 
			
		||||
 | 
			
		||||
Version 1.02.93 - 21st January 2015
 | 
			
		||||
===================================
 | 
			
		||||
  Reduce severity of ioctl error message when dmeventd waitevent is interrupted.
 | 
			
		||||
  Report 'unknown version' when incompatible version numbers were not obtained.
 | 
			
		||||
  Report more info from thin pool status (out of data, metadata-ro, fail).
 | 
			
		||||
  Support error_if_no_space for thin pool target.
 | 
			
		||||
  Fix segfault while using selection with regex and unbuffered reporting.
 | 
			
		||||
  Add dm_report_compact_fields to remove empty fields from report output.
 | 
			
		||||
  Remove unimplemented dm_report_set_output_selection from libdevmapper.h.
 | 
			
		||||
 | 
			
		||||
Version 1.02.92 - 24th November 2014
 | 
			
		||||
====================================
 | 
			
		||||
  Fix memory corruption with sorting empty string lists (1.02.86).
 | 
			
		||||
  Fix man dmsetup.8 syntax warning of Groff
 | 
			
		||||
  Accept unquoted strings and / in place of {} when parsing configs.
 | 
			
		||||
 | 
			
		||||
Version 1.02.91 - 11th November 2014
 | 
			
		||||
====================================
 | 
			
		||||
  Update cache creation and dm_config_node to pass policy.
 | 
			
		||||
  Allow activation of any thin-pool if transaction_id supplied is 0.
 | 
			
		||||
  Don't print uninitialized stack bytes when non-root uses dm_check_version().
 | 
			
		||||
  Fix selection criteria to not match reserved values when using >, <, >=, <.
 | 
			
		||||
  Add DM_LIST_HEAD_INIT macro to libdevmapper.h.
 | 
			
		||||
  Fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
 | 
			
		||||
 | 
			
		||||
Version 1.02.90 - 1st September 2014
 | 
			
		||||
====================================
 | 
			
		||||
  Restore proper buffer size for parsing mountinfo line (1.02.89)
 | 
			
		||||
 | 
			
		||||
Version 1.02.89 - 26th August 2014
 | 
			
		||||
==================================
 | 
			
		||||
  Improve libdevmapper-event select() error handling.
 | 
			
		||||
  Add extra check for matching transation_id after message submitting.
 | 
			
		||||
  Add dm_report_field_string_list_unsorted for str. list report without sorting.
 | 
			
		||||
  Support --deferred with dmsetup remove to defer removal of open devices.
 | 
			
		||||
  Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag.
 | 
			
		||||
  Add support for selection to match string list subset, recognize { } operator.
 | 
			
		||||
  Fix string list selection with '[value]' to not match list that's superset.
 | 
			
		||||
  Fix string list selection to match whole words only, not prefixes.
 | 
			
		||||
 | 
			
		||||
Version 1.02.88 - 5th August 2014
 | 
			
		||||
=================================
 | 
			
		||||
  Add dm_tree_set_optional_uuid_suffixes to handle upgrades.
 | 
			
		||||
 | 
			
		||||
Version 1.02.87 - 23rd July 2014
 | 
			
		||||
================================
 | 
			
		||||
  Fix dm_report_field_string_list to handle delimiter with multiple chars.
 | 
			
		||||
  Add dm_report_field_reserved_value for per-field reserved value definition.
 | 
			
		||||
 | 
			
		||||
Version 1.02.86 - 23rd June 2014
 | 
			
		||||
================================
 | 
			
		||||
  Make "help" and "?" reporting fields implicit.
 | 
			
		||||
  Recognize implicit "selected" field if using dm_report_init_with_selection.
 | 
			
		||||
  Add support for implicit reporting fields which are predefined in libdm.
 | 
			
		||||
  Add DM_REPORT_FIELD_TYPE_PERCENT: separate number and percent fields.
 | 
			
		||||
  Add dm_percent_range_t,dm_percent_to_float,dm_make_percent to libdm for reuse.
 | 
			
		||||
  Add dm_report_reserved_value to libdevmapper for reserved value definition.
 | 
			
		||||
  Also display field types when listing all fields in selection help.
 | 
			
		||||
  Recognize "help" keyword in selection string to show brief help for selection.
 | 
			
		||||
  Always order items reported as string list field lexicographically.
 | 
			
		||||
  Add dm_report_field_string_list to libdevmapper for direct string list report.
 | 
			
		||||
  Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields.
 | 
			
		||||
  Add dm_str_list to libdevmapper for string list type definition and its reuse.
 | 
			
		||||
  Add dmsetup -S/--select to define selection criteria for dmsetup reports.
 | 
			
		||||
  Add dm_report_init_with_selection to intialize report with selection criteria.
 | 
			
		||||
  Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields.
 | 
			
		||||
  Use RemoveOnStop for dm-event.socket systemd unit.
 | 
			
		||||
  Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page.
 | 
			
		||||
  Warn user about incorrect use of cookie with 'dmsetup remove --force'.
 | 
			
		||||
  Also recognize 'help'/'?' as reserved sort key name to show help.
 | 
			
		||||
  Add dm_units_to_factor for size unit parsing.
 | 
			
		||||
  Increase bitset size for minors for thin dmeventd plugin.
 | 
			
		||||
 | 
			
		||||
Version 1.02.85 - 10th April 2014
 | 
			
		||||
=================================
 | 
			
		||||
  Check for sprintf error when building internal device path.
 | 
			
		||||
  Check for sprintf error when creating path for dm control node.
 | 
			
		||||
  When buffer for dm_get_library_version() is too small, return error code.
 | 
			
		||||
  Always reinitialize _name_mangling_mode in dm_lib_init().
 | 
			
		||||
  Add tracking flag about implicitly added devices into dm_tree.
 | 
			
		||||
  Stop timeout thread immediately when the last worker thread is finished.
 | 
			
		||||
  Fix dmeventd logging with parallel wait event processing.
 | 
			
		||||
  Reuse _node_send_messages() for validation of transaction_id in preload.
 | 
			
		||||
  Transaction_id could be lower by one only when messages are prepared.
 | 
			
		||||
  Do not call callback when preload fails.
 | 
			
		||||
  Wrap is_selinux_enabled() to be called just once.
 | 
			
		||||
  Use correctly signed 64b constant when working with raid volumes.
 | 
			
		||||
  Exit dmeventd with pidfile cleanup instead of raising SIGKILL on DIE request.
 | 
			
		||||
  Add new DM_EVENT_GET_PARAMETERS request to dmeventd protocol.
 | 
			
		||||
  Do not use systemd's reload for dmeventd restart, use dmeventd -R instead.
 | 
			
		||||
  Drop cryptsetup rules from 10-dm.rules - cryptsetup >= 1.1.3 sets them.
 | 
			
		||||
 | 
			
		||||
Version 1.02.84 - 20th January 2014
 | 
			
		||||
===================================
 | 
			
		||||
  Revert activation of activated nodes if a node preload callback fails.
 | 
			
		||||
  Avoid busy looping on CPU when dmeventd reads event DM_WAIT_RETRY.
 | 
			
		||||
  Ensure global mutex is held when working with dmeventd thread.
 | 
			
		||||
  Drop taking timeout mutex for un/registering dmeventd monitor.
 | 
			
		||||
  Allow section names in config file data to be quoted strings.
 | 
			
		||||
  Close fifos before exiting in dmeventd restart() error path.
 | 
			
		||||
  Move printf format string directly into dm_asprintf args list.
 | 
			
		||||
  Catch invalid use of string sort values when reporting numerical fields.
 | 
			
		||||
 | 
			
		||||
Version 1.02.83 - 13th November 2013
 | 
			
		||||
====================================
 | 
			
		||||
  Consistently report on stderr when device is not found for dmsetup info.
 | 
			
		||||
  Skip race errors when non-udev dmsetup build runs on udev-enabled system.
 | 
			
		||||
  Skip error message when holders are not present in sysfs.
 | 
			
		||||
  Use __linux__ instead of linux define to make libdevmapper.h C compliant.
 | 
			
		||||
  Use mutex to avoid possible race while creating/destroying memory pools.
 | 
			
		||||
  Require libpthread to build now.
 | 
			
		||||
 | 
			
		||||
Version 1.02.82 - 4th October 2013
 | 
			
		||||
==================================
 | 
			
		||||
  Define symbolic names for subsystem udev flags in libdevmapper for easier use.
 | 
			
		||||
  Make subsystem udev rules responsible for importing DM_SUBSYSTEM_UDEV_FLAG*.
 | 
			
		||||
 | 
			
		||||
Version 1.02.81 - 23rd September 2013
 | 
			
		||||
=====================================
 | 
			
		||||
  Tidy dmeventd fifo initialisation.
 | 
			
		||||
 | 
			
		||||
Version 1.02.80 - 20th September 2013
 | 
			
		||||
=====================================
 | 
			
		||||
  Detect invalid sector supplied to 'dmsetup message'.
 | 
			
		||||
  Free any previously-set string if a dm_task_set_* function is called again.
 | 
			
		||||
  Do not allow passing empty new name for dmsetup rename.
 | 
			
		||||
  Display any output returned by 'dmsetup message'.
 | 
			
		||||
  Add dm_task_get_message_response to libdevmapper.
 | 
			
		||||
 | 
			
		||||
Version 1.02.79 - 13th August 2013
 | 
			
		||||
==================================
 | 
			
		||||
  Create dmeventd timeout threads as "detached" so exit status is freed.
 | 
			
		||||
  Add DM_ABORT_ON_INTERNAL_ERRORS env var support to abort on internal errors.
 | 
			
		||||
 | 
			
		||||
Version 1.02.78 - 24th July 2013
 | 
			
		||||
================================
 | 
			
		||||
  Process thin messages once to active thin pool target for dm_tree.
 | 
			
		||||
  Optimize out setting the same value or read_ahead.
 | 
			
		||||
  Add DM_ARRAY_SIZE public macro.
 | 
			
		||||
  Move syslog code out of signal handle in dmeventd.
 | 
			
		||||
  Add DM_TO_STRING public macro.
 | 
			
		||||
  Always return success on dmeventd -V command call.
 | 
			
		||||
  Fix parsing of 64bit snapshot status in dmeventd snapshot plugin.
 | 
			
		||||
  Add dm_get_status_snapshot() for parsing snapshot status.
 | 
			
		||||
  Detecte mounted fs also via reading /proc/self/mountinfo.
 | 
			
		||||
  Add dm_mountinfo_read() for parsing /proc/self/mountinfo.
 | 
			
		||||
  Report error for nonexisting devices in dmeventd communication.
 | 
			
		||||
  Prevent double free error after dmeventd call of _fill_device_data().
 | 
			
		||||
  Update dmevent structure message_data to simplify/fix error path handling.
 | 
			
		||||
  Validate passed params to dm_get_status_raid/thin/thin_pool(). 
 | 
			
		||||
  Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68).
 | 
			
		||||
  Add dm_config_write_{node_out/one_node_out} for enhanced config output.
 | 
			
		||||
  Add dm_config_value_is_bool to check for boolean value in supported formats.
 | 
			
		||||
  Fix config node lookup inside empty sections to not return the section itself.
 | 
			
		||||
  Append discards and read-only fields to exported struct dm_status_thin_pool.
 | 
			
		||||
  Fix segfault for truncated string token in config file after the first '"'.
 | 
			
		||||
  Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC).
 | 
			
		||||
  Fix resource leak in error path of dmeventd's umount of thin volume.
 | 
			
		||||
  Automatically deactivate failed preloaded dm tree node.
 | 
			
		||||
  Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only.
 | 
			
		||||
  Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled.
 | 
			
		||||
 | 
			
		||||
Version 1.02.77 - 15th October 2012
 | 
			
		||||
===================================
 | 
			
		||||
  Support unmount of thin volumes from pool above thin pool threshold.
 | 
			
		||||
  Update man page to reflect that dm UUIDs are being mangled as well.
 | 
			
		||||
  Apply 'dmsetup mangle' for dm UUIDs besides dm names.
 | 
			
		||||
  Add 'mangled_uuid' and 'unmangled_uuid' fields to dmsetup info -c -o.
 | 
			
		||||
  Mangle device UUID on dm_task_set_uuid/newuuid call if necessary.
 | 
			
		||||
  Add dm_task_get_uuid_mangled/unmangled to libdevmapper.
 | 
			
		||||
  Always reset delay_resume_if_new flag when stacking thin pool over anything.
 | 
			
		||||
  Don't create value for dm_config_node and require dm_config_create_value call.
 | 
			
		||||
  Check for existing new_name for dmsetup rename.
 | 
			
		||||
  Fix memory leak in dmsetup _get_split_name() error path.
 | 
			
		||||
 | 
			
		||||
Version 1.02.76 - 7th August 2012
 | 
			
		||||
=================================
 | 
			
		||||
  Add dm_vasprintf to libdevmapper.
 | 
			
		||||
  Allow --noflush with dmsetup status and wait (for thin target).
 | 
			
		||||
  Add dm_config_write_one_node to libdevmapper.
 | 
			
		||||
  Support thin pool message release/reserve_metadata_snap in libdevmapper.
 | 
			
		||||
  Support thin pool discards and external origin features in libdevmapper.
 | 
			
		||||
  Add configure --enable-udev-rule-exec-detection to detect exec path in rules.
 | 
			
		||||
  Use sbindir in udev rules by default and remove executable path detection.
 | 
			
		||||
  Remove hard-coded paths for dmeventd fifos and use default-dm-run-dir.
 | 
			
		||||
  Add configure --with-lvmetad-pidfile to remove hard-coded value.
 | 
			
		||||
  Add configure --with-default-pid-dir for common directory with pid files.
 | 
			
		||||
  Add configure --with-default-dm-run-dir to set run directory for dm tools.
 | 
			
		||||
  Detect kernel_send() errors in cmirrord.
 | 
			
		||||
  Add __attribute__ instrumentation to libdevmapper.h.
 | 
			
		||||
  Print clean_bits instead of sync_bits in pull_state in cmirrord.
 | 
			
		||||
  Add tests for errors from closedir(), close() in cmirrord.
 | 
			
		||||
  Add documentation references in systemd units.
 | 
			
		||||
  Remove veritysetup.  Now maintained with cryptsetup.
 | 
			
		||||
 | 
			
		||||
Version 1.02.75 - 8th June 2012
 | 
			
		||||
===============================
 | 
			
		||||
  Upstream source repo now fedorahosted.org git not sources.redhat.com CVS.
 | 
			
		||||
  Remove unsupported udev_get_dev_path libudev call used for checking udev dir.
 | 
			
		||||
  Set delay_resume_if_new on deptree snapshot origin.
 | 
			
		||||
  Log value chosen in _find_config_bool like other variable types do.
 | 
			
		||||
  Wait for dmeventd to exit after sending it DM_EVENT_CMD_DIE when restarting.
 | 
			
		||||
  Append 'Used' to {Blk}DevNames/DevNos dmsetup report headers for clarity.
 | 
			
		||||
  Add configure --with-veritysetup for independent veritysetup tool.
 | 
			
		||||
  Properly support supplied dmevent path in dm_event_register_handler().
 | 
			
		||||
  Remove dmeventd fifos on exit if they are not managed by systemd.
 | 
			
		||||
  Use SD_ACTIVATION environment variable in systemd units to detect systemd.
 | 
			
		||||
  Only start a new dmeventd instance on restart if one was already running.
 | 
			
		||||
  Extend the time waited for input from dmeventd fifo to 5 secs. (1.02.73)
 | 
			
		||||
 | 
			
		||||
Version 1.02.74 - 6th March 2012
 | 
			
		||||
================================
 | 
			
		||||
  Check for multiply-mangled names in auto mangling mode.
 | 
			
		||||
  Fix dm_task_get_name_unmangled to not unmangle already unmangled name.
 | 
			
		||||
  Check whether device names are properly mangled on ioctl return.
 | 
			
		||||
  Deactivation of failed thin check on thin pool returns success.
 | 
			
		||||
 | 
			
		||||
Version 1.02.73 - 3rd March 2012
 | 
			
		||||
================================
 | 
			
		||||
  Test _thread_registry list with holding mutex in dmeventd.
 | 
			
		||||
  Add dm_tree_node_set_callback() for preload and deactivation hooks.
 | 
			
		||||
  Drop unsupported TRIM message for thin pool.
 | 
			
		||||
  Improve logging for fifo startup in dmeventd.
 | 
			
		||||
  Better detection of missing dmeventd fifo connection (1.02.71).
 | 
			
		||||
  Add a few pointer validations in dmsetup.
 | 
			
		||||
  Support dm_task_get_driver_version() query without version string.
 | 
			
		||||
  Log failure of pthread_join when cleaning unused threads in dmeventd.
 | 
			
		||||
  Fix empty string warning logic in _find_config_str. (1.02.68)
 | 
			
		||||
  Fix dm_task_set_name to properly resolve path to dm name (1.02.71).
 | 
			
		||||
  Add dm_strncpy() function as a faster strncpy() replacement.
 | 
			
		||||
 | 
			
		||||
Version 1.02.72 - 23rd February 2012
 | 
			
		||||
====================================
 | 
			
		||||
  Avoid memory reallocation for dm_asprintf.
 | 
			
		||||
 | 
			
		||||
Version 1.02.71 - 20th February 2012
 | 
			
		||||
====================================
 | 
			
		||||
  Switch to using built-in blkid in 13-dm-disk.rules.
 | 
			
		||||
  Add "watch" rule to 13-dm-disk.rules.
 | 
			
		||||
  Detect failing fifo and skip 20s retry communication period.
 | 
			
		||||
  Add DM_DEFAULT_NAME_MANGLING_MODE environment variable as an override.
 | 
			
		||||
  Add dm_lib_init to automatically initialise device-mapper library on load.
 | 
			
		||||
  Replace any '\' char with '\\' in dm table specification on input.
 | 
			
		||||
  Add mangle command to dmsetup to provide renaming to correct mangled form.
 | 
			
		||||
  Add 'mangled_name' and 'unmangled_name' fields to dmsetup info -c -o.
 | 
			
		||||
  Add --manglename option to dmsetup to select the name mangling mode.
 | 
			
		||||
  Add dm_task_get_name_mangled/unmangled to libdevmapper.
 | 
			
		||||
  Mangle device name on dm_task_set_name/newname call if necessary.
 | 
			
		||||
  Add dm_set/get_name_mangling_mode to set/get name mangling in libdevmapper.
 | 
			
		||||
  Add configure --with-default-name-mangling for udev-friendly dev name charset.
 | 
			
		||||
  Test for parsed words in _umount() dmeventd snapshot plugin.
 | 
			
		||||
  Fix memory leak in fail path of parse_loop_device_name() in dmsetup.
 | 
			
		||||
  Check for missing reply_uuid in dm_event_get_registered_device().
 | 
			
		||||
  Check for allocation failure in dmeventd restart().
 | 
			
		||||
  Add few missing allocation failures tests in dmsetup.
 | 
			
		||||
  Fix potential risk of writing in front of buffer in _sysfs_get_dm_name().
 | 
			
		||||
 | 
			
		||||
Version 1.02.70 - 12th February 2012
 | 
			
		||||
====================================
 | 
			
		||||
  Fix dm_event_get_version() check.
 | 
			
		||||
  Add pointer test for dependency check in _add_dev().
 | 
			
		||||
  Validate name and uuid params of dm_tree_add_new_dev_with_udev_flags().
 | 
			
		||||
  Do not crash for dm_report_init() sort_key == NULL and behave like "".
 | 
			
		||||
  Return error for failing allocation in dm_asprintf().
 | 
			
		||||
  Add missing test for failing allocation in dm_realloc() code.
 | 
			
		||||
  Add test for memory allocation failures in regex matcher code.
 | 
			
		||||
  Simplify dm_task_set_geometry() and use dm_asprintf().
 | 
			
		||||
  Set all parameters to 0 for dm_get_next_target() for NULL return.
 | 
			
		||||
  Fix fd resource leak in error path for _udev_notify_sem_create().
 | 
			
		||||
  Leave space for '\0' for readline() call in _sysfs_get_kernel_name().
 | 
			
		||||
 | 
			
		||||
Version 1.02.69 - 1st February 2012
 | 
			
		||||
===================================
 | 
			
		||||
  Clean up dmeventd systemd unit ordering and requirements.
 | 
			
		||||
 | 
			
		||||
Version 1.02.68 - 26th January 2012
 | 
			
		||||
===================================
 | 
			
		||||
  Reset all members of info struct in dm_tree_add_new_dev_with_udev_flags.
 | 
			
		||||
  Add dmsetup wipe_table to replace table with one that uses error target.
 | 
			
		||||
  Add 'blkdevname' and 'blkdevs_used' fields to dmsetup info -c -o.
 | 
			
		||||
  Add 'blkdevname' option to dmsetup ls --tree to see block device names.
 | 
			
		||||
  Add -o devno/blkdevname/devname to dmsetup deps and ls.
 | 
			
		||||
  Add dm_device_get_name to get map name or block device name for given devno.
 | 
			
		||||
  Remove empty devices when clearing left-over inactive tables in deptree.
 | 
			
		||||
  Add dm_uuid_prefix/dm_set_uuid_prefix to override hard-coded LVM- prefix.
 | 
			
		||||
  Improve dmsetup man page description of readahead parameter.
 | 
			
		||||
  Use sysfs to set/get readahead if possible.
 | 
			
		||||
  Fix lvm2-monitor init script to use normalized output when using vgs.
 | 
			
		||||
  Add test for max length (DM_MAX_TYPE_NAME) of target type name.
 | 
			
		||||
  Include a copy of kernel DM documentation in doc/kernel.
 | 
			
		||||
  Improve man page style for dmsetup and mention more targets.
 | 
			
		||||
  Fix _get_proc_number to be tolerant of malformed /proc/misc entries.
 | 
			
		||||
  Fix missing thread list manipulation protection in dmeventd.
 | 
			
		||||
  Add ExecReload to dm-event.service for systemd to reload dmeventd properly.
 | 
			
		||||
  Add dm_config_tree_find_str_allow_empty and dm_config_find_str_allow_empty.
 | 
			
		||||
  Fix compile-time pool memory locking with DEBUG_MEM.
 | 
			
		||||
  Fix valgrind error reports in free of pool chunks with DEBUG_MEM.
 | 
			
		||||
  Align size of structure chunk for fast pool allocator to 8 bytes.
 | 
			
		||||
  Simplify some pointer operations in dm_free_aux() debug code.
 | 
			
		||||
  Remove unused dbg_malloc.h file from source tree.
 | 
			
		||||
  Cleanup backtraces for _create_and_load_v4().
 | 
			
		||||
  Fix alignment warning in bitcount calculation for raid segment.
 | 
			
		||||
  Allocate dm_tree structure from dm_tree pool.
 | 
			
		||||
  Update debug logging for _resume_node.
 | 
			
		||||
  Add functions to support thin provisioning target.
 | 
			
		||||
  Improve libdm-config error path reporting.
 | 
			
		||||
  Update dmsetup resume man with --addnodeonresume/create options.
 | 
			
		||||
  Add dependency for dm man pages to man subdirectory make all target.
 | 
			
		||||
  Add dm_tree_retry_remove to use retry logic for device removal in a dm_tree.
 | 
			
		||||
  Add dm_device_has_mounted_fs fn to check mounted filesystem on a device.
 | 
			
		||||
  Add dm_device_has_holders fn to to check use of the device by another device.
 | 
			
		||||
  Add dm_sysfs_dir to libdevmapper to retrieve sysfs location set.
 | 
			
		||||
  Add dm_set_sysfs_dir to libdevmapper to set sysfs location.
 | 
			
		||||
  Add --retry option for dmsetup remove to retry removal if not successful.
 | 
			
		||||
  Add dm_task_retry_remove fn to use retry logic for device removal.
 | 
			
		||||
  Remove unused passed parameters for _mirror_emit_segment_line().
 | 
			
		||||
  Add dm_config and string character escaping functions to libdevmapper.
 | 
			
		||||
  Mark unreleased memory pools as internal error.
 | 
			
		||||
 | 
			
		||||
Version 1.02.67 - 19th August 2011
 | 
			
		||||
==================================
 | 
			
		||||
  Add dm_tree_node_add_null_area for temporarily-missing raid devs tracked.
 | 
			
		||||
 | 
			
		||||
Version 1.02.66 - 12th August 2011
 | 
			
		||||
==================================
 | 
			
		||||
  Release geometry buffer in dm_task_destroy.
 | 
			
		||||
  Update udev rules to skip DM flags decoding for removed devices.
 | 
			
		||||
  Add compile-time pool memory locking options (to debug shared VG structs).
 | 
			
		||||
  Remove device name prefix from dmsetup line output if -j & -m or -u supplied.
 | 
			
		||||
  Remove support for the original version 1 dm ioctls.
 | 
			
		||||
  Add missing check for allocation failure _create_dir_recursive().
 | 
			
		||||
  Add support for systemd file descriptor handover in dmeventd.
 | 
			
		||||
  Fix memory leak in dmsetup _message() memory allocation error path.
 | 
			
		||||
  Use new oom killer adjustment interface (oom_score_adj) when available.
 | 
			
		||||
  Add systemd unit files for dmeventd.
 | 
			
		||||
  Fix read-only identical table reload supression.
 | 
			
		||||
 | 
			
		||||
Version 1.02.65 - 8th July 2011
 | 
			
		||||
===============================
 | 
			
		||||
  Remove dev name prefix from dmsetup line output if exactly one dev requested.
 | 
			
		||||
  Report internal error if suspending a device using an already-suspended dev.
 | 
			
		||||
  Report error if a table load requiring target parameters has none supplied.
 | 
			
		||||
  Add dmsetup --checks and dm_task_enable_checks framework to validate ioctls.
 | 
			
		||||
  Add age_in_minutes parameter to dmsetup udevcomplete_all.
 | 
			
		||||
  Return immediately from dm_lib_exit() if called more than once.
 | 
			
		||||
  Disable udev fallback by default and add --verifyudev option to dmsetup.
 | 
			
		||||
  Report internal error if any table is loaded while any dev is known suspended.
 | 
			
		||||
  Add dm_get_suspended_counter() for number of devs in suspended state by lib.
 | 
			
		||||
  Fix "all" report field prefix matching to include label fields with pv_all.
 | 
			
		||||
  Delay resuming new preloaded mirror devices with core logs in deptree code.
 | 
			
		||||
  Accept new kernel version 3 uname formats in initialisation.
 | 
			
		||||
 | 
			
		||||
Version 1.02.64 - 29th April 2011
 | 
			
		||||
==================================
 | 
			
		||||
  Require libudev >= 143 when compiling with udev support.
 | 
			
		||||
  Use word alignment for dm_pool_strdup() and dm_pool_strndup().
 | 
			
		||||
  Use dm_snprintf() to fix signedness warning in dm_set_dev_dir().
 | 
			
		||||
  Use unsigned loop counter to fix signedness warning in _other_node_ops().
 | 
			
		||||
  Fix const cast in dmsetup calls of dm_report_field_string().
 | 
			
		||||
  Streamline /dev/mapper/control node code for common cases.
 | 
			
		||||
  Use hard-coded dm control node device number for 2.6.36 kernels and above.
 | 
			
		||||
  Improve stack debug reporting in dm_task_create().
 | 
			
		||||
  Fallback to control node creation only if node doesn't exist yet.
 | 
			
		||||
  Change dm_hash binary functions to take void *key instead of char *.
 | 
			
		||||
  Fix uninitialised memory use with empty params in _reload_with_suppression_v4.
 | 
			
		||||
  Lower severity of selabel_lookup and matchpathcon failure to log_debug.
 | 
			
		||||
  Add test for failed allocation from dm_task_set_uuid() in dmeventd.
 | 
			
		||||
  Add dm_event_get_version to dmeventd for use with -R.
 | 
			
		||||
  Avoid dmeventd core dumps when handling request with unknown command ID.
 | 
			
		||||
  Have dmeventd -R start up even when no existing copy is running.
 | 
			
		||||
  Accept multiple mapped device names on many dmsetup command lines.
 | 
			
		||||
  Fix dm_udev_wait calls in dmsetup to occur before readahead display not after.
 | 
			
		||||
  Include an implicit dm_task_update_nodes() within dm_udev_wait().
 | 
			
		||||
  Fix _create_and_load_v4 not to lose the --addnodeoncreate setting (1.02.62).
 | 
			
		||||
  Add inactive table query support for kernel driver >= 4.11.6 (RHEL 5.7).
 | 
			
		||||
  Log debug open_count in _node_has_closed_parents().
 | 
			
		||||
  Add a const to dm_report_field_string() data parameter.
 | 
			
		||||
 | 
			
		||||
Version 1.02.63 - 9th February 2011
 | 
			
		||||
===================================
 | 
			
		||||
  Reinstate DEBUG_MEM as it's part of the API. (1.02.62)
 | 
			
		||||
 | 
			
		||||
Version 1.02.62 - 4th February 2011
 | 
			
		||||
===================================
 | 
			
		||||
  Add configure --with-device-nodes-on=create for previous behaviour.
 | 
			
		||||
  Move creation of device nodes from 'create' to 'resume'.
 | 
			
		||||
  Add --addnodeonresume and --addnodeoncreate options to dmsetup.
 | 
			
		||||
  Add dm_task_set_add_node to libdevmapper to control dev node creation time.
 | 
			
		||||
  Add dm_task_secure_data to libdevmapper to wipe ioctl buffers in kernel.
 | 
			
		||||
  Log debug message when expected uevent is not generated.
 | 
			
		||||
  Only compile memory debugging code when DEBUG_MEM is set.
 | 
			
		||||
  Set DM_UDEV_DISABLE_OTHER_RULES_FLAG for suspended DM devices in udev rules.
 | 
			
		||||
  Begin a new pool object for each row in _output_as_rows() correctly.
 | 
			
		||||
 | 
			
		||||
Version 1.02.61 - 10th January 2011
 | 
			
		||||
===================================
 | 
			
		||||
  Add DM_COOKIE_AUTO_CREATE to libdevmapper.h.
 | 
			
		||||
  Export DM_CONTROL_NODE_UMASK and use it while creating /dev/mapper/control.
 | 
			
		||||
 | 
			
		||||
Version 1.02.60 - 20th December 2010
 | 
			
		||||
====================================
 | 
			
		||||
  Check for unlink failure in remove_lockfile() in dmeventd.
 | 
			
		||||
  Use dm_free for dm_malloc-ed areas in _clog_ctr/_clog_dtr in cmirrord.
 | 
			
		||||
  Use char* arithmetic in _process_all() & _targets() in dmsetup.
 | 
			
		||||
  Change dm_regex_create() API to accept const char * const *patterns.
 | 
			
		||||
  Add new dm_prepare_selinux_context fn to libdevmapper and use it throughout.
 | 
			
		||||
  Detect existence of new SELinux selabel interface during configure.
 | 
			
		||||
 | 
			
		||||
Version 1.02.59 - 6th December 2010
 | 
			
		||||
===================================
 | 
			
		||||
  Add backtraces to _process_mapper_dir and  _create_and_load_v4 error paths.
 | 
			
		||||
  Remove superfluous checks for NULL before calling dm_free.
 | 
			
		||||
 | 
			
		||||
Version 1.02.58 - 22nd November 2010
 | 
			
		||||
====================================
 | 
			
		||||
  Fix _output_field crash from field_id free with DEBUG_MEM. (1.02.57)
 | 
			
		||||
 | 
			
		||||
Version 1.02.57 - 8th November 2010
 | 
			
		||||
===================================
 | 
			
		||||
  Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common.
 | 
			
		||||
  Add dmeventd -R to restart dmeventd without losing monitoring state. (1.02.56)
 | 
			
		||||
  Fix memory leak of field_id in _output_field function.
 | 
			
		||||
  Allocate buffer for reporting functions dynamically to support long outputs.
 | 
			
		||||
 | 
			
		||||
Version 1.02.56 - 25th October 2010
 | 
			
		||||
===================================
 | 
			
		||||
  Return const pointer from dm_basename() in libdevmapper.
 | 
			
		||||
  Implement dmeventd -R to restart without state loss.
 | 
			
		||||
  Add dm_zalloc and use it and dm_pool_zalloc throughout.
 | 
			
		||||
  Add --setuuid to dmsetup rename.
 | 
			
		||||
  Add dm_task_set_newuuid to set uuid of mapped device post-creation.
 | 
			
		||||
 | 
			
		||||
Version 1.02.55 - 24th September 2010
 | 
			
		||||
=====================================
 | 
			
		||||
  Fix the way regions are marked complete to avoid slow --nosync cmirror I/O.
 | 
			
		||||
  Add DM_REPORT_FIELD_TYPE_ID_LEN to libdevmapper.h.
 | 
			
		||||
 | 
			
		||||
Version 1.02.54 - 18th August 2010
 | 
			
		||||
==================================
 | 
			
		||||
  Fix dm-mod autoloading logic to not assume control node is set correctly.
 | 
			
		||||
  Add dmeventd/executable to lvm.conf to test alternative dmeventd.
 | 
			
		||||
  Export dm_event_handler_set_dmeventd_path to override built-in dmeventd path.
 | 
			
		||||
  Generate libdevmapper-event exported symbols.
 | 
			
		||||
  Remove superfluous NULL pointer tests before dm_free from dmeventd.
 | 
			
		||||
  Assume dm-mod autoloading support is in kernel 2.6.36 and higher, not 2.6.35.
 | 
			
		||||
  Fix udev rules to support udev database content generated by older rules.
 | 
			
		||||
  Reinstate detection of inappropriate uevent with DISK_RO set and suppress it.
 | 
			
		||||
  Fix regex ttree off-by-one error.
 | 
			
		||||
  Add --enable-valgrind-pool to configure.
 | 
			
		||||
  Fix segfault in regex matcher with characters of ordinal value > 127.
 | 
			
		||||
  Fix 'void*' arithmetic warnings in dbg_malloc.c and libdm-iface.c.
 | 
			
		||||
  Wait for node creation before displaying debug info in dmsetup.
 | 
			
		||||
  Fix return status 0 for "dmsetup info -c -o help".
 | 
			
		||||
  Add check for kernel semaphore support and disable udev_sync if not available.
 | 
			
		||||
 | 
			
		||||
Version 1.02.53 - 28th July 2010
 | 
			
		||||
================================
 | 
			
		||||
  Revert failed table load preparation after "create, load and resume".
 | 
			
		||||
  Switch dmeventd to use dm_create_lockfile and drop duplicate code.
 | 
			
		||||
  Add dm_create_lockfile to libdm to handle pidfiles for all daemons.
 | 
			
		||||
  Replace lookup with next in struct dfa_state & calculate states on demand.
 | 
			
		||||
  Improve the regex matcher, reducing the number of charset nodes used.
 | 
			
		||||
  Add dm_regex_fingerprint to facilitate regex testing.
 | 
			
		||||
  Skip ffs(0) in _test_word in bitset functions.
 | 
			
		||||
  Use "nowatch" udev rule for inappropriate devices.
 | 
			
		||||
 | 
			
		||||
Version 1.02.52 - 6th July 2010
 | 
			
		||||
===============================
 | 
			
		||||
  Fix dmlosetup snprintf %llu compiler warning.
 | 
			
		||||
  Add parentheses to some libdevmapper.h macro arguments.
 | 
			
		||||
  Add printf format attributes to dm_{sn,as}printf and fix a caller.
 | 
			
		||||
  Move dmeventd man page from install_lvm2 to install_device-mapper. (1.02.50)
 | 
			
		||||
 | 
			
		||||
Version 1.02.51 - 30th June 2010
 | 
			
		||||
================================
 | 
			
		||||
  Generate libdevmapper exported symbols from header file.
 | 
			
		||||
 | 
			
		||||
Version 1.02.50 - 23rd June 2010
 | 
			
		||||
================================
 | 
			
		||||
  Fix INTERNAL_ERROR typo in ioctl iface unknown task message.
 | 
			
		||||
  Fix udev rules to handle spurious events properly.
 | 
			
		||||
  Use C99 [] not [0] in dm_ulog_request struct to avoid abort when fortified.
 | 
			
		||||
  Allow use of devmapper header file in C++ mode (extern "C" and __typeof__).
 | 
			
		||||
  Add dmeventd man page.
 | 
			
		||||
 | 
			
		||||
Version 1.02.49 - 4th June 2010
 | 
			
		||||
===============================
 | 
			
		||||
  Support autoloading of dm-mod module for kernels from 2.6.35.
 | 
			
		||||
  Document 'clear' in dmsetup man page.
 | 
			
		||||
  Fix semctl parameter (union) to avoid misaligned parameter on some arches.
 | 
			
		||||
  Add dm_tree_node_set_presuspend_node() to presuspend child when deactivating.
 | 
			
		||||
  Initial support for replicator target.
 | 
			
		||||
 | 
			
		||||
Version 1.02.48 - 17th May 2010
 | 
			
		||||
================================
 | 
			
		||||
  Use -d to control level of messages sent to syslog by dmeventd.
 | 
			
		||||
  Change -d to -f to run dmeventd in foreground.
 | 
			
		||||
  Do not print encryption key in message debug output (cryptsetup luksResume).
 | 
			
		||||
  Fix dmeventd static build library dependencies.
 | 
			
		||||
  Fix udev flags on remove in create_and_load error path.
 | 
			
		||||
 | 
			
		||||
Version 1.02.47 - 30th April 2010
 | 
			
		||||
=================================
 | 
			
		||||
  Add support for new IMPORT{db} udev rule.
 | 
			
		||||
  Add DM_UDEV_PRIMARY_SOURCE_FLAG udev flag to recognize proper DM events.
 | 
			
		||||
  Also include udev libs in libdevmapper.pc when udev_sync is enabled.
 | 
			
		||||
  Cache bitset locations to speed up _calc_states.
 | 
			
		||||
  Add a regex optimisation pass for shared prefixes and suffixes.
 | 
			
		||||
  Add dm_bit_and and dm_bitset_equal to libdevmapper.
 | 
			
		||||
  Simplify dm_bitset_create.
 | 
			
		||||
  Speed up dm_bit_get_next with ffs().
 | 
			
		||||
 | 
			
		||||
Version 1.02.46 - 14th April 2010
 | 
			
		||||
=================================
 | 
			
		||||
  Change dm_tree_deactivate_children to fail if device is open.
 | 
			
		||||
  Wipe memory buffers for dm-ioctl parameters before releasing.
 | 
			
		||||
  Strictly require libudev if udev_sync is used.
 | 
			
		||||
  Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
 | 
			
		||||
 | 
			
		||||
Version 1.02.45 - 9th March 2010
 | 
			
		||||
================================
 | 
			
		||||
  Add --showkeys parameter description to dmsetup man page.
 | 
			
		||||
  Add --help option as synonym for help command.
 | 
			
		||||
 | 
			
		||||
Version 1.02.44 - 15th February 2010
 | 
			
		||||
====================================
 | 
			
		||||
  Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only.
 | 
			
		||||
  Export dm_udev_create_cookie function to create new cookies on demand.
 | 
			
		||||
  Add --udevcookie, udevcreatecookie and udevreleasecookie to dmsetup.
 | 
			
		||||
  Set udev state automatically instead of using DM_UDEV_DISABLE_CHECKING.
 | 
			
		||||
 | 
			
		||||
Version 1.02.43 - 21st January 2010
 | 
			
		||||
===================================
 | 
			
		||||
  Remove bitset, hash and pool headers superceded by libdevmapper.h.
 | 
			
		||||
  Fix off-by-one error causing bad cluster mirror table construction.
 | 
			
		||||
 | 
			
		||||
Version 1.02.42 - 14th January 2010
 | 
			
		||||
===================================
 | 
			
		||||
  Add support for the "snapshot-merge" kernel target (2.6.33-rc1).
 | 
			
		||||
  Introduce a third activation_priority level in dm_tree_activate_children.
 | 
			
		||||
 | 
			
		||||
Version 1.02.41 - 12th January 2010
 | 
			
		||||
===================================
 | 
			
		||||
  If DM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings.
 | 
			
		||||
  Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags.
 | 
			
		||||
  Add --noudevrules option for dmsetup to disable /dev node management by udev.
 | 
			
		||||
  Fix 'dmsetup info -c -o all' to show all fields.
 | 
			
		||||
  Return errors if dm_tree_*_children functions fail.
 | 
			
		||||
  Fix coredump and memory leak for 'dmsetup help -c'.
 | 
			
		||||
  Disable udev rules for change events with DISK_RO set.
 | 
			
		||||
 | 
			
		||||
Version 1.02.40 - 19th November 2009
 | 
			
		||||
====================================
 | 
			
		||||
  Fix install_device-mapper Makefile target to not build dmeventd plugins.
 | 
			
		||||
  Support udev flags even when udev_sync is disabled or not compiled in.
 | 
			
		||||
  Remove 'last_rule' from udev rules: honour DM_UDEV_DISABLE_OTHER_RULES_FLAG.
 | 
			
		||||
  Add dmsetup --inactive support.
 | 
			
		||||
  Add dm_task_query_inactive_table to libdevmapper for kernel driver >= 4.16.
 | 
			
		||||
  Fix hash lookup segfault when keys compared are different lengths.
 | 
			
		||||
 | 
			
		||||
Version 1.02.39 - 26th October 2009
 | 
			
		||||
===================================
 | 
			
		||||
  Remove strict default permissions for DM devices from 95-dm-notify.rules.
 | 
			
		||||
  Add dmsetup udevflags command to decode udev flags in given cookie value.
 | 
			
		||||
  Support udev flags in libdevmapper incl. dm_tree_add_new_dev_with_udev_flags.
 | 
			
		||||
  Make libdm ABI consistent when built with/without selinux support.
 | 
			
		||||
 | 
			
		||||
Version 1.02.38 - 25th September 2009
 | 
			
		||||
=====================================
 | 
			
		||||
  Export DM_DEV_DIR_UMASK, the default umask for /dev directories created.
 | 
			
		||||
  Handle any path supplied to dm_task_set_name by looking up in /dev/mapper.
 | 
			
		||||
  Add several examples to 12-dm-permissions.rules.
 | 
			
		||||
  Add splitname and --yes to dmsetup man page.
 | 
			
		||||
  Fix _mirror_emit_segment_line return code.
 | 
			
		||||
  Fix dmeventd _temporary_log_fn parameters. (2.02.50)
 | 
			
		||||
 | 
			
		||||
Version 1.02.37 - 15th September 2009
 | 
			
		||||
=====================================
 | 
			
		||||
  Add dmsetup manpage entries for udevcomplete_all and udevcookies.
 | 
			
		||||
  Check udev is running when processing cookies and retain state internally.
 | 
			
		||||
  Add y|--yes option to dmsetup for default 'yes' answer to prompts.
 | 
			
		||||
  Fix tools Makefile to process dmsetup sources separately.
 | 
			
		||||
  Restore umask when device node creation fails.
 | 
			
		||||
  Check kernel vsn to use 'block_on_error' or 'handle_errors' in mirror table.
 | 
			
		||||
  Add dm-log-userspace.h to tree for cmirrord builds.
 | 
			
		||||
 | 
			
		||||
Version 1.02.36 - 6th August 2009
 | 
			
		||||
=================================
 | 
			
		||||
  Add udevcookies, udevcomplete, udevcomplete_all and --noudevwait to dmsetup.
 | 
			
		||||
  Add libdevmapper functions to support synchronisation with udev.
 | 
			
		||||
 | 
			
		||||
Version 1.02.35 - 28th July 2009
 | 
			
		||||
================================
 | 
			
		||||
  Add LOG_LINE_WITH_ERRNO macro.
 | 
			
		||||
  Use log_error macro consistently throughout in place of log_err.
 | 
			
		||||
 | 
			
		||||
Version 1.02.34 - 15th July 2009
 | 
			
		||||
================================
 | 
			
		||||
  Use _exit() not exit() after forking to avoid flushing libc buffers twice.
 | 
			
		||||
  Rename plog macro to LOG_LINE & add LOG_MESG variant for dm_dump_memory_debug.
 | 
			
		||||
  Change plog to use dm_log_with_errno unless deprecated dm_log_init was used.
 | 
			
		||||
  Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old fns.
 | 
			
		||||
  Fix whitespace in linear target line to fix identical table line detection.
 | 
			
		||||
  Add device number to more log messages during activation.
 | 
			
		||||
 | 
			
		||||
Version 1.02.33 - 30th June 2009
 | 
			
		||||
================================
 | 
			
		||||
  Don't fallback to default major number: use dm_task_set_major_minor. (1.02.31)
 | 
			
		||||
  Do not fork daemon when dmeventd cannot be found.
 | 
			
		||||
  Add crypt target handling to libdevmapper tree nodes.
 | 
			
		||||
  Add splitname command to dmsetup.
 | 
			
		||||
  Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports.
 | 
			
		||||
  Make mempool optional in dm_split_lvm_name().
 | 
			
		||||
 | 
			
		||||
Version 1.02.32 - 21st May 2009
 | 
			
		||||
===============================
 | 
			
		||||
  Only generate libdevmapper.a when configured to link statically.
 | 
			
		||||
  Export dm_tree_node_size_changed() from libdevmapper.
 | 
			
		||||
  Propagate the table size_changed property up the dm device tree.
 | 
			
		||||
  Detect failure to free memory pools when releasing the library.
 | 
			
		||||
  Fix segfault when getopt processes dmsetup -U, -G and -M options.
 | 
			
		||||
 | 
			
		||||
Version 1.02.31 - 3rd March 2009
 | 
			
		||||
================================
 | 
			
		||||
  If kernel supports only one dm major number, use in place of any supplied.
 | 
			
		||||
 | 
			
		||||
Version 1.02.30 - 26th January 2009
 | 
			
		||||
====================================
 | 
			
		||||
  Add "all" field to reports expanding to all fields of report type.
 | 
			
		||||
  Enforce device name length and character limitations in libdm.
 | 
			
		||||
  Replace _dm_snprintf with EMIT_PARAMS macro for creating target lines.
 | 
			
		||||
 | 
			
		||||
Version 1.02.29 - 10th November 2008
 | 
			
		||||
====================================
 | 
			
		||||
  Merge device-mapper into the LVM2 tree.
 | 
			
		||||
  Split out dm-logging.h from log.h.
 | 
			
		||||
  Use lvm-types.h.
 | 
			
		||||
  Add usrsbindir to configure.
 | 
			
		||||
 | 
			
		||||
Version 1.02.28 - 18th September 2008
 | 
			
		||||
=====================================
 | 
			
		||||
  Only resume devices in dm_tree_preload_children if size changes.
 | 
			
		||||
  Extend deptree buffers so the largest possible device numbers fit.
 | 
			
		||||
  Generate versioned libdevmapper-event.so.
 | 
			
		||||
  Underline longer report help text headings.
 | 
			
		||||
 | 
			
		||||
Version 1.02.27 - 25th June 2008
 | 
			
		||||
================================
 | 
			
		||||
  Align struct memblock in dbg_malloc for sparc.
 | 
			
		||||
  Add --unquoted and --rows to dmsetup.
 | 
			
		||||
  Avoid compiler warning about cast in dmsetup.c's OFFSET_OF macro.
 | 
			
		||||
  Fix inverted no_flush debug message.
 | 
			
		||||
  Remove --enable-jobs from configure. (Set at runtime instead.)
 | 
			
		||||
  Bring configure.in and list.h into line with the lvm2 versions.
 | 
			
		||||
 | 
			
		||||
Version 1.02.26 - 6th June 2008
 | 
			
		||||
===============================
 | 
			
		||||
  Initialise params buffer to empty string in _emit_segment.
 | 
			
		||||
  Skip add_dev_node when ioctls disabled.
 | 
			
		||||
  Make dm_hash_iter safe against deletion.
 | 
			
		||||
  Accept a NULL pointer to dm_free silently.
 | 
			
		||||
  Add tables_loaded, readonly and suspended columns to reports.
 | 
			
		||||
  Add --nameprefixes to dmsetup.
 | 
			
		||||
  Add field name prefix option to reporting functions.
 | 
			
		||||
  Calculate string size within dm_pool_grow_object.
 | 
			
		||||
 | 
			
		||||
Version 1.02.25 - 10th April 2008
 | 
			
		||||
=================================
 | 
			
		||||
  Remove redundant if-before-free tests.
 | 
			
		||||
  Use log_warn for reporting field help text instead of log_print.
 | 
			
		||||
  Change cluster mirror log type name (s/clustered_/clustered-/)
 | 
			
		||||
 | 
			
		||||
Version 1.02.24 - 20th December 2007
 | 
			
		||||
====================================
 | 
			
		||||
  Fix deptree to pass new name to _resume_node after a rename.
 | 
			
		||||
  Suppress other node operations if node is deleted.
 | 
			
		||||
  Add node operation stack debug messages.
 | 
			
		||||
  Report error when empty device name passed to readahead functions.
 | 
			
		||||
  Fix minimum readahead debug message.
 | 
			
		||||
 | 
			
		||||
Version 1.02.23 - 5th December 2007
 | 
			
		||||
===================================
 | 
			
		||||
  Update dm-ioctl.h after removal of compat code.
 | 
			
		||||
  Add readahead support to libdevmapper and dmsetup.
 | 
			
		||||
  Fix double free in a libdevmapper-event error path.
 | 
			
		||||
  Fix configure --with-dmeventd-path substitution.
 | 
			
		||||
  Allow a DM_DEV_DIR environment variable to override /dev in dmsetup.
 | 
			
		||||
  Create a libdevmapper.so.$LIB_VERSION symlink within the build tree.
 | 
			
		||||
  Avoid static link failure with some SELinux libraries that require libpthread.
 | 
			
		||||
  Remove obsolete dmfs code from tree and update INSTALL.
 | 
			
		||||
 | 
			
		||||
Version 1.02.22 - 21st August 2007
 | 
			
		||||
==================================
 | 
			
		||||
  Fix inconsistent licence notices: executables are GPLv2; libraries LGPLv2.1.
 | 
			
		||||
  Update to use autoconf 2.61, while still supporting 2.57.
 | 
			
		||||
  Avoid repeated dm_task free on some dm_event_get_registered_device errors.
 | 
			
		||||
  Introduce log_sys_* macros from LVM2.
 | 
			
		||||
  Export dm_fclose and dm_create_dir; remove libdm-file.h.
 | 
			
		||||
  Don't log EROFS mkdir failures in _create_dir_recursive (for LVM2).
 | 
			
		||||
  Add fclose wrapper dm_fclose that catches write failures (using ferror).
 | 
			
		||||
  Export dm_create_dir (was create_dir) to help fix LVM2 link error
 | 
			
		||||
  Don't log mkdir fail-with-EROFS, to make create_dir equiv to the one in LVM2
 | 
			
		||||
  Introduce and use log_sys_* macros from LVM2
 | 
			
		||||
  dm_fclose: new function
 | 
			
		||||
  libdevmapper, dmeventd: be paranoid about detecting write failure
 | 
			
		||||
 | 
			
		||||
Version 1.02.21 - 13th July 2007
 | 
			
		||||
================================
 | 
			
		||||
  Introduce _LOG_STDERR to send log_warn() messages to stderr not stdout.
 | 
			
		||||
  Fix dmsetup -o devno string termination. (1.02.20)
 | 
			
		||||
  Fix dmsetup -o devno string termination. (1.02.20) 
 | 
			
		||||
 | 
			
		||||
Version 1.02.20 - 15th June 2007
 | 
			
		||||
================================
 | 
			
		||||
@@ -1006,3 +297,4 @@ Version 1.00.08 - 27 Feb 2004
 | 
			
		||||
  Fixed DESTDIR for make install/install_static_lib.
 | 
			
		||||
  Updated README/INSTALL to reflect move to sources.redhat.com.
 | 
			
		||||
  Updated autoconf files to 2003-06-17.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								acinclude.m4
									
									
									
									
									
								
							@@ -1,63 +0,0 @@
 | 
			
		||||
dnl AC_GCC_VERSION
 | 
			
		||||
dnl check for compiler version
 | 
			
		||||
dnl sets COMPILER_VERSION and GCC_VERSION
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AC_CC_VERSION],
 | 
			
		||||
[
 | 
			
		||||
    AC_MSG_CHECKING([C compiler version])
 | 
			
		||||
    COMPILER_VERSION=`$CC -v 2>&1 | grep version`
 | 
			
		||||
    case "$COMPILER_VERSION" in
 | 
			
		||||
        *gcc*)
 | 
			
		||||
	   dnl Ok, how to turn $3 into the real $3
 | 
			
		||||
	   GCC_VERSION=`echo $COMPILER_VERSION | \
 | 
			
		||||
	   sed -e 's/[[^ ]]*\ [[^ ]]*\ \([[^ ]]*\)\ .*/\1/'` ;;
 | 
			
		||||
	*) GCC_VERSION=unknown ;;
 | 
			
		||||
    esac
 | 
			
		||||
    AC_MSG_RESULT($GCC_VERSION)
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_TRY_CCFLAG([CCFLAG], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
 | 
			
		||||
dnl check if $CC supports a given flag
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AC_TRY_CCFLAG],
 | 
			
		||||
[
 | 
			
		||||
    AC_REQUIRE([AC_PROG_CC])
 | 
			
		||||
    ac_save_CFLAGS=$CFLAGS
 | 
			
		||||
    CFLAGS=$1
 | 
			
		||||
    AC_CACHE_CHECK([whether $CC accepts $1 flag], [ac_cv_flag_$2],
 | 
			
		||||
	[AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
 | 
			
		||||
			   [AS_VAR_SET([ac_cv_flag_$2], [yes])],
 | 
			
		||||
			   [AS_VAR_SET([ac_cv_flag_$2], [no])])])
 | 
			
		||||
    CFLAGS=$ac_save_CFLAGS
 | 
			
		||||
    $2=AS_VAR_GET([ac_cv_flag_$2])
 | 
			
		||||
    if test "$2" = yes; then
 | 
			
		||||
        ifelse([$3], [], [:], [$3])
 | 
			
		||||
    else
 | 
			
		||||
        ifelse([$4], [], [:], [$4])
 | 
			
		||||
    fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_IF_YES([TEST-FOR-YES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
 | 
			
		||||
dnl AS_IF() abstraction, checks shell variable for 'yes'
 | 
			
		||||
AC_DEFUN([AC_IF_YES], [AS_IF([test $$1 = yes], [$2], [$3])])
 | 
			
		||||
 | 
			
		||||
dnl AC_TRY_LDFLAGS([LDFLAGS], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
 | 
			
		||||
dnl check if $CC supports given ld flags
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AC_TRY_LDFLAGS],
 | 
			
		||||
[
 | 
			
		||||
    AC_REQUIRE([AC_PROG_CC])
 | 
			
		||||
    ac_save_LDFLAGS=$LDFLAGS
 | 
			
		||||
    LDFLAGS=$1
 | 
			
		||||
	AC_CACHE_CHECK([whether $CC accepts $1 ld flags], [ac_cv_flag_$2],
 | 
			
		||||
	[AC_LINK_IFELSE([AC_LANG_PROGRAM()],
 | 
			
		||||
			[AS_VAR_SET([ac_cv_flag_$2], [yes])],
 | 
			
		||||
			[AS_VAR_SET([ac_cv_flag_$2], [no])])])
 | 
			
		||||
    LDFLAGS=$ac_save_LDFLAGS
 | 
			
		||||
    $2=AS_VAR_GET([ac_cv_flag_$2])
 | 
			
		||||
    if test "$2" = yes; then
 | 
			
		||||
        ifelse([$3], [], [:], [$3])
 | 
			
		||||
    else
 | 
			
		||||
        ifelse([$4], [], [:], [$4])
 | 
			
		||||
    fi
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										230
									
								
								aclocal.m4
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										230
									
								
								aclocal.m4
									
									
									
									
										vendored
									
									
								
							@@ -1,230 +0,0 @@
 | 
			
		||||
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
# This file is free software; the Free Software Foundation
 | 
			
		||||
# gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
# with or without modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
 | 
			
		||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 | 
			
		||||
# PARTICULAR PURPOSE.
 | 
			
		||||
 | 
			
		||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 | 
			
		||||
# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
 | 
			
		||||
# serial 1 (pkg-config-0.24)
 | 
			
		||||
# 
 | 
			
		||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
 | 
			
		||||
#
 | 
			
		||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 | 
			
		||||
#
 | 
			
		||||
# As a special exception to the GNU General Public License, if you
 | 
			
		||||
# distribute this file as part of a program that contains a
 | 
			
		||||
# configuration script generated by Autoconf, you may include it under
 | 
			
		||||
# the same distribution terms that you use for the rest of that program.
 | 
			
		||||
 | 
			
		||||
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
 | 
			
		||||
# ----------------------------------
 | 
			
		||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
 | 
			
		||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
 | 
			
		||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
 | 
			
		||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
 | 
			
		||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
 | 
			
		||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
 | 
			
		||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
 | 
			
		||||
 | 
			
		||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
 | 
			
		||||
	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
 | 
			
		||||
fi
 | 
			
		||||
if test -n "$PKG_CONFIG"; then
 | 
			
		||||
	_pkg_min_version=m4_default([$1], [0.9.0])
 | 
			
		||||
	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
 | 
			
		||||
	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
 | 
			
		||||
		AC_MSG_RESULT([yes])
 | 
			
		||||
	else
 | 
			
		||||
		AC_MSG_RESULT([no])
 | 
			
		||||
		PKG_CONFIG=""
 | 
			
		||||
	fi
 | 
			
		||||
fi[]dnl
 | 
			
		||||
])# PKG_PROG_PKG_CONFIG
 | 
			
		||||
 | 
			
		||||
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
 | 
			
		||||
#
 | 
			
		||||
# Check to see whether a particular set of modules exists.  Similar
 | 
			
		||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
 | 
			
		||||
#
 | 
			
		||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
 | 
			
		||||
# only at the first occurence in configure.ac, so if the first place
 | 
			
		||||
# it's called might be skipped (such as if it is within an "if", you
 | 
			
		||||
# have to call PKG_CHECK_EXISTS manually
 | 
			
		||||
# --------------------------------------------------------------
 | 
			
		||||
AC_DEFUN([PKG_CHECK_EXISTS],
 | 
			
		||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
 | 
			
		||||
if test -n "$PKG_CONFIG" && \
 | 
			
		||||
    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
 | 
			
		||||
  m4_default([$2], [:])
 | 
			
		||||
m4_ifvaln([$3], [else
 | 
			
		||||
  $3])dnl
 | 
			
		||||
fi])
 | 
			
		||||
 | 
			
		||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
 | 
			
		||||
# ---------------------------------------------
 | 
			
		||||
m4_define([_PKG_CONFIG],
 | 
			
		||||
[if test -n "$$1"; then
 | 
			
		||||
    pkg_cv_[]$1="$$1"
 | 
			
		||||
 elif test -n "$PKG_CONFIG"; then
 | 
			
		||||
    PKG_CHECK_EXISTS([$3],
 | 
			
		||||
                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
 | 
			
		||||
		      test "x$?" != "x0" && pkg_failed=yes ],
 | 
			
		||||
		     [pkg_failed=yes])
 | 
			
		||||
 else
 | 
			
		||||
    pkg_failed=untried
 | 
			
		||||
fi[]dnl
 | 
			
		||||
])# _PKG_CONFIG
 | 
			
		||||
 | 
			
		||||
# _PKG_SHORT_ERRORS_SUPPORTED
 | 
			
		||||
# -----------------------------
 | 
			
		||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
 | 
			
		||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
 | 
			
		||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
 | 
			
		||||
        _pkg_short_errors_supported=yes
 | 
			
		||||
else
 | 
			
		||||
        _pkg_short_errors_supported=no
 | 
			
		||||
fi[]dnl
 | 
			
		||||
])# _PKG_SHORT_ERRORS_SUPPORTED
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
 | 
			
		||||
# [ACTION-IF-NOT-FOUND])
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# Note that if there is a possibility the first call to
 | 
			
		||||
# PKG_CHECK_MODULES might not happen, you should be sure to include an
 | 
			
		||||
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# --------------------------------------------------------------
 | 
			
		||||
AC_DEFUN([PKG_CHECK_MODULES],
 | 
			
		||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
 | 
			
		||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
 | 
			
		||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
 | 
			
		||||
 | 
			
		||||
pkg_failed=no
 | 
			
		||||
AC_MSG_CHECKING([for $1])
 | 
			
		||||
 | 
			
		||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
 | 
			
		||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
 | 
			
		||||
 | 
			
		||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
 | 
			
		||||
and $1[]_LIBS to avoid the need to call pkg-config.
 | 
			
		||||
See the pkg-config man page for more details.])
 | 
			
		||||
 | 
			
		||||
if test $pkg_failed = yes; then
 | 
			
		||||
   	AC_MSG_RESULT([no])
 | 
			
		||||
        _PKG_SHORT_ERRORS_SUPPORTED
 | 
			
		||||
        if test $_pkg_short_errors_supported = yes; then
 | 
			
		||||
	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
 | 
			
		||||
        else 
 | 
			
		||||
	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
 | 
			
		||||
        fi
 | 
			
		||||
	# Put the nasty error message in config.log where it belongs
 | 
			
		||||
	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
 | 
			
		||||
 | 
			
		||||
	m4_default([$4], [AC_MSG_ERROR(
 | 
			
		||||
[Package requirements ($2) were not met:
 | 
			
		||||
 | 
			
		||||
$$1_PKG_ERRORS
 | 
			
		||||
 | 
			
		||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
 | 
			
		||||
installed software in a non-standard prefix.
 | 
			
		||||
 | 
			
		||||
_PKG_TEXT])[]dnl
 | 
			
		||||
        ])
 | 
			
		||||
elif test $pkg_failed = untried; then
 | 
			
		||||
     	AC_MSG_RESULT([no])
 | 
			
		||||
	m4_default([$4], [AC_MSG_FAILURE(
 | 
			
		||||
[The pkg-config script could not be found or is too old.  Make sure it
 | 
			
		||||
is in your PATH or set the PKG_CONFIG environment variable to the full
 | 
			
		||||
path to pkg-config.
 | 
			
		||||
 | 
			
		||||
_PKG_TEXT
 | 
			
		||||
 | 
			
		||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
 | 
			
		||||
        ])
 | 
			
		||||
else
 | 
			
		||||
	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
 | 
			
		||||
	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
 | 
			
		||||
        AC_MSG_RESULT([yes])
 | 
			
		||||
	$3
 | 
			
		||||
fi[]dnl
 | 
			
		||||
])# PKG_CHECK_MODULES
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# PKG_INSTALLDIR(DIRECTORY)
 | 
			
		||||
# -------------------------
 | 
			
		||||
# Substitutes the variable pkgconfigdir as the location where a module
 | 
			
		||||
# should install pkg-config .pc files. By default the directory is
 | 
			
		||||
# $libdir/pkgconfig, but the default can be changed by passing
 | 
			
		||||
# DIRECTORY. The user can override through the --with-pkgconfigdir
 | 
			
		||||
# parameter.
 | 
			
		||||
AC_DEFUN([PKG_INSTALLDIR],
 | 
			
		||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
 | 
			
		||||
m4_pushdef([pkg_description],
 | 
			
		||||
    [pkg-config installation directory @<:@]pkg_default[@:>@])
 | 
			
		||||
AC_ARG_WITH([pkgconfigdir],
 | 
			
		||||
    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
 | 
			
		||||
    [with_pkgconfigdir=]pkg_default)
 | 
			
		||||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
 | 
			
		||||
m4_popdef([pkg_default])
 | 
			
		||||
m4_popdef([pkg_description])
 | 
			
		||||
]) dnl PKG_INSTALLDIR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
 | 
			
		||||
# -------------------------
 | 
			
		||||
# Substitutes the variable noarch_pkgconfigdir as the location where a
 | 
			
		||||
# module should install arch-independent pkg-config .pc files. By
 | 
			
		||||
# default the directory is $datadir/pkgconfig, but the default can be
 | 
			
		||||
# changed by passing DIRECTORY. The user can override through the
 | 
			
		||||
# --with-noarch-pkgconfigdir parameter.
 | 
			
		||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
 | 
			
		||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
 | 
			
		||||
m4_pushdef([pkg_description],
 | 
			
		||||
    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
 | 
			
		||||
AC_ARG_WITH([noarch-pkgconfigdir],
 | 
			
		||||
    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
 | 
			
		||||
    [with_noarch_pkgconfigdir=]pkg_default)
 | 
			
		||||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
 | 
			
		||||
m4_popdef([pkg_default])
 | 
			
		||||
m4_popdef([pkg_description])
 | 
			
		||||
]) dnl PKG_NOARCH_INSTALLDIR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
 | 
			
		||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
 | 
			
		||||
# -------------------------------------------
 | 
			
		||||
# Retrieves the value of the pkg-config variable for the given module.
 | 
			
		||||
AC_DEFUN([PKG_CHECK_VAR],
 | 
			
		||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
 | 
			
		||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
 | 
			
		||||
 | 
			
		||||
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
 | 
			
		||||
AS_VAR_COPY([$1], [pkg_cv_][$1])
 | 
			
		||||
 | 
			
		||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
 | 
			
		||||
])# PKG_CHECK_VAR
 | 
			
		||||
 | 
			
		||||
m4_include([acinclude.m4])
 | 
			
		||||
							
								
								
									
										1120
									
								
								autoconf/config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1120
									
								
								autoconf/config.guess
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										531
									
								
								autoconf/config.sub
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										531
									
								
								autoconf/config.sub
									
									
									
									
										vendored
									
									
								
							@@ -1,40 +1,42 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Configuration validation subroutine script.
 | 
			
		||||
#   Copyright 1992-2014 Free Software Foundation, Inc.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2014-01-01'
 | 
			
		||||
timestamp='2003-06-17'
 | 
			
		||||
 | 
			
		||||
# This file is free software; you can redistribute it and/or modify it
 | 
			
		||||
# under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
# This file is (in principle) common to ALL GNU software.
 | 
			
		||||
# The presence of a machine in this file suggests that SOME GNU software
 | 
			
		||||
# can handle that machine.  It does not imply ALL GNU software can.
 | 
			
		||||
#
 | 
			
		||||
# This file 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.
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 59 Temple Place - Suite 330,
 | 
			
		||||
# Boston, MA 02111-1307, USA.
 | 
			
		||||
 | 
			
		||||
# As a special exception to the GNU General Public License, if you
 | 
			
		||||
# distribute this file as part of a program that contains a
 | 
			
		||||
# configuration script generated by Autoconf, you may include it under
 | 
			
		||||
# the same distribution terms that you use for the rest of that
 | 
			
		||||
# program.  This Exception is an additional permission under section 7
 | 
			
		||||
# of the GNU General Public License, version 3 ("GPLv3").
 | 
			
		||||
# the same distribution terms that you use for the rest of that program.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
 | 
			
		||||
# Please send patches to <config-patches@gnu.org>.  Submit a context
 | 
			
		||||
# diff and a properly formatted ChangeLog entry.
 | 
			
		||||
#
 | 
			
		||||
# Configuration subroutine to validate and canonicalize a configuration type.
 | 
			
		||||
# Supply the specified configuration type as an argument.
 | 
			
		||||
# If it is invalid, we print an error message on stderr and exit with code 1.
 | 
			
		||||
# Otherwise, we print the canonical config type on stdout and succeed.
 | 
			
		||||
 | 
			
		||||
# You can get the latest version of this script from:
 | 
			
		||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
 | 
			
		||||
 | 
			
		||||
# This file is supposed to be the same for all GNU packages
 | 
			
		||||
# and recognize all the CPU types, system types and aliases
 | 
			
		||||
# that are meaningful with *any* GNU software.
 | 
			
		||||
@@ -68,7 +70,8 @@ Report bugs and patches to <config-patches@gnu.org>."
 | 
			
		||||
version="\
 | 
			
		||||
GNU config.sub ($timestamp)
 | 
			
		||||
 | 
			
		||||
Copyright 1992-2014 Free Software Foundation, Inc.
 | 
			
		||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 | 
			
		||||
Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
This is free software; see the source for copying conditions.  There is NO
 | 
			
		||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 | 
			
		||||
@@ -80,11 +83,11 @@ Try \`$me --help' for more information."
 | 
			
		||||
while test $# -gt 0 ; do
 | 
			
		||||
  case $1 in
 | 
			
		||||
    --time-stamp | --time* | -t )
 | 
			
		||||
       echo "$timestamp" ; exit ;;
 | 
			
		||||
       echo "$timestamp" ; exit 0 ;;
 | 
			
		||||
    --version | -v )
 | 
			
		||||
       echo "$version" ; exit ;;
 | 
			
		||||
       echo "$version" ; exit 0 ;;
 | 
			
		||||
    --help | --h* | -h )
 | 
			
		||||
       echo "$usage"; exit ;;
 | 
			
		||||
       echo "$usage"; exit 0 ;;
 | 
			
		||||
    -- )     # Stop option processing
 | 
			
		||||
       shift; break ;;
 | 
			
		||||
    - )	# Use stdin as input.
 | 
			
		||||
@@ -96,7 +99,7 @@ while test $# -gt 0 ; do
 | 
			
		||||
    *local*)
 | 
			
		||||
       # First pass through any local machine types.
 | 
			
		||||
       echo $1
 | 
			
		||||
       exit ;;
 | 
			
		||||
       exit 0;;
 | 
			
		||||
 | 
			
		||||
    * )
 | 
			
		||||
       break ;;
 | 
			
		||||
@@ -115,18 +118,10 @@ esac
 | 
			
		||||
# Here we must recognize all the valid KERNEL-OS combinations.
 | 
			
		||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 | 
			
		||||
case $maybe_os in
 | 
			
		||||
  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
 | 
			
		||||
  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
 | 
			
		||||
  knetbsd*-gnu* | netbsd*-gnu* | \
 | 
			
		||||
  kopensolaris*-gnu* | \
 | 
			
		||||
  storm-chaos* | os2-emx* | rtmk-nova*)
 | 
			
		||||
  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
 | 
			
		||||
    os=-$maybe_os
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
 | 
			
		||||
    ;;
 | 
			
		||||
  android-linux)
 | 
			
		||||
    os=-linux-android
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
 | 
			
		||||
    if [ $basic_machine != $1 ]
 | 
			
		||||
@@ -149,13 +144,10 @@ case $os in
 | 
			
		||||
	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 | 
			
		||||
	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 | 
			
		||||
	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
 | 
			
		||||
	-apple | -axis | -knuth | -cray | -microblaze*)
 | 
			
		||||
	-apple | -axis)
 | 
			
		||||
		os=
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
	-bluegene*)
 | 
			
		||||
		os=-cnk
 | 
			
		||||
		;;
 | 
			
		||||
	-sim | -cisco | -oki | -wec | -winbond)
 | 
			
		||||
		os=
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
@@ -170,17 +162,13 @@ case $os in
 | 
			
		||||
		os=-chorusos
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
	-chorusrdb)
 | 
			
		||||
		os=-chorusrdb
 | 
			
		||||
 	-chorusrdb)
 | 
			
		||||
 		os=-chorusrdb
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
 		;;
 | 
			
		||||
	-hiux*)
 | 
			
		||||
		os=-hiuxwe2
 | 
			
		||||
		;;
 | 
			
		||||
	-sco6)
 | 
			
		||||
		os=-sco5v6
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
		;;
 | 
			
		||||
	-sco5)
 | 
			
		||||
		os=-sco3.2v5
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
@@ -197,10 +185,6 @@ case $os in
 | 
			
		||||
		# Don't forget version if it is 3.2v4 or newer.
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
		;;
 | 
			
		||||
	-sco5v6*)
 | 
			
		||||
		# Don't forget version if it is 3.2v4 or newer.
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
		;;
 | 
			
		||||
	-sco*)
 | 
			
		||||
		os=-sco3.2v2
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
@@ -218,12 +202,6 @@ case $os in
 | 
			
		||||
	-isc*)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
		;;
 | 
			
		||||
	-lynx*178)
 | 
			
		||||
		os=-lynxos178
 | 
			
		||||
		;;
 | 
			
		||||
	-lynx*5)
 | 
			
		||||
		os=-lynxos5
 | 
			
		||||
		;;
 | 
			
		||||
	-lynx*)
 | 
			
		||||
		os=-lynxos
 | 
			
		||||
		;;
 | 
			
		||||
@@ -248,107 +226,55 @@ case $basic_machine in
 | 
			
		||||
	# Some are omitted here because they have special meanings below.
 | 
			
		||||
	1750a | 580 \
 | 
			
		||||
	| a29k \
 | 
			
		||||
	| aarch64 | aarch64_be \
 | 
			
		||||
	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 | 
			
		||||
	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
 | 
			
		||||
	| am33_2.0 \
 | 
			
		||||
	| arc | arceb \
 | 
			
		||||
	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
 | 
			
		||||
	| avr | avr32 \
 | 
			
		||||
	| be32 | be64 \
 | 
			
		||||
	| bfin \
 | 
			
		||||
	| c4x | c8051 | clipper \
 | 
			
		||||
	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
 | 
			
		||||
	| c4x | clipper \
 | 
			
		||||
	| d10v | d30v | dlx | dsp16xx \
 | 
			
		||||
	| epiphany \
 | 
			
		||||
	| fido | fr30 | frv \
 | 
			
		||||
	| fr30 | frv \
 | 
			
		||||
	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 | 
			
		||||
	| hexagon \
 | 
			
		||||
	| i370 | i860 | i960 | ia64 \
 | 
			
		||||
	| ip2k | iq2000 \
 | 
			
		||||
	| k1om \
 | 
			
		||||
	| le32 | le64 \
 | 
			
		||||
	| lm32 \
 | 
			
		||||
	| m32c | m32r | m32rle | m68000 | m68k | m88k \
 | 
			
		||||
	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
 | 
			
		||||
	| ip2k \
 | 
			
		||||
	| m32r | m68000 | m68k | m88k | mcore \
 | 
			
		||||
	| mips | mipsbe | mipseb | mipsel | mipsle \
 | 
			
		||||
	| mips16 \
 | 
			
		||||
	| mips64 | mips64el \
 | 
			
		||||
	| mips64octeon | mips64octeonel \
 | 
			
		||||
	| mips64orion | mips64orionel \
 | 
			
		||||
	| mips64r5900 | mips64r5900el \
 | 
			
		||||
	| mips64vr | mips64vrel \
 | 
			
		||||
	| mips64orion | mips64orionel \
 | 
			
		||||
	| mips64vr4100 | mips64vr4100el \
 | 
			
		||||
	| mips64vr4300 | mips64vr4300el \
 | 
			
		||||
	| mips64vr5000 | mips64vr5000el \
 | 
			
		||||
	| mips64vr5900 | mips64vr5900el \
 | 
			
		||||
	| mipsisa32 | mipsisa32el \
 | 
			
		||||
	| mipsisa32r2 | mipsisa32r2el \
 | 
			
		||||
	| mipsisa64 | mipsisa64el \
 | 
			
		||||
	| mipsisa64r2 | mipsisa64r2el \
 | 
			
		||||
	| mipsisa64sb1 | mipsisa64sb1el \
 | 
			
		||||
	| mipsisa64sr71k | mipsisa64sr71kel \
 | 
			
		||||
	| mipsr5900 | mipsr5900el \
 | 
			
		||||
	| mipstx39 | mipstx39el \
 | 
			
		||||
	| mn10200 | mn10300 \
 | 
			
		||||
	| moxie \
 | 
			
		||||
	| mt \
 | 
			
		||||
	| msp430 \
 | 
			
		||||
	| nds32 | nds32le | nds32be \
 | 
			
		||||
	| nios | nios2 | nios2eb | nios2el \
 | 
			
		||||
	| ns16k | ns32k \
 | 
			
		||||
	| open8 \
 | 
			
		||||
	| or1k | or32 \
 | 
			
		||||
	| openrisc | or32 \
 | 
			
		||||
	| pdp10 | pdp11 | pj | pjl \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 | 
			
		||||
	| pyramid \
 | 
			
		||||
	| rl78 | rx \
 | 
			
		||||
	| score \
 | 
			
		||||
	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| sh64 | sh64le \
 | 
			
		||||
	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 | 
			
		||||
	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
 | 
			
		||||
	| spu \
 | 
			
		||||
	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 | 
			
		||||
	| ubicom32 \
 | 
			
		||||
	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
 | 
			
		||||
	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
 | 
			
		||||
	| strongarm \
 | 
			
		||||
	| tahoe | thumb | tic4x | tic80 | tron \
 | 
			
		||||
	| v850 | v850e \
 | 
			
		||||
	| we32k \
 | 
			
		||||
	| x86 | xc16x | xstormy16 | xtensa \
 | 
			
		||||
	| z8k | z80)
 | 
			
		||||
	| x86 | xscale | xstormy16 | xtensa \
 | 
			
		||||
	| z8k)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	c54x)
 | 
			
		||||
		basic_machine=tic54x-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	c55x)
 | 
			
		||||
		basic_machine=tic55x-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	c6x)
 | 
			
		||||
		basic_machine=tic6x-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
 | 
			
		||||
	m6811 | m68hc11 | m6812 | m68hc12)
 | 
			
		||||
		# Motorola 68HC11/12.
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 | 
			
		||||
		;;
 | 
			
		||||
	ms1)
 | 
			
		||||
		basic_machine=mt-unknown
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	strongarm | thumb | xscale)
 | 
			
		||||
		basic_machine=arm-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	xgate)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
	xscaleeb)
 | 
			
		||||
		basic_machine=armeb-unknown
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	xscaleel)
 | 
			
		||||
		basic_machine=armel-unknown
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	# We use `pc' rather than `unknown'
 | 
			
		||||
	# because (1) that's what they normally are, and
 | 
			
		||||
@@ -364,83 +290,58 @@ case $basic_machine in
 | 
			
		||||
	# Recognize the basic CPU types with company name.
 | 
			
		||||
	580-* \
 | 
			
		||||
	| a29k-* \
 | 
			
		||||
	| aarch64-* | aarch64_be-* \
 | 
			
		||||
	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
 | 
			
		||||
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 | 
			
		||||
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
 | 
			
		||||
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 | 
			
		||||
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 | 
			
		||||
	| avr-* | avr32-* \
 | 
			
		||||
	| be32-* | be64-* \
 | 
			
		||||
	| bfin-* | bs2000-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 | 
			
		||||
	| c8051-* | clipper-* | craynv-* | cydra-* \
 | 
			
		||||
	| avr-* \
 | 
			
		||||
	| bs2000-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
 | 
			
		||||
	| clipper-* | cydra-* \
 | 
			
		||||
	| d10v-* | d30v-* | dlx-* \
 | 
			
		||||
	| elxsi-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
 | 
			
		||||
	| h8300-* | h8500-* \
 | 
			
		||||
	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 | 
			
		||||
	| hexagon-* \
 | 
			
		||||
	| i*86-* | i860-* | i960-* | ia64-* \
 | 
			
		||||
	| ip2k-* | iq2000-* \
 | 
			
		||||
	| k1om-* \
 | 
			
		||||
	| le32-* | le64-* \
 | 
			
		||||
	| lm32-* \
 | 
			
		||||
	| m32c-* | m32r-* | m32rle-* \
 | 
			
		||||
	| ip2k-* \
 | 
			
		||||
	| m32r-* \
 | 
			
		||||
	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
 | 
			
		||||
	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
 | 
			
		||||
	| microblaze-* | microblazeel-* \
 | 
			
		||||
	| m88110-* | m88k-* | mcore-* \
 | 
			
		||||
	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 | 
			
		||||
	| mips16-* \
 | 
			
		||||
	| mips64-* | mips64el-* \
 | 
			
		||||
	| mips64octeon-* | mips64octeonel-* \
 | 
			
		||||
	| mips64orion-* | mips64orionel-* \
 | 
			
		||||
	| mips64r5900-* | mips64r5900el-* \
 | 
			
		||||
	| mips64vr-* | mips64vrel-* \
 | 
			
		||||
	| mips64orion-* | mips64orionel-* \
 | 
			
		||||
	| mips64vr4100-* | mips64vr4100el-* \
 | 
			
		||||
	| mips64vr4300-* | mips64vr4300el-* \
 | 
			
		||||
	| mips64vr5000-* | mips64vr5000el-* \
 | 
			
		||||
	| mips64vr5900-* | mips64vr5900el-* \
 | 
			
		||||
	| mipsisa32-* | mipsisa32el-* \
 | 
			
		||||
	| mipsisa32r2-* | mipsisa32r2el-* \
 | 
			
		||||
	| mipsisa64-* | mipsisa64el-* \
 | 
			
		||||
	| mipsisa64r2-* | mipsisa64r2el-* \
 | 
			
		||||
	| mipsisa64sb1-* | mipsisa64sb1el-* \
 | 
			
		||||
	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 | 
			
		||||
	| mipsr5900-* | mipsr5900el-* \
 | 
			
		||||
	| mipstx39-* | mipstx39el-* \
 | 
			
		||||
	| mmix-* \
 | 
			
		||||
	| mt-* \
 | 
			
		||||
	| msp430-* \
 | 
			
		||||
	| nds32-* | nds32le-* | nds32be-* \
 | 
			
		||||
	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 | 
			
		||||
	| none-* | np1-* | ns16k-* | ns32k-* \
 | 
			
		||||
	| open8-* \
 | 
			
		||||
	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
 | 
			
		||||
	| orion-* \
 | 
			
		||||
	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 | 
			
		||||
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 | 
			
		||||
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 | 
			
		||||
	| pyramid-* \
 | 
			
		||||
	| rl78-* | romp-* | rs6000-* | rx-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 | 
			
		||||
	| romp-* | rs6000-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
 | 
			
		||||
	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 | 
			
		||||
	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 | 
			
		||||
	| sparclite-* \
 | 
			
		||||
	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
 | 
			
		||||
	| tahoe-* \
 | 
			
		||||
	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
 | 
			
		||||
	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
 | 
			
		||||
	| tahoe-* | thumb-* \
 | 
			
		||||
	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 | 
			
		||||
	| tile*-* \
 | 
			
		||||
	| tron-* \
 | 
			
		||||
	| ubicom32-* \
 | 
			
		||||
	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 | 
			
		||||
	| vax-* \
 | 
			
		||||
	| v850-* | v850e-* | vax-* \
 | 
			
		||||
	| we32k-* \
 | 
			
		||||
	| x86-* | x86_64-* | xc16x-* | xps100-* \
 | 
			
		||||
	| xstormy16-* | xtensa*-* \
 | 
			
		||||
	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
 | 
			
		||||
	| xtensa-* \
 | 
			
		||||
	| ymp-* \
 | 
			
		||||
	| z8k-* | z80-*)
 | 
			
		||||
		;;
 | 
			
		||||
	# Recognize the basic CPU types without company name, with glob match.
 | 
			
		||||
	xtensa*)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
	| z8k-*)
 | 
			
		||||
		;;
 | 
			
		||||
	# Recognize the various machine names and aliases which stand
 | 
			
		||||
	# for a CPU type and a company and sometimes even an OS.
 | 
			
		||||
@@ -458,9 +359,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=a29k-amd
 | 
			
		||||
		os=-udi
 | 
			
		||||
		;;
 | 
			
		||||
	abacus)
 | 
			
		||||
		basic_machine=abacus-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	adobe68k)
 | 
			
		||||
		basic_machine=m68010-adobe
 | 
			
		||||
		os=-scout
 | 
			
		||||
@@ -478,9 +376,6 @@ case $basic_machine in
 | 
			
		||||
	amd64)
 | 
			
		||||
		basic_machine=x86_64-pc
 | 
			
		||||
		;;
 | 
			
		||||
	amd64-*)
 | 
			
		||||
		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	amdahl)
 | 
			
		||||
		basic_machine=580-amdahl
 | 
			
		||||
		os=-sysv
 | 
			
		||||
@@ -504,10 +399,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=m68k-apollo
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
	aros)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-aros
 | 
			
		||||
		;;
 | 
			
		||||
	aux)
 | 
			
		||||
		basic_machine=m68k-apple
 | 
			
		||||
		os=-aux
 | 
			
		||||
@@ -516,35 +407,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=ns32k-sequent
 | 
			
		||||
		os=-dynix
 | 
			
		||||
		;;
 | 
			
		||||
	blackfin)
 | 
			
		||||
		basic_machine=bfin-unknown
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	blackfin-*)
 | 
			
		||||
		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	bluegene*)
 | 
			
		||||
		basic_machine=powerpc-ibm
 | 
			
		||||
		os=-cnk
 | 
			
		||||
		;;
 | 
			
		||||
	c54x-*)
 | 
			
		||||
		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	c55x-*)
 | 
			
		||||
		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	c6x-*)
 | 
			
		||||
		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	c90)
 | 
			
		||||
		basic_machine=c90-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	cegcc)
 | 
			
		||||
		basic_machine=arm-unknown
 | 
			
		||||
		os=-cegcc
 | 
			
		||||
		;;
 | 
			
		||||
	convex-c1)
 | 
			
		||||
		basic_machine=c1-convex
 | 
			
		||||
		os=-bsd
 | 
			
		||||
@@ -569,27 +435,12 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=j90-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	craynv)
 | 
			
		||||
		basic_machine=craynv-cray
 | 
			
		||||
		os=-unicosmp
 | 
			
		||||
		;;
 | 
			
		||||
	cr16 | cr16-*)
 | 
			
		||||
		basic_machine=cr16-unknown
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	crds | unos)
 | 
			
		||||
		basic_machine=m68k-crds
 | 
			
		||||
		;;
 | 
			
		||||
	crisv32 | crisv32-* | etraxfs*)
 | 
			
		||||
		basic_machine=crisv32-axis
 | 
			
		||||
		;;
 | 
			
		||||
	cris | cris-* | etrax*)
 | 
			
		||||
		basic_machine=cris-axis
 | 
			
		||||
		;;
 | 
			
		||||
	crx)
 | 
			
		||||
		basic_machine=crx-unknown
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	da30 | da30-*)
 | 
			
		||||
		basic_machine=m68k-da30
 | 
			
		||||
		;;
 | 
			
		||||
@@ -612,14 +463,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=m88k-motorola
 | 
			
		||||
		os=-sysv3
 | 
			
		||||
		;;
 | 
			
		||||
	dicos)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		os=-dicos
 | 
			
		||||
		;;
 | 
			
		||||
	djgpp)
 | 
			
		||||
		basic_machine=i586-pc
 | 
			
		||||
		os=-msdosdjgpp
 | 
			
		||||
		;;
 | 
			
		||||
	dpx20 | dpx20-*)
 | 
			
		||||
		basic_machine=rs6000-bull
 | 
			
		||||
		os=-bosx
 | 
			
		||||
@@ -731,6 +574,7 @@ case $basic_machine in
 | 
			
		||||
	i370-ibm* | ibm*)
 | 
			
		||||
		basic_machine=i370-ibm
 | 
			
		||||
		;;
 | 
			
		||||
# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
 | 
			
		||||
	i*86v32)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 | 
			
		||||
		os=-sysv32
 | 
			
		||||
@@ -769,14 +613,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=m68k-isi
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	m68knommu)
 | 
			
		||||
		basic_machine=m68k-unknown
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	m68knommu-*)
 | 
			
		||||
		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	m88k-omron*)
 | 
			
		||||
		basic_machine=m88k-omron
 | 
			
		||||
		;;
 | 
			
		||||
@@ -788,21 +624,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=ns32k-utek
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	microblaze*)
 | 
			
		||||
		basic_machine=microblaze-xilinx
 | 
			
		||||
		;;
 | 
			
		||||
	mingw64)
 | 
			
		||||
		basic_machine=x86_64-pc
 | 
			
		||||
		os=-mingw64
 | 
			
		||||
		;;
 | 
			
		||||
	mingw32)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-mingw32
 | 
			
		||||
		;;
 | 
			
		||||
	mingw32ce)
 | 
			
		||||
		basic_machine=arm-unknown
 | 
			
		||||
		os=-mingw32ce
 | 
			
		||||
		;;
 | 
			
		||||
	miniframe)
 | 
			
		||||
		basic_machine=m68000-convergent
 | 
			
		||||
		;;
 | 
			
		||||
@@ -816,6 +641,10 @@ case $basic_machine in
 | 
			
		||||
	mips3*)
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	mmix*)
 | 
			
		||||
		basic_machine=mmix-knuth
 | 
			
		||||
		os=-mmixware
 | 
			
		||||
		;;
 | 
			
		||||
	monitor)
 | 
			
		||||
		basic_machine=m68k-rom68k
 | 
			
		||||
		os=-coff
 | 
			
		||||
@@ -828,21 +657,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-msdos
 | 
			
		||||
		;;
 | 
			
		||||
	ms1-*)
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
 | 
			
		||||
		;;
 | 
			
		||||
	msys)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		os=-msys
 | 
			
		||||
		;;
 | 
			
		||||
	mvs)
 | 
			
		||||
		basic_machine=i370-ibm
 | 
			
		||||
		os=-mvs
 | 
			
		||||
		;;
 | 
			
		||||
	nacl)
 | 
			
		||||
		basic_machine=le32-unknown
 | 
			
		||||
		os=-nacl
 | 
			
		||||
		;;
 | 
			
		||||
	ncr3000)
 | 
			
		||||
		basic_machine=i486-ncr
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
@@ -907,11 +725,9 @@ case $basic_machine in
 | 
			
		||||
	np1)
 | 
			
		||||
		basic_machine=np1-gould
 | 
			
		||||
		;;
 | 
			
		||||
	neo-tandem)
 | 
			
		||||
		basic_machine=neo-tandem
 | 
			
		||||
		;;
 | 
			
		||||
	nse-tandem)
 | 
			
		||||
		basic_machine=nse-tandem
 | 
			
		||||
	nv1)
 | 
			
		||||
		basic_machine=nv1-cray
 | 
			
		||||
		os=-unicosmp
 | 
			
		||||
		;;
 | 
			
		||||
	nsr-tandem)
 | 
			
		||||
		basic_machine=nsr-tandem
 | 
			
		||||
@@ -920,12 +736,9 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=hppa1.1-oki
 | 
			
		||||
		os=-proelf
 | 
			
		||||
		;;
 | 
			
		||||
	openrisc | openrisc-*)
 | 
			
		||||
	or32 | or32-*)
 | 
			
		||||
		basic_machine=or32-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	os400)
 | 
			
		||||
		basic_machine=powerpc-ibm
 | 
			
		||||
		os=-os400
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	OSE68000 | ose68000)
 | 
			
		||||
		basic_machine=m68000-ericsson
 | 
			
		||||
@@ -943,14 +756,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i860-intel
 | 
			
		||||
		os=-osf
 | 
			
		||||
		;;
 | 
			
		||||
	parisc)
 | 
			
		||||
		basic_machine=hppa-unknown
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	parisc-*)
 | 
			
		||||
		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	pbd)
 | 
			
		||||
		basic_machine=sparc-tti
 | 
			
		||||
		;;
 | 
			
		||||
@@ -960,12 +765,6 @@ case $basic_machine in
 | 
			
		||||
	pc532 | pc532-*)
 | 
			
		||||
		basic_machine=ns32k-pc532
 | 
			
		||||
		;;
 | 
			
		||||
	pc98)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pc98-*)
 | 
			
		||||
		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pentium | p5 | k5 | k6 | nexgen | viac3)
 | 
			
		||||
		basic_machine=i586-pc
 | 
			
		||||
		;;
 | 
			
		||||
@@ -995,10 +794,9 @@ case $basic_machine in
 | 
			
		||||
		;;
 | 
			
		||||
	power)	basic_machine=power-ibm
 | 
			
		||||
		;;
 | 
			
		||||
	ppc | ppcbe)	basic_machine=powerpc-unknown
 | 
			
		||||
	ppc)	basic_machine=powerpc-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	ppc-* | ppcbe-*)
 | 
			
		||||
		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	ppcle | powerpclittle | ppc-le | powerpc-little)
 | 
			
		||||
		basic_machine=powerpcle-unknown
 | 
			
		||||
@@ -1023,14 +821,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i586-unknown
 | 
			
		||||
		os=-pw32
 | 
			
		||||
		;;
 | 
			
		||||
	rdos | rdos64)
 | 
			
		||||
		basic_machine=x86_64-pc
 | 
			
		||||
		os=-rdos
 | 
			
		||||
		;;
 | 
			
		||||
	rdos32)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-rdos
 | 
			
		||||
		;;
 | 
			
		||||
	rom68k)
 | 
			
		||||
		basic_machine=m68k-rom68k
 | 
			
		||||
		os=-coff
 | 
			
		||||
@@ -1057,10 +847,6 @@ case $basic_machine in
 | 
			
		||||
	sb1el)
 | 
			
		||||
		basic_machine=mipsisa64sb1el-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sde)
 | 
			
		||||
		basic_machine=mipsisa32-sde
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	sei)
 | 
			
		||||
		basic_machine=mips-sei
 | 
			
		||||
		os=-seiux
 | 
			
		||||
@@ -1072,9 +858,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=sh-hitachi
 | 
			
		||||
		os=-hms
 | 
			
		||||
		;;
 | 
			
		||||
	sh5el)
 | 
			
		||||
		basic_machine=sh5le-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sh64)
 | 
			
		||||
		basic_machine=sh64-unknown
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1096,9 +879,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i860-stratus
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
	strongarm-* | thumb-*)
 | 
			
		||||
		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	sun2)
 | 
			
		||||
		basic_machine=m68000-sun
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1155,9 +935,17 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=t90-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	tile*)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-linux-gnu
 | 
			
		||||
	tic54x | c54x*)
 | 
			
		||||
		basic_machine=tic54x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic55x | c55x*)
 | 
			
		||||
		basic_machine=tic55x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic6x | c6x*)
 | 
			
		||||
		basic_machine=tic6x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tx39)
 | 
			
		||||
		basic_machine=mipstx39-unknown
 | 
			
		||||
@@ -1172,10 +960,6 @@ case $basic_machine in
 | 
			
		||||
	tower | tower-32)
 | 
			
		||||
		basic_machine=m68k-ncr
 | 
			
		||||
		;;
 | 
			
		||||
	tpf)
 | 
			
		||||
		basic_machine=s390x-ibm
 | 
			
		||||
		os=-tpf
 | 
			
		||||
		;;
 | 
			
		||||
	udi29k)
 | 
			
		||||
		basic_machine=a29k-amd
 | 
			
		||||
		os=-udi
 | 
			
		||||
@@ -1219,16 +1003,9 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=hppa1.1-winbond
 | 
			
		||||
		os=-proelf
 | 
			
		||||
		;;
 | 
			
		||||
	xbox)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		os=-mingw32
 | 
			
		||||
		;;
 | 
			
		||||
	xps | xps100)
 | 
			
		||||
		basic_machine=xps100-honeywell
 | 
			
		||||
		;;
 | 
			
		||||
	xscale-* | xscalee[bl]-*)
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
 | 
			
		||||
		;;
 | 
			
		||||
	ymp)
 | 
			
		||||
		basic_machine=ymp-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
@@ -1237,10 +1014,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=z8k-unknown
 | 
			
		||||
		os=-sim
 | 
			
		||||
		;;
 | 
			
		||||
	z80-*-coff)
 | 
			
		||||
		basic_machine=z80-unknown
 | 
			
		||||
		os=-sim
 | 
			
		||||
		;;
 | 
			
		||||
	none)
 | 
			
		||||
		basic_machine=none-none
 | 
			
		||||
		os=-none
 | 
			
		||||
@@ -1260,9 +1033,6 @@ case $basic_machine in
 | 
			
		||||
	romp)
 | 
			
		||||
		basic_machine=romp-ibm
 | 
			
		||||
		;;
 | 
			
		||||
	mmix)
 | 
			
		||||
		basic_machine=mmix-knuth
 | 
			
		||||
		;;
 | 
			
		||||
	rs6000)
 | 
			
		||||
		basic_machine=rs6000-ibm
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1279,10 +1049,13 @@ case $basic_machine in
 | 
			
		||||
	we32k)
 | 
			
		||||
		basic_machine=we32k-att
 | 
			
		||||
		;;
 | 
			
		||||
	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
 | 
			
		||||
	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
 | 
			
		||||
		basic_machine=sh-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
 | 
			
		||||
	sh64)
 | 
			
		||||
		basic_machine=sh64-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sparc | sparcv9 | sparcv9b)
 | 
			
		||||
		basic_machine=sparc-sun
 | 
			
		||||
		;;
 | 
			
		||||
	cydra)
 | 
			
		||||
@@ -1326,12 +1099,9 @@ esac
 | 
			
		||||
if [ x"$os" != x"" ]
 | 
			
		||||
then
 | 
			
		||||
case $os in
 | 
			
		||||
	# First match some system type aliases
 | 
			
		||||
	# that might get confused with valid system types.
 | 
			
		||||
        # First match some system type aliases
 | 
			
		||||
        # that might get confused with valid system types.
 | 
			
		||||
	# -solaris* is a basic system type, with this one exception.
 | 
			
		||||
	-auroraux)
 | 
			
		||||
		os=-auroraux
 | 
			
		||||
		;;
 | 
			
		||||
	-solaris1 | -solaris1.*)
 | 
			
		||||
		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1352,31 +1122,25 @@ case $os in
 | 
			
		||||
	# Each alternative MUST END IN A *, to match a version number.
 | 
			
		||||
	# -sysv* is not here because it comes later, after sysvr4.
 | 
			
		||||
	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
 | 
			
		||||
	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
 | 
			
		||||
	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 | 
			
		||||
	      | -sym* | -kopensolaris* | -plan9* \
 | 
			
		||||
	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
 | 
			
		||||
	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
 | 
			
		||||
	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
 | 
			
		||||
	      | -aos* | -aros* \
 | 
			
		||||
	      | -aos* \
 | 
			
		||||
	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 | 
			
		||||
	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 | 
			
		||||
	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
 | 
			
		||||
	      | -bitrig* | -openbsd* | -solidbsd* \
 | 
			
		||||
	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 | 
			
		||||
	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 | 
			
		||||
	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
 | 
			
		||||
	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 | 
			
		||||
	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 | 
			
		||||
	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 | 
			
		||||
	      | -chorusos* | -chorusrdb* | -cegcc* \
 | 
			
		||||
	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 | 
			
		||||
	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 | 
			
		||||
	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
 | 
			
		||||
	      | -uxpv* | -beos* | -mpeix* | -udk* \
 | 
			
		||||
	      | -chorusos* | -chorusrdb* \
 | 
			
		||||
	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 | 
			
		||||
	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
 | 
			
		||||
	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 | 
			
		||||
	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 | 
			
		||||
	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 | 
			
		||||
	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 | 
			
		||||
	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 | 
			
		||||
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
 | 
			
		||||
	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 | 
			
		||||
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
 | 
			
		||||
	# Remember, each alternative MUST END IN *, to match a version number.
 | 
			
		||||
		;;
 | 
			
		||||
	-qnx*)
 | 
			
		||||
@@ -1394,15 +1158,12 @@ case $os in
 | 
			
		||||
		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 | 
			
		||||
		;;
 | 
			
		||||
	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
 | 
			
		||||
	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
 | 
			
		||||
	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
 | 
			
		||||
	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
 | 
			
		||||
		;;
 | 
			
		||||
	-mac*)
 | 
			
		||||
		os=`echo $os | sed -e 's|mac|macos|'`
 | 
			
		||||
		;;
 | 
			
		||||
	-linux-dietlibc)
 | 
			
		||||
		os=-linux-dietlibc
 | 
			
		||||
		;;
 | 
			
		||||
	-linux*)
 | 
			
		||||
		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1415,9 +1176,6 @@ case $os in
 | 
			
		||||
	-opened*)
 | 
			
		||||
		os=-openedition
 | 
			
		||||
		;;
 | 
			
		||||
	-os400*)
 | 
			
		||||
		os=-os400
 | 
			
		||||
		;;
 | 
			
		||||
	-wince*)
 | 
			
		||||
		os=-wince
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1439,9 +1197,6 @@ case $os in
 | 
			
		||||
	-atheos*)
 | 
			
		||||
		os=-atheos
 | 
			
		||||
		;;
 | 
			
		||||
	-syllable*)
 | 
			
		||||
		os=-syllable
 | 
			
		||||
		;;
 | 
			
		||||
	-386bsd)
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1464,9 +1219,6 @@ case $os in
 | 
			
		||||
	-sinix*)
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
	-tpf*)
 | 
			
		||||
		os=-tpf
 | 
			
		||||
		;;
 | 
			
		||||
	-triton*)
 | 
			
		||||
		os=-sysv3
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1500,13 +1252,8 @@ case $os in
 | 
			
		||||
	-aros*)
 | 
			
		||||
		os=-aros
 | 
			
		||||
		;;
 | 
			
		||||
	-zvmoe)
 | 
			
		||||
		os=-zvmoe
 | 
			
		||||
		;;
 | 
			
		||||
	-dicos*)
 | 
			
		||||
		os=-dicos
 | 
			
		||||
		;;
 | 
			
		||||
	-nacl*)
 | 
			
		||||
	-kaos*)
 | 
			
		||||
		os=-kaos
 | 
			
		||||
		;;
 | 
			
		||||
	-none)
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1530,12 +1277,6 @@ else
 | 
			
		||||
# system, and we'll never get to this point.
 | 
			
		||||
 | 
			
		||||
case $basic_machine in
 | 
			
		||||
	score-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	spu-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	*-acorn)
 | 
			
		||||
		os=-riscix1.2
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1545,24 +1286,9 @@ case $basic_machine in
 | 
			
		||||
	arm*-semi)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
	c4x-* | tic4x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	c8051-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	hexagon-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	tic54x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic55x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic6x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
    c4x-* | tic4x-*)
 | 
			
		||||
        os=-coff
 | 
			
		||||
        ;;
 | 
			
		||||
	# This must come before the *-dec entry.
 | 
			
		||||
	pdp10-*)
 | 
			
		||||
		os=-tops20
 | 
			
		||||
@@ -1581,22 +1307,19 @@ case $basic_machine in
 | 
			
		||||
		;;
 | 
			
		||||
	m68000-sun)
 | 
			
		||||
		os=-sunos3
 | 
			
		||||
		# This also exists in the configure program, but was not the
 | 
			
		||||
		# default.
 | 
			
		||||
		# os=-sunos4
 | 
			
		||||
		;;
 | 
			
		||||
	m68*-cisco)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
	mep-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	mips*-cisco)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	mips*-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	or1k-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	or32-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1609,15 +1332,9 @@ case $basic_machine in
 | 
			
		||||
	*-be)
 | 
			
		||||
		os=-beos
 | 
			
		||||
		;;
 | 
			
		||||
	*-haiku)
 | 
			
		||||
		os=-haiku
 | 
			
		||||
		;;
 | 
			
		||||
	*-ibm)
 | 
			
		||||
		os=-aix
 | 
			
		||||
		;;
 | 
			
		||||
	*-knuth)
 | 
			
		||||
		os=-mmixware
 | 
			
		||||
		;;
 | 
			
		||||
	*-wec)
 | 
			
		||||
		os=-proelf
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1720,7 +1437,7 @@ case $basic_machine in
 | 
			
		||||
			-sunos*)
 | 
			
		||||
				vendor=sun
 | 
			
		||||
				;;
 | 
			
		||||
			-cnk*|-aix*)
 | 
			
		||||
			-aix*)
 | 
			
		||||
				vendor=ibm
 | 
			
		||||
				;;
 | 
			
		||||
			-beos*)
 | 
			
		||||
@@ -1750,15 +1467,9 @@ case $basic_machine in
 | 
			
		||||
			-mvs* | -opened*)
 | 
			
		||||
				vendor=ibm
 | 
			
		||||
				;;
 | 
			
		||||
			-os400*)
 | 
			
		||||
				vendor=ibm
 | 
			
		||||
				;;
 | 
			
		||||
			-ptx*)
 | 
			
		||||
				vendor=sequent
 | 
			
		||||
				;;
 | 
			
		||||
			-tpf*)
 | 
			
		||||
				vendor=ibm
 | 
			
		||||
				;;
 | 
			
		||||
			-vxsim* | -vxworks* | -windiss*)
 | 
			
		||||
				vendor=wrs
 | 
			
		||||
				;;
 | 
			
		||||
@@ -1783,7 +1494,7 @@ case $basic_machine in
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
echo $basic_machine$os
 | 
			
		||||
exit
 | 
			
		||||
exit 0
 | 
			
		||||
 | 
			
		||||
# Local variables:
 | 
			
		||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# install - install a program, script, or datafile
 | 
			
		||||
 | 
			
		||||
scriptversion=2006-10-14.15
 | 
			
		||||
scriptversion=2003-06-13.21
 | 
			
		||||
 | 
			
		||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
 | 
			
		||||
# later released in X11R6 (xc/config/util/install.sh) with the
 | 
			
		||||
@@ -39,24 +39,15 @@ scriptversion=2006-10-14.15
 | 
			
		||||
# when there is no Makefile.
 | 
			
		||||
#
 | 
			
		||||
# This script is compatible with the BSD install script, but was written
 | 
			
		||||
# from scratch.
 | 
			
		||||
 | 
			
		||||
nl='
 | 
			
		||||
'
 | 
			
		||||
IFS=" ""	$nl"
 | 
			
		||||
# from scratch.  It can only install one file at a time, a restriction
 | 
			
		||||
# shared with many OS's install programs.
 | 
			
		||||
 | 
			
		||||
# set DOITPROG to echo to test this script
 | 
			
		||||
 | 
			
		||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
 | 
			
		||||
doit="${DOITPROG-}"
 | 
			
		||||
if test -z "$doit"; then
 | 
			
		||||
  doit_exec=exec
 | 
			
		||||
else
 | 
			
		||||
  doit_exec=$doit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Put in absolute file names if you don't have them in your path;
 | 
			
		||||
# or use environment vars.
 | 
			
		||||
# put in absolute paths if you don't have them in your path; or use env. vars.
 | 
			
		||||
 | 
			
		||||
mvprog="${MVPROG-mv}"
 | 
			
		||||
cpprog="${CPPROG-cp}"
 | 
			
		||||
@@ -67,13 +58,10 @@ stripprog="${STRIPPROG-strip}"
 | 
			
		||||
rmprog="${RMPROG-rm}"
 | 
			
		||||
mkdirprog="${MKDIRPROG-mkdir}"
 | 
			
		||||
 | 
			
		||||
posix_glob=
 | 
			
		||||
posix_mkdir=
 | 
			
		||||
 | 
			
		||||
# Desired mode of installed file.
 | 
			
		||||
mode=0755
 | 
			
		||||
 | 
			
		||||
chmodcmd=$chmodprog
 | 
			
		||||
transformbasename=
 | 
			
		||||
transform_arg=
 | 
			
		||||
instcmd="$mvprog"
 | 
			
		||||
chmodcmd="$chmodprog 0755"
 | 
			
		||||
chowncmd=
 | 
			
		||||
chgrpcmd=
 | 
			
		||||
stripcmd=
 | 
			
		||||
@@ -82,27 +70,22 @@ mvcmd="$mvprog"
 | 
			
		||||
src=
 | 
			
		||||
dst=
 | 
			
		||||
dir_arg=
 | 
			
		||||
dstarg=
 | 
			
		||||
no_target_directory=
 | 
			
		||||
 | 
			
		||||
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
 | 
			
		||||
   or: $0 [OPTION]... SRCFILES... DIRECTORY
 | 
			
		||||
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
 | 
			
		||||
   or: $0 [OPTION]... -d DIRECTORIES...
 | 
			
		||||
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
 | 
			
		||||
   or: $0 -d DIR1 DIR2...
 | 
			
		||||
 | 
			
		||||
In the 1st form, copy SRCFILE to DSTFILE.
 | 
			
		||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
 | 
			
		||||
In the 4th, create DIRECTORIES.
 | 
			
		||||
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
 | 
			
		||||
In the second, create the directory path DIR.
 | 
			
		||||
 | 
			
		||||
Options:
 | 
			
		||||
-c         (ignored)
 | 
			
		||||
-b=TRANSFORMBASENAME
 | 
			
		||||
-c         copy source (using $cpprog) instead of moving (using $mvprog).
 | 
			
		||||
-d         create directories instead of installing files.
 | 
			
		||||
-g GROUP   $chgrpprog installed files to GROUP.
 | 
			
		||||
-m MODE    $chmodprog installed files to MODE.
 | 
			
		||||
-o USER    $chownprog installed files to USER.
 | 
			
		||||
-s         $stripprog installed files.
 | 
			
		||||
-t DIRECTORY  install into DIRECTORY.
 | 
			
		||||
-T         report an error if DSTFILE is a directory.
 | 
			
		||||
-g GROUP   $chgrp installed files to GROUP.
 | 
			
		||||
-m MODE    $chmod installed files to MODE.
 | 
			
		||||
-o USER    $chown installed files to USER.
 | 
			
		||||
-s         strip installed files (using $stripprog).
 | 
			
		||||
-t=TRANSFORM
 | 
			
		||||
--help     display this help and exit.
 | 
			
		||||
--version  display version info and exit.
 | 
			
		||||
 | 
			
		||||
@@ -110,9 +93,14 @@ Environment variables override the default commands:
 | 
			
		||||
  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
while test $# -ne 0; do
 | 
			
		||||
while test -n "$1"; do
 | 
			
		||||
  case $1 in
 | 
			
		||||
    -c) shift
 | 
			
		||||
    -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
 | 
			
		||||
        shift
 | 
			
		||||
        continue;;
 | 
			
		||||
 | 
			
		||||
    -c) instcmd=$cpprog
 | 
			
		||||
        shift
 | 
			
		||||
        continue;;
 | 
			
		||||
 | 
			
		||||
    -d) dir_arg=true
 | 
			
		||||
@@ -124,17 +112,11 @@ while test $# -ne 0; do
 | 
			
		||||
        shift
 | 
			
		||||
        continue;;
 | 
			
		||||
 | 
			
		||||
    --help) echo "$usage"; exit $?;;
 | 
			
		||||
    --help) echo "$usage"; exit 0;;
 | 
			
		||||
 | 
			
		||||
    -m) mode=$2
 | 
			
		||||
    -m) chmodcmd="$chmodprog $2"
 | 
			
		||||
        shift
 | 
			
		||||
        shift
 | 
			
		||||
	case $mode in
 | 
			
		||||
	  *' '* | *'	'* | *'
 | 
			
		||||
'*	  | *'*'* | *'?'* | *'['*)
 | 
			
		||||
	    echo "$0: invalid mode: $mode" >&2
 | 
			
		||||
	    exit 1;;
 | 
			
		||||
	esac
 | 
			
		||||
        continue;;
 | 
			
		||||
 | 
			
		||||
    -o) chowncmd="$chownprog $2"
 | 
			
		||||
@@ -146,358 +128,155 @@ while test $# -ne 0; do
 | 
			
		||||
        shift
 | 
			
		||||
        continue;;
 | 
			
		||||
 | 
			
		||||
    -t) dstarg=$2
 | 
			
		||||
	shift
 | 
			
		||||
	shift
 | 
			
		||||
	continue;;
 | 
			
		||||
    -t=*) transformarg=`echo $1 | sed 's/-t=//'`
 | 
			
		||||
        shift
 | 
			
		||||
        continue;;
 | 
			
		||||
 | 
			
		||||
    -T) no_target_directory=true
 | 
			
		||||
	shift
 | 
			
		||||
	continue;;
 | 
			
		||||
    --version) echo "$0 $scriptversion"; exit 0;;
 | 
			
		||||
 | 
			
		||||
    --version) echo "$0 $scriptversion"; exit $?;;
 | 
			
		||||
 | 
			
		||||
    --)	shift
 | 
			
		||||
	break;;
 | 
			
		||||
 | 
			
		||||
    -*)	echo "$0: invalid option: $1" >&2
 | 
			
		||||
	exit 1;;
 | 
			
		||||
 | 
			
		||||
    *)  break;;
 | 
			
		||||
    *)  if test -z "$src"; then
 | 
			
		||||
          src=$1
 | 
			
		||||
        else
 | 
			
		||||
          # this colon is to work around a 386BSD /bin/sh bug
 | 
			
		||||
          :
 | 
			
		||||
          dst=$1
 | 
			
		||||
        fi
 | 
			
		||||
        shift
 | 
			
		||||
        continue;;
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
 | 
			
		||||
  # When -d is used, all remaining arguments are directories to create.
 | 
			
		||||
  # When -t is used, the destination is already specified.
 | 
			
		||||
  # Otherwise, the last argument is the destination.  Remove it from $@.
 | 
			
		||||
  for arg
 | 
			
		||||
  do
 | 
			
		||||
    if test -n "$dstarg"; then
 | 
			
		||||
      # $@ is not empty: it contains at least $arg.
 | 
			
		||||
      set fnord "$@" "$dstarg"
 | 
			
		||||
      shift # fnord
 | 
			
		||||
    fi
 | 
			
		||||
    shift # arg
 | 
			
		||||
    dstarg=$arg
 | 
			
		||||
if test -z "$src"; then
 | 
			
		||||
  echo "$0: no input file specified." >&2
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -n "$dir_arg"; then
 | 
			
		||||
  dst=$src
 | 
			
		||||
  src=
 | 
			
		||||
 | 
			
		||||
  if test -d "$dst"; then
 | 
			
		||||
    instcmd=:
 | 
			
		||||
    chmodcmd=
 | 
			
		||||
  else
 | 
			
		||||
    instcmd=$mkdirprog
 | 
			
		||||
  fi
 | 
			
		||||
else
 | 
			
		||||
  # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
 | 
			
		||||
  # might cause directories to be created, which would be especially bad
 | 
			
		||||
  # if $src (and thus $dsttmp) contains '*'.
 | 
			
		||||
  if test ! -f "$src" && test ! -d "$src"; then
 | 
			
		||||
    echo "$0: $src does not exist." >&2
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if test -z "$dst"; then
 | 
			
		||||
    echo "$0: no destination specified." >&2
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # If destination is a directory, append the input filename; won't work
 | 
			
		||||
  # if double slashes aren't ignored.
 | 
			
		||||
  if test -d "$dst"; then
 | 
			
		||||
    dst=$dst/`basename "$src"`
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
## this sed command emulates the dirname command
 | 
			
		||||
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
 | 
			
		||||
 | 
			
		||||
# Make sure that the destination directory exists.
 | 
			
		||||
# (this part is taken from Noah Friedman's mkinstalldirs script.)
 | 
			
		||||
 | 
			
		||||
# Skip lots of stat calls in the usual case.
 | 
			
		||||
if test ! -d "$dstdir"; then
 | 
			
		||||
  defaultIFS='
 | 
			
		||||
	'
 | 
			
		||||
  IFS="${IFS-$defaultIFS}"
 | 
			
		||||
 | 
			
		||||
  oIFS=$IFS
 | 
			
		||||
  # Some sh's can't handle IFS=/ for some reason.
 | 
			
		||||
  IFS='%'
 | 
			
		||||
  set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
 | 
			
		||||
  IFS=$oIFS
 | 
			
		||||
 | 
			
		||||
  pathcomp=
 | 
			
		||||
 | 
			
		||||
  while test $# -ne 0 ; do
 | 
			
		||||
    pathcomp=$pathcomp$1
 | 
			
		||||
    shift
 | 
			
		||||
    test -d "$pathcomp" || $mkdirprog "$pathcomp"
 | 
			
		||||
    pathcomp=$pathcomp/
 | 
			
		||||
  done
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test $# -eq 0; then
 | 
			
		||||
  if test -z "$dir_arg"; then
 | 
			
		||||
    echo "$0: no input file specified." >&2
 | 
			
		||||
    exit 1
 | 
			
		||||
  fi
 | 
			
		||||
  # It's OK to call `install-sh -d' without argument.
 | 
			
		||||
  # This can happen when creating conditional directories.
 | 
			
		||||
  exit 0
 | 
			
		||||
fi
 | 
			
		||||
if test -n "$dir_arg"; then
 | 
			
		||||
  $doit $instcmd "$dst" \
 | 
			
		||||
    && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
 | 
			
		||||
    && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
 | 
			
		||||
    && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
 | 
			
		||||
    && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
 | 
			
		||||
 | 
			
		||||
if test -z "$dir_arg"; then
 | 
			
		||||
else
 | 
			
		||||
  # If we're going to rename the final executable, determine the name now.
 | 
			
		||||
  if test -z "$transformarg"; then
 | 
			
		||||
    dstfile=`basename "$dst"`
 | 
			
		||||
  else
 | 
			
		||||
    dstfile=`basename "$dst" $transformbasename \
 | 
			
		||||
             | sed $transformarg`$transformbasename
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # don't allow the sed command to completely eliminate the filename.
 | 
			
		||||
  test -z "$dstfile" && dstfile=`basename "$dst"`
 | 
			
		||||
 | 
			
		||||
  # Make a couple of temp file names in the proper directory.
 | 
			
		||||
  dsttmp=$dstdir/_inst.$$_
 | 
			
		||||
  rmtmp=$dstdir/_rm.$$_
 | 
			
		||||
 | 
			
		||||
  # Trap to clean up those temp files at exit.
 | 
			
		||||
  trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
 | 
			
		||||
  trap '(exit $?); exit' 1 2 13 15
 | 
			
		||||
 | 
			
		||||
  # Set umask so as not to create temps with too-generous modes.
 | 
			
		||||
  # However, 'strip' requires both read and write access to temps.
 | 
			
		||||
  case $mode in
 | 
			
		||||
    # Optimize common cases.
 | 
			
		||||
    *644) cp_umask=133;;
 | 
			
		||||
    *755) cp_umask=22;;
 | 
			
		||||
  # Move or copy the file name to the temp name
 | 
			
		||||
  $doit $instcmd "$src" "$dsttmp" &&
 | 
			
		||||
 | 
			
		||||
    *[0-7])
 | 
			
		||||
      if test -z "$stripcmd"; then
 | 
			
		||||
	u_plus_rw=
 | 
			
		||||
      else
 | 
			
		||||
	u_plus_rw='% 200'
 | 
			
		||||
      fi
 | 
			
		||||
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
 | 
			
		||||
    *)
 | 
			
		||||
      if test -z "$stripcmd"; then
 | 
			
		||||
	u_plus_rw=
 | 
			
		||||
      else
 | 
			
		||||
	u_plus_rw=,u+rw
 | 
			
		||||
      fi
 | 
			
		||||
      cp_umask=$mode$u_plus_rw;;
 | 
			
		||||
  esac
 | 
			
		||||
fi
 | 
			
		||||
  # and set any options; do chmod last to preserve setuid bits.
 | 
			
		||||
  #
 | 
			
		||||
  # If any of these fail, we abort the whole thing.  If we want to
 | 
			
		||||
  # ignore errors from any of these, just make sure not to ignore
 | 
			
		||||
  # errors from the above "$doit $instcmd $src $dsttmp" command.
 | 
			
		||||
  #
 | 
			
		||||
  { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
 | 
			
		||||
    && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
 | 
			
		||||
    && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
 | 
			
		||||
    && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
 | 
			
		||||
 | 
			
		||||
for src
 | 
			
		||||
do
 | 
			
		||||
  # Protect names starting with `-'.
 | 
			
		||||
  case $src in
 | 
			
		||||
    -*) src=./$src ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  if test -n "$dir_arg"; then
 | 
			
		||||
    dst=$src
 | 
			
		||||
    dstdir=$dst
 | 
			
		||||
    test -d "$dstdir"
 | 
			
		||||
    dstdir_status=$?
 | 
			
		||||
  else
 | 
			
		||||
 | 
			
		||||
    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
 | 
			
		||||
    # might cause directories to be created, which would be especially bad
 | 
			
		||||
    # if $src (and thus $dsttmp) contains '*'.
 | 
			
		||||
    if test ! -f "$src" && test ! -d "$src"; then
 | 
			
		||||
      echo "$0: $src does not exist." >&2
 | 
			
		||||
      exit 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if test -z "$dstarg"; then
 | 
			
		||||
      echo "$0: no destination specified." >&2
 | 
			
		||||
      exit 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    dst=$dstarg
 | 
			
		||||
    # Protect names starting with `-'.
 | 
			
		||||
    case $dst in
 | 
			
		||||
      -*) dst=./$dst ;;
 | 
			
		||||
    esac
 | 
			
		||||
 | 
			
		||||
    # If destination is a directory, append the input filename; won't work
 | 
			
		||||
    # if double slashes aren't ignored.
 | 
			
		||||
    if test -d "$dst"; then
 | 
			
		||||
      if test -n "$no_target_directory"; then
 | 
			
		||||
	echo "$0: $dstarg: Is a directory" >&2
 | 
			
		||||
	exit 1
 | 
			
		||||
      fi
 | 
			
		||||
      dstdir=$dst
 | 
			
		||||
      dst=$dstdir/`basename "$src"`
 | 
			
		||||
      dstdir_status=0
 | 
			
		||||
    else
 | 
			
		||||
      # Prefer dirname, but fall back on a substitute if dirname fails.
 | 
			
		||||
      dstdir=`
 | 
			
		||||
	(dirname "$dst") 2>/dev/null ||
 | 
			
		||||
	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 | 
			
		||||
	     X"$dst" : 'X\(//\)[^/]' \| \
 | 
			
		||||
	     X"$dst" : 'X\(//\)$' \| \
 | 
			
		||||
	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
 | 
			
		||||
	echo X"$dst" |
 | 
			
		||||
	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 | 
			
		||||
		   s//\1/
 | 
			
		||||
		   q
 | 
			
		||||
		 }
 | 
			
		||||
		 /^X\(\/\/\)[^/].*/{
 | 
			
		||||
		   s//\1/
 | 
			
		||||
		   q
 | 
			
		||||
		 }
 | 
			
		||||
		 /^X\(\/\/\)$/{
 | 
			
		||||
		   s//\1/
 | 
			
		||||
		   q
 | 
			
		||||
		 }
 | 
			
		||||
		 /^X\(\/\).*/{
 | 
			
		||||
		   s//\1/
 | 
			
		||||
		   q
 | 
			
		||||
		 }
 | 
			
		||||
		 s/.*/./; q'
 | 
			
		||||
      `
 | 
			
		||||
 | 
			
		||||
      test -d "$dstdir"
 | 
			
		||||
      dstdir_status=$?
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  obsolete_mkdir_used=false
 | 
			
		||||
 | 
			
		||||
  if test $dstdir_status != 0; then
 | 
			
		||||
    case $posix_mkdir in
 | 
			
		||||
      '')
 | 
			
		||||
	# Create intermediate dirs using mode 755 as modified by the umask.
 | 
			
		||||
	# This is like FreeBSD 'install' as of 1997-10-28.
 | 
			
		||||
	umask=`umask`
 | 
			
		||||
	case $stripcmd.$umask in
 | 
			
		||||
	  # Optimize common cases.
 | 
			
		||||
	  *[2367][2367]) mkdir_umask=$umask;;
 | 
			
		||||
	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
 | 
			
		||||
 | 
			
		||||
	  *[0-7])
 | 
			
		||||
	    mkdir_umask=`expr $umask + 22 \
 | 
			
		||||
	      - $umask % 100 % 40 + $umask % 20 \
 | 
			
		||||
	      - $umask % 10 % 4 + $umask % 2
 | 
			
		||||
	    `;;
 | 
			
		||||
	  *) mkdir_umask=$umask,go-w;;
 | 
			
		||||
	esac
 | 
			
		||||
 | 
			
		||||
	# With -d, create the new directory with the user-specified mode.
 | 
			
		||||
	# Otherwise, rely on $mkdir_umask.
 | 
			
		||||
	if test -n "$dir_arg"; then
 | 
			
		||||
	  mkdir_mode=-m$mode
 | 
			
		||||
	else
 | 
			
		||||
	  mkdir_mode=
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	posix_mkdir=false
 | 
			
		||||
	case $umask in
 | 
			
		||||
	  *[123567][0-7][0-7])
 | 
			
		||||
	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
 | 
			
		||||
	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
 | 
			
		||||
	    ;;
 | 
			
		||||
	  *)
 | 
			
		||||
	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
 | 
			
		||||
	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
 | 
			
		||||
 | 
			
		||||
	    if (umask $mkdir_umask &&
 | 
			
		||||
		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
 | 
			
		||||
	    then
 | 
			
		||||
	      if test -z "$dir_arg" || {
 | 
			
		||||
		   # Check for POSIX incompatibilities with -m.
 | 
			
		||||
		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
 | 
			
		||||
		   # other-writeable bit of parent directory when it shouldn't.
 | 
			
		||||
		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
 | 
			
		||||
		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
 | 
			
		||||
		   case $ls_ld_tmpdir in
 | 
			
		||||
		     d????-?r-*) different_mode=700;;
 | 
			
		||||
		     d????-?--*) different_mode=755;;
 | 
			
		||||
		     *) false;;
 | 
			
		||||
		   esac &&
 | 
			
		||||
		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
 | 
			
		||||
		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
 | 
			
		||||
		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
 | 
			
		||||
		   }
 | 
			
		||||
		 }
 | 
			
		||||
	      then posix_mkdir=:
 | 
			
		||||
	      fi
 | 
			
		||||
	      rmdir "$tmpdir/d" "$tmpdir"
 | 
			
		||||
	    else
 | 
			
		||||
	      # Remove any dirs left behind by ancient mkdir implementations.
 | 
			
		||||
	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
 | 
			
		||||
	    fi
 | 
			
		||||
	    trap '' 0;;
 | 
			
		||||
	esac;;
 | 
			
		||||
    esac
 | 
			
		||||
 | 
			
		||||
    if
 | 
			
		||||
      $posix_mkdir && (
 | 
			
		||||
	umask $mkdir_umask &&
 | 
			
		||||
	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
 | 
			
		||||
      )
 | 
			
		||||
    then :
 | 
			
		||||
    else
 | 
			
		||||
 | 
			
		||||
      # The umask is ridiculous, or mkdir does not conform to POSIX,
 | 
			
		||||
      # or it failed possibly due to a race condition.  Create the
 | 
			
		||||
      # directory the slow way, step by step, checking for races as we go.
 | 
			
		||||
 | 
			
		||||
      case $dstdir in
 | 
			
		||||
	/*) prefix=/ ;;
 | 
			
		||||
	-*) prefix=./ ;;
 | 
			
		||||
	*)  prefix= ;;
 | 
			
		||||
      esac
 | 
			
		||||
 | 
			
		||||
      case $posix_glob in
 | 
			
		||||
        '')
 | 
			
		||||
	  if (set -f) 2>/dev/null; then
 | 
			
		||||
	    posix_glob=true
 | 
			
		||||
	  else
 | 
			
		||||
	    posix_glob=false
 | 
			
		||||
	  fi ;;
 | 
			
		||||
      esac
 | 
			
		||||
 | 
			
		||||
      oIFS=$IFS
 | 
			
		||||
      IFS=/
 | 
			
		||||
      $posix_glob && set -f
 | 
			
		||||
      set fnord $dstdir
 | 
			
		||||
      shift
 | 
			
		||||
      $posix_glob && set +f
 | 
			
		||||
      IFS=$oIFS
 | 
			
		||||
 | 
			
		||||
      prefixes=
 | 
			
		||||
 | 
			
		||||
      for d
 | 
			
		||||
      do
 | 
			
		||||
	test -z "$d" && continue
 | 
			
		||||
 | 
			
		||||
	prefix=$prefix$d
 | 
			
		||||
	if test -d "$prefix"; then
 | 
			
		||||
	  prefixes=
 | 
			
		||||
	else
 | 
			
		||||
	  if $posix_mkdir; then
 | 
			
		||||
	    (umask=$mkdir_umask &&
 | 
			
		||||
	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
 | 
			
		||||
	    # Don't fail if two instances are running concurrently.
 | 
			
		||||
	    test -d "$prefix" || exit 1
 | 
			
		||||
	  else
 | 
			
		||||
	    case $prefix in
 | 
			
		||||
	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
 | 
			
		||||
	      *) qprefix=$prefix;;
 | 
			
		||||
	    esac
 | 
			
		||||
	    prefixes="$prefixes '$qprefix'"
 | 
			
		||||
	  fi
 | 
			
		||||
	fi
 | 
			
		||||
	prefix=$prefix/
 | 
			
		||||
      done
 | 
			
		||||
 | 
			
		||||
      if test -n "$prefixes"; then
 | 
			
		||||
	# Don't fail if two instances are running concurrently.
 | 
			
		||||
	(umask $mkdir_umask &&
 | 
			
		||||
	 eval "\$doit_exec \$mkdirprog $prefixes") ||
 | 
			
		||||
	  test -d "$dstdir" || exit 1
 | 
			
		||||
	obsolete_mkdir_used=true
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if test -n "$dir_arg"; then
 | 
			
		||||
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
 | 
			
		||||
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
 | 
			
		||||
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
 | 
			
		||||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
 | 
			
		||||
  else
 | 
			
		||||
 | 
			
		||||
    # Make a couple of temp file names in the proper directory.
 | 
			
		||||
    dsttmp=$dstdir/_inst.$$_
 | 
			
		||||
    rmtmp=$dstdir/_rm.$$_
 | 
			
		||||
 | 
			
		||||
    # Trap to clean up those temp files at exit.
 | 
			
		||||
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 | 
			
		||||
 | 
			
		||||
    # Copy the file name to the temp name.
 | 
			
		||||
    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
 | 
			
		||||
 | 
			
		||||
    # and set any options; do chmod last to preserve setuid bits.
 | 
			
		||||
    #
 | 
			
		||||
    # If any of these fail, we abort the whole thing.  If we want to
 | 
			
		||||
    # ignore errors from any of these, just make sure not to ignore
 | 
			
		||||
    # errors from the above "$doit $cpprog $src $dsttmp" command.
 | 
			
		||||
    #
 | 
			
		||||
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
 | 
			
		||||
      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
 | 
			
		||||
      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
 | 
			
		||||
      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
 | 
			
		||||
 | 
			
		||||
    # Now rename the file to the real destination.
 | 
			
		||||
    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
 | 
			
		||||
  # Now remove or move aside any old file at destination location.  We
 | 
			
		||||
  # try this two ways since rm can't unlink itself on some systems and
 | 
			
		||||
  # the destination file might be busy for other reasons.  In this case,
 | 
			
		||||
  # the final cleanup might fail but the new file should still install
 | 
			
		||||
  # successfully.
 | 
			
		||||
  {
 | 
			
		||||
    if test -f "$dstdir/$dstfile"; then
 | 
			
		||||
      $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
 | 
			
		||||
      || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
 | 
			
		||||
      || {
 | 
			
		||||
	   # The rename failed, perhaps because mv can't rename something else
 | 
			
		||||
	   # to itself, or perhaps because mv is so ancient that it does not
 | 
			
		||||
	   # support -f.
 | 
			
		||||
	  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
 | 
			
		||||
	  (exit 1); exit
 | 
			
		||||
      }
 | 
			
		||||
    else
 | 
			
		||||
      :
 | 
			
		||||
    fi
 | 
			
		||||
  } &&
 | 
			
		||||
 | 
			
		||||
	   # Now remove or move aside any old file at destination location.
 | 
			
		||||
	   # We try this two ways since rm can't unlink itself on some
 | 
			
		||||
	   # systems and the destination file might be busy for other
 | 
			
		||||
	   # reasons.  In this case, the final cleanup might fail but the new
 | 
			
		||||
	   # file should still install successfully.
 | 
			
		||||
	   {
 | 
			
		||||
	     if test -f "$dst"; then
 | 
			
		||||
	       $doit $rmcmd -f "$dst" 2>/dev/null \
 | 
			
		||||
	       || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
 | 
			
		||||
		     && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
 | 
			
		||||
	       || {
 | 
			
		||||
		 echo "$0: cannot unlink or rename $dst" >&2
 | 
			
		||||
		 (exit 1); exit 1
 | 
			
		||||
	       }
 | 
			
		||||
	     else
 | 
			
		||||
	       :
 | 
			
		||||
	     fi
 | 
			
		||||
	   } &&
 | 
			
		||||
  # Now rename the file to the real destination.
 | 
			
		||||
  $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
 | 
			
		||||
fi &&
 | 
			
		||||
 | 
			
		||||
	   # Now rename the file to the real destination.
 | 
			
		||||
	   $doit $mvcmd "$dsttmp" "$dst"
 | 
			
		||||
	 }
 | 
			
		||||
    } || exit 1
 | 
			
		||||
 | 
			
		||||
    trap '' 0
 | 
			
		||||
  fi
 | 
			
		||||
done
 | 
			
		||||
# The final little trick to "correctly" pass the exit status to the exit trap.
 | 
			
		||||
{
 | 
			
		||||
  (exit 0); exit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Local variables:
 | 
			
		||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU General Public License v.2.
 | 
			
		||||
#
 | 
			
		||||
# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
CONFSRC=example.conf
 | 
			
		||||
CONFDEST=lvm.conf
 | 
			
		||||
CONFLOCAL=lvmlocal.conf
 | 
			
		||||
 | 
			
		||||
PROFILE_TEMPLATES=command_profile_template.profile metadata_profile_template.profile
 | 
			
		||||
PROFILES=$(PROFILE_TEMPLATES) $(srcdir)/thin-generic.profile $(srcdir)/thin-performance.profile
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
.PHONY: install_conf install_localconf install_profiles
 | 
			
		||||
 | 
			
		||||
generate:
 | 
			
		||||
	(cat $(top_srcdir)/conf/example.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withfullcomments --ignorelocal) > example.conf.in
 | 
			
		||||
	(cat $(top_srcdir)/conf/lvmlocal.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withfullcomments local) > lvmlocal.conf.in
 | 
			
		||||
 | 
			
		||||
install_conf: $(CONFSRC)
 | 
			
		||||
	@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
 | 
			
		||||
		echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST)"; \
 | 
			
		||||
		$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST); \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
install_localconf: $(CONFLOCAL)
 | 
			
		||||
	@if [ ! -e $(confdir)/$(CONFLOCAL) ]; then \
 | 
			
		||||
		echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL)"; \
 | 
			
		||||
		$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL); \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
install_profiles: $(PROFILES)
 | 
			
		||||
	$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_PROFILE_DIR)
 | 
			
		||||
	$(INSTALL_DATA) $(PROFILES) $(DESTDIR)$(DEFAULT_PROFILE_DIR)/
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_conf install_localconf install_profiles
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
 | 
			
		||||
DISTCLEAN_TARGETS += $(CONFSRC) $(CONFLOCAL) $(PROFILE_TEMPLATES)
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
# This is a command profile template for the LVM2 system.
 | 
			
		||||
#
 | 
			
		||||
# It contains all configuration settings that are customizable by command
 | 
			
		||||
# profiles. To create a new command profile, select the settings you want
 | 
			
		||||
# to customize and add them in a new file named <profile_name>.profile.
 | 
			
		||||
# Then install the new profile in a directory as defined by config/profile_dir
 | 
			
		||||
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
 | 
			
		||||
#
 | 
			
		||||
# Command profiles can be referenced by using the --commandprofile option then.
 | 
			
		||||
#
 | 
			
		||||
# Refer to 'man lvm.conf' for further information about profiles and
 | 
			
		||||
# general configuration file layout.
 | 
			
		||||
#
 | 
			
		||||
global {
 | 
			
		||||
	units="h"
 | 
			
		||||
	si_unit_consistency=1
 | 
			
		||||
	suffix=1
 | 
			
		||||
	lvdisplay_shows_full_device_path=0
 | 
			
		||||
}
 | 
			
		||||
report {
 | 
			
		||||
	compact_output=0
 | 
			
		||||
	aligned=1
 | 
			
		||||
	buffered=1
 | 
			
		||||
	headings=1
 | 
			
		||||
	separator=" "
 | 
			
		||||
	list_item_separator=","
 | 
			
		||||
	prefixes=0
 | 
			
		||||
	quoted=1
 | 
			
		||||
	colums_as_rows=0
 | 
			
		||||
	binary_values_as_numeric=0
 | 
			
		||||
	devtypes_sort="devtype_name"
 | 
			
		||||
	devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
 | 
			
		||||
	devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
 | 
			
		||||
	lvs_sort="vg_name,lv_name"
 | 
			
		||||
	lvs_cols="lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
 | 
			
		||||
	lvs_cols_verbose="lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"
 | 
			
		||||
	vgs_sort="vg_name"
 | 
			
		||||
	vgs_cols="vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
 | 
			
		||||
	vgs_cols_verbose="vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"
 | 
			
		||||
	pvs_sort="pv_name"
 | 
			
		||||
	pvs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
 | 
			
		||||
	pvs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
 | 
			
		||||
	segs_sort="vg_name,lv_name,seg_start"
 | 
			
		||||
	segs_cols="lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
 | 
			
		||||
	segs_cols_verbose="lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
 | 
			
		||||
	pvsegs_sort="pv_name,pvseg_start"
 | 
			
		||||
	pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
 | 
			
		||||
	pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
# This is an example configuration file for the LVM2 system.
 | 
			
		||||
# It contains the default settings that would be used if there was no
 | 
			
		||||
# @DEFAULT_SYS_DIR@/lvm.conf file.
 | 
			
		||||
#
 | 
			
		||||
# Refer to 'man lvm.conf' for further information including the file layout.
 | 
			
		||||
#
 | 
			
		||||
# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set
 | 
			
		||||
# the environment variable LVM_SYSTEM_DIR before running the tools.
 | 
			
		||||
#
 | 
			
		||||
# N.B. Take care that each setting only appears once if uncommenting
 | 
			
		||||
# example settings in this file.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1625
									
								
								conf/example.conf.in
									
									
									
									
									
								
							
							
						
						
									
										1625
									
								
								conf/example.conf.in
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,19 +0,0 @@
 | 
			
		||||
# This is a local configuration file template for the LVM2 system
 | 
			
		||||
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
 | 
			
		||||
#
 | 
			
		||||
# Refer to 'man lvm.conf' for information about the file layout.
 | 
			
		||||
#
 | 
			
		||||
# To put this file in a different directory and override
 | 
			
		||||
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
 | 
			
		||||
# running the tools.
 | 
			
		||||
#
 | 
			
		||||
# The lvmlocal.conf file is normally expected to contain only the
 | 
			
		||||
# "local" section which contains settings that should not be shared or
 | 
			
		||||
# repeated among different hosts.  (But if other sections are present,
 | 
			
		||||
# they *will* get processed.  Settings in this file override equivalent
 | 
			
		||||
# ones in lvm.conf and are in turn overridden by ones in any enabled
 | 
			
		||||
# lvm_<tag>.conf files.)
 | 
			
		||||
#
 | 
			
		||||
# Please take care that each setting only appears once if uncommenting
 | 
			
		||||
# example settings in this file and never copy this file between hosts.
 | 
			
		||||
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
# This is a local configuration file template for the LVM2 system
 | 
			
		||||
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
 | 
			
		||||
#
 | 
			
		||||
# Refer to 'man lvm.conf' for information about the file layout.
 | 
			
		||||
#
 | 
			
		||||
# To put this file in a different directory and override
 | 
			
		||||
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
 | 
			
		||||
# running the tools.
 | 
			
		||||
#
 | 
			
		||||
# The lvmlocal.conf file is normally expected to contain only the
 | 
			
		||||
# "local" section which contains settings that should not be shared or
 | 
			
		||||
# repeated among different hosts.  (But if other sections are present,
 | 
			
		||||
# they *will* get processed.  Settings in this file override equivalent
 | 
			
		||||
# ones in lvm.conf and are in turn overridden by ones in any enabled
 | 
			
		||||
# lvm_<tag>.conf files.)
 | 
			
		||||
#
 | 
			
		||||
# Please take care that each setting only appears once if uncommenting
 | 
			
		||||
# example settings in this file and never copy this file between hosts.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Configuration section local.
 | 
			
		||||
# LVM settings that are specific to the local host.
 | 
			
		||||
local {
 | 
			
		||||
 | 
			
		||||
	# Configuration option local/system_id.
 | 
			
		||||
	# Defines the local system ID for lvmlocal mode.
 | 
			
		||||
	# This is used when global/system_id_source is set
 | 
			
		||||
	# to 'lvmlocal' in the main configuration file,
 | 
			
		||||
	# e.g. lvm.conf.
 | 
			
		||||
	# When used, it must be set to a unique value
 | 
			
		||||
	# among all hosts sharing access to the storage,
 | 
			
		||||
	# e.g. a host name.
 | 
			
		||||
	# Example:
 | 
			
		||||
	# Set no system ID.
 | 
			
		||||
	# system_id = ""
 | 
			
		||||
	# Example:
 | 
			
		||||
	# Set the system_id to the string 'host1'.
 | 
			
		||||
	# system_id = "host1"
 | 
			
		||||
	# This configuration option does not have a default value defined.
 | 
			
		||||
#	system_id=""
 | 
			
		||||
 | 
			
		||||
	# Configuration option local/extra_system_ids.
 | 
			
		||||
	# A list of extra VG system IDs the local host can access.
 | 
			
		||||
	# VGs with the system IDs listed here (in addition
 | 
			
		||||
	# to the host's own system ID) can be fully accessed
 | 
			
		||||
	# by the local host.  (These are system IDs that the
 | 
			
		||||
	# host sees in VGs, not system IDs that identify the
 | 
			
		||||
	# local host, which is determined by system_id_source.)
 | 
			
		||||
	# Use this only after consulting 'man lvmsystemid'
 | 
			
		||||
	# to be certain of correct usage and possible dangers.
 | 
			
		||||
	# This configuration option does not have a default value defined.
 | 
			
		||||
#	extra_system_ids=[]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
# This is a metadata profile template for the LVM2 system.
 | 
			
		||||
#
 | 
			
		||||
# It contains all configuration settings that are customizable by metadata
 | 
			
		||||
# profiles. To create a new metadata profile, select the settings you want
 | 
			
		||||
# to customize and add them in a new file named <profile_name>.profile.
 | 
			
		||||
# Then install the new profile in a directory as defined by config/profile_dir
 | 
			
		||||
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
 | 
			
		||||
#
 | 
			
		||||
# Metadata profiles can be referenced by using the --metadataprofile LVM2
 | 
			
		||||
# command line option.
 | 
			
		||||
#
 | 
			
		||||
# Refer to 'man lvm.conf' for further information about profiles and
 | 
			
		||||
# general configuration file layout.
 | 
			
		||||
#
 | 
			
		||||
allocation {
 | 
			
		||||
	thin_pool_zero=1
 | 
			
		||||
	thin_pool_discards="passdown"
 | 
			
		||||
	thin_pool_chunk_size_policy="generic"
 | 
			
		||||
#	thin_pool_chunk_size=128
 | 
			
		||||
}
 | 
			
		||||
activation {
 | 
			
		||||
	thin_pool_autoextend_threshold=100
 | 
			
		||||
	thin_pool_autoextend_percent=20
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
allocation {
 | 
			
		||||
	thin_pool_chunk_size_policy = "generic"
 | 
			
		||||
	thin_pool_zero = 1
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
allocation {
 | 
			
		||||
	thin_pool_chunk_size_policy = "performance"
 | 
			
		||||
	thin_pool_zero = 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1943
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										1943
									
								
								configure.in
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
@@ -13,35 +13,11 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
.PHONY: dmeventd clvmd cmirrord lvmetad
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
ifneq ("@CLVMD@", "none")
 | 
			
		||||
  SUBDIRS += clvmd
 | 
			
		||||
  SUBDIRS = clvmd
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@BUILD_CMIRRORD@", "yes")
 | 
			
		||||
  SUBDIRS += cmirrord
 | 
			
		||||
endif
 | 
			
		||||
include $(top_srcdir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
ifeq ("@BUILD_DMEVENTD@", "yes")
 | 
			
		||||
  SUBDIRS += dmeventd
 | 
			
		||||
ifneq ("$(CFLOW_CMD)", "")
 | 
			
		||||
daemons.cflow: dmeventd.cflow
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@BUILD_LVMETAD@", "yes")
 | 
			
		||||
  SUBDIRS += lvmetad
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),distclean)
 | 
			
		||||
  SUBDIRS = clvmd cmirrord dmeventd lvmetad
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
ifeq ("@BUILD_DMEVENTD@", "yes")
 | 
			
		||||
device-mapper: dmeventd.device-mapper
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
@@ -13,22 +13,7 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
CMAN_LIBS = @CMAN_LIBS@
 | 
			
		||||
CMAN_CFLAGS = @CMAN_CFLAGS@
 | 
			
		||||
CMAP_LIBS = @CMAP_LIBS@
 | 
			
		||||
CMAP_CFLAGS = @CMAP_CFLAGS@
 | 
			
		||||
CONFDB_LIBS = @CONFDB_LIBS@
 | 
			
		||||
CONFDB_CFLAGS = @CONFDB_CFLAGS@
 | 
			
		||||
CPG_LIBS = @CPG_LIBS@
 | 
			
		||||
CPG_CFLAGS = @CPG_CFLAGS@
 | 
			
		||||
DLM_LIBS = @DLM_LIBS@
 | 
			
		||||
DLM_CFLAGS = @DLM_CFLAGS@
 | 
			
		||||
QUORUM_LIBS = @QUORUM_LIBS@
 | 
			
		||||
QUORUM_CFLAGS = @QUORUM_CFLAGS@
 | 
			
		||||
SALCK_LIBS = @SALCK_LIBS@
 | 
			
		||||
SALCK_CFLAGS = @SALCK_CFLAGS@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
SOURCES = \
 | 
			
		||||
	clvmd-command.c  \
 | 
			
		||||
@@ -36,72 +21,78 @@ SOURCES = \
 | 
			
		||||
	lvm-functions.c  \
 | 
			
		||||
	refresh_clvmd.c
 | 
			
		||||
 | 
			
		||||
ifeq ("@CLVMD@", "gulm")
 | 
			
		||||
	GULM = yes
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@CLVMD@", "cman")
 | 
			
		||||
	CMAN = yes
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@CLVMD@", "openais")
 | 
			
		||||
	OPENAIS = yes
 | 
			
		||||
	GULM = no
 | 
			
		||||
	CMAN = no
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@CLVMD@", "all")
 | 
			
		||||
	GULM = yes
 | 
			
		||||
	CMAN = yes
 | 
			
		||||
	OPENAIS = no
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@DEBUG@", "yes")
 | 
			
		||||
	DEFS += -DDEBUG
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq (,$(findstring cman,, "@CLVMD@,"))
 | 
			
		||||
ifeq ("$(GULM)", "yes")
 | 
			
		||||
	SOURCES += clvmd-gulm.c tcp-comms.c
 | 
			
		||||
	LMLIBS += -lccs -lgulm
 | 
			
		||||
	DEFS += -DUSE_GULM
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("$(CMAN)", "yes")
 | 
			
		||||
	SOURCES += clvmd-cman.c
 | 
			
		||||
	LMLIBS += $(CMAN_LIBS) $(CONFDB_LIBS) $(DLM_LIBS)
 | 
			
		||||
	CFLAGS += $(CMAN_CFLAGS) $(CONFDB_CFLAGS) $(DLM_CFLAGS)
 | 
			
		||||
	LMLIBS += -ldlm -lcman
 | 
			
		||||
	DEFS += -DUSE_CMAN
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq (,$(findstring openais,, "@CLVMD@,"))
 | 
			
		||||
ifeq ("$(OPENAIS)", "yes")
 | 
			
		||||
	SOURCES += clvmd-openais.c
 | 
			
		||||
	LMLIBS += $(CONFDB_LIBS) $(CPG_LIBS) $(SALCK_LIBS)
 | 
			
		||||
	CFLAGS += $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(SALCK_CFLAGS)
 | 
			
		||||
	LMLIBS += -lSaLck -lcpg
 | 
			
		||||
	DEFS += -DUSE_OPENAIS
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq (,$(findstring corosync,, "@CLVMD@,"))
 | 
			
		||||
	SOURCES += clvmd-corosync.c
 | 
			
		||||
	LMLIBS += $(CMAP_LIBS) $(CONFDB_LIBS) $(CPG_LIBS) $(DLM_LIBS) $(QUORUM_LIBS)
 | 
			
		||||
	CFLAGS += $(CMAP_CFLAGS) $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(DLM_CFLAGS) $(QUORUM_CFLAGS)
 | 
			
		||||
	DEFS += -DUSE_COROSYNC
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq (,$(findstring singlenode,, "@CLVMD@,"))
 | 
			
		||||
	SOURCES += clvmd-singlenode.c
 | 
			
		||||
	DEFS += -DUSE_SINGLENODE
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),distclean)
 | 
			
		||||
	SOURCES += clvmd-cman.c
 | 
			
		||||
	SOURCES += clvmd-openais.c
 | 
			
		||||
	SOURCES += clvmd-corosync.c
 | 
			
		||||
	SOURCES += clvmd-singlenode.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
TARGETS = \
 | 
			
		||||
	clvmd
 | 
			
		||||
 | 
			
		||||
LVMLIBS = $(LVMINTERNAL_LIBS)
 | 
			
		||||
LVMLIBS = -llvm -lpthread
 | 
			
		||||
 | 
			
		||||
ifeq ("@DMEVENTD@", "yes")
 | 
			
		||||
	LVMLIBS += -ldevmapper-event
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
LVMLIBS += -ldevmapper
 | 
			
		||||
LIBS += $(PTHREAD_LIBS)
 | 
			
		||||
 | 
			
		||||
CFLAGS += -fno-strict-aliasing $(EXTRA_EXEC_CFLAGS)
 | 
			
		||||
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
 | 
			
		||||
DEFS += -D_REENTRANT
 | 
			
		||||
CFLAGS += -fno-strict-aliasing
 | 
			
		||||
 | 
			
		||||
include $(top_srcdir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
INSTALL_TARGETS = \
 | 
			
		||||
	install_clvmd
 | 
			
		||||
 | 
			
		||||
clvmd: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
 | 
			
		||||
	$(CC) $(CFLAGS) $(LDFLAGS) -o clvmd $(OBJECTS) \
 | 
			
		||||
clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
 | 
			
		||||
	$(CC) -o clvmd $(OBJECTS) $(CFLAGS) $(LDFLAGS) \
 | 
			
		||||
		$(LVMLIBS) $(LMLIBS) $(LIBS)
 | 
			
		||||
 | 
			
		||||
.PHONY: install_clvmd
 | 
			
		||||
 | 
			
		||||
install_clvmd: $(TARGETS)
 | 
			
		||||
	$(INSTALL_PROGRAM) -D clvmd $(usrsbindir)/clvmd
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
 | 
			
		||||
		$(sbindir)/clvmd
 | 
			
		||||
 | 
			
		||||
install: $(INSTALL_TARGETS)
 | 
			
		||||
 | 
			
		||||
install_cluster: $(INSTALL_TARGETS)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
@@ -22,40 +22,37 @@
 | 
			
		||||
#ifndef _CLVM_H
 | 
			
		||||
#define _CLVM_H
 | 
			
		||||
 | 
			
		||||
#include "configure.h"
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
struct clvm_header {
 | 
			
		||||
	uint8_t  cmd;	        /* See below */
 | 
			
		||||
	uint8_t  flags;	        /* See below */
 | 
			
		||||
	uint16_t xid;	        /* Transaction ID */
 | 
			
		||||
	uint32_t clientid;	/* Only used in Daemon->Daemon comms */
 | 
			
		||||
	int32_t  status;	/* For replies, whether request succeeded */
 | 
			
		||||
	uint32_t arglen;	/* Length of argument below.
 | 
			
		||||
				   If >1500 then it will be passed
 | 
			
		||||
	uint32_t arglen;	/* Length of argument below. 
 | 
			
		||||
				   If >1500 then it will be passed 
 | 
			
		||||
				   around the cluster in the system LV */
 | 
			
		||||
	char node[1];		/* Actually a NUL-terminated string, node name.
 | 
			
		||||
				   If this is empty then the command is
 | 
			
		||||
				   forwarded to all cluster nodes unless
 | 
			
		||||
				   FLAG_LOCAL or FLAG_REMOTE is also set. */
 | 
			
		||||
	char args[1];		/* Arguments for the command follow the
 | 
			
		||||
				   If this is empty then the command is 
 | 
			
		||||
				   forwarded to all cluster nodes unless 
 | 
			
		||||
				   FLAG_LOCAL is also set. */
 | 
			
		||||
	char args[1];		/* Arguments for the command follow the 
 | 
			
		||||
				   node name, This member is only
 | 
			
		||||
				   valid if the node name is empty */
 | 
			
		||||
} __attribute__ ((packed));
 | 
			
		||||
 | 
			
		||||
/* Flags */
 | 
			
		||||
#define CLVMD_FLAG_LOCAL	1	/* Only do this on the local node */
 | 
			
		||||
#define CLVMD_FLAG_SYSTEMLV	2	/* Data in system LV under my node name */
 | 
			
		||||
#define CLVMD_FLAG_NODEERRS	4	/* Reply has errors in node-specific portion */
 | 
			
		||||
#define CLVMD_FLAG_REMOTE	8	/* Do this on all nodes except for the local node */
 | 
			
		||||
#define CLVMD_FLAG_LOCAL        1	/* Only do this on the local node */
 | 
			
		||||
#define CLVMD_FLAG_SYSTEMLV     2	/* Data in system LV under my node name */
 | 
			
		||||
#define CLVMD_FLAG_NODEERRS     4       /* Reply has errors in node-specific portion */
 | 
			
		||||
 | 
			
		||||
/* Name of the local socket to communicate between lvm and clvmd */
 | 
			
		||||
static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
 | 
			
		||||
/* Name of the local socket to communicate between libclvm and clvmd */
 | 
			
		||||
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd";
 | 
			
		||||
static const char CLVMD_SOCKNAME[] = "\0clvmd";
 | 
			
		||||
 | 
			
		||||
/* Internal commands & replies */
 | 
			
		||||
#define CLVMD_CMD_REPLY    1
 | 
			
		||||
#define CLVMD_CMD_VERSION  2	/* Send version around cluster when we start */
 | 
			
		||||
#define CLVMD_CMD_GOAWAY   3	/* Die if received this - we are running
 | 
			
		||||
#define CLVMD_CMD_GOAWAY   3	/* Die if received this - we are running 
 | 
			
		||||
				   an incompatible version */
 | 
			
		||||
#define CLVMD_CMD_TEST     4	/* Just for mucking about */
 | 
			
		||||
 | 
			
		||||
@@ -65,19 +62,9 @@ static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
 | 
			
		||||
/* Lock/Unlock commands */
 | 
			
		||||
#define CLVMD_CMD_LOCK_LV           50
 | 
			
		||||
#define CLVMD_CMD_LOCK_VG           51
 | 
			
		||||
#define CLVMD_CMD_LOCK_QUERY	    52
 | 
			
		||||
 | 
			
		||||
/* Misc functions */
 | 
			
		||||
#define CLVMD_CMD_REFRESH	    40
 | 
			
		||||
#define CLVMD_CMD_GET_CLUSTERNAME   41
 | 
			
		||||
#define CLVMD_CMD_SET_DEBUG	    42
 | 
			
		||||
#define CLVMD_CMD_VG_BACKUP	    43
 | 
			
		||||
#define CLVMD_CMD_RESTART	    44
 | 
			
		||||
#define CLVMD_CMD_SYNC_NAMES	    45
 | 
			
		||||
 | 
			
		||||
/* Used internally by some callers, but not part of the protocol.*/
 | 
			
		||||
#define NODE_ALL	"*"
 | 
			
		||||
#define NODE_LOCAL	"."
 | 
			
		||||
#define NODE_REMOTE	"^"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -17,32 +17,42 @@
 | 
			
		||||
 * CMAN communication layer for clvmd.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clvmd-common.h"
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/uio.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <libdlm.h>
 | 
			
		||||
 | 
			
		||||
#include "clvmd-comms.h"
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "clvmd.h"
 | 
			
		||||
#include "lvm-functions.h"
 | 
			
		||||
 | 
			
		||||
#include <libdlm.h>
 | 
			
		||||
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
#define LOCKSPACE_NAME "clvmd"
 | 
			
		||||
 | 
			
		||||
struct clvmd_node
 | 
			
		||||
{
 | 
			
		||||
	struct cman_node *node;
 | 
			
		||||
	int clvmd_up;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int num_nodes;
 | 
			
		||||
static struct cman_node *nodes = NULL;
 | 
			
		||||
static struct cman_node this_node;
 | 
			
		||||
static int count_nodes; /* size of allocated nodes array */
 | 
			
		||||
static struct dm_hash_table *node_updown_hash;
 | 
			
		||||
static int max_updown_nodes = 50;	/* Current size of the allocated array */
 | 
			
		||||
/* Node up/down status, indexed by nodeid */
 | 
			
		||||
static int *node_updown = NULL;
 | 
			
		||||
static dlm_lshandle_t *lockspace;
 | 
			
		||||
static cman_handle_t c_handle;
 | 
			
		||||
 | 
			
		||||
@@ -62,8 +72,6 @@ struct lock_wait {
 | 
			
		||||
 | 
			
		||||
static int _init_cluster(void)
 | 
			
		||||
{
 | 
			
		||||
	node_updown_hash = dm_hash_create(100);
 | 
			
		||||
 | 
			
		||||
	/* Open the cluster communication socket */
 | 
			
		||||
	c_handle = cman_init(NULL);
 | 
			
		||||
	if (!c_handle) {
 | 
			
		||||
@@ -89,17 +97,11 @@ static int _init_cluster(void)
 | 
			
		||||
	DEBUGLOG("CMAN initialisation complete\n");
 | 
			
		||||
 | 
			
		||||
	/* Create a lockspace for LV & VG locks to live in */
 | 
			
		||||
	lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
 | 
			
		||||
	lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
 | 
			
		||||
	if (!lockspace) {
 | 
			
		||||
		lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
 | 
			
		||||
		if (!lockspace) {
 | 
			
		||||
			syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		DEBUGLOG("Created DLM lockspace for CLVMD.\n");
 | 
			
		||||
	} else
 | 
			
		||||
		DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
 | 
			
		||||
 | 
			
		||||
		syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	dlm_ls_pthread_init(lockspace);
 | 
			
		||||
	DEBUGLOG("DLM initialisation complete\n");
 | 
			
		||||
	return 0;
 | 
			
		||||
@@ -110,12 +112,12 @@ static void _cluster_init_completed(void)
 | 
			
		||||
	clvmd_cluster_init_completed();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_main_cluster_fd(void)
 | 
			
		||||
static int _get_main_cluster_fd()
 | 
			
		||||
{
 | 
			
		||||
	return cman_get_fd(c_handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_num_nodes(void)
 | 
			
		||||
static int _get_num_nodes()
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	int nnodes = 0;
 | 
			
		||||
@@ -163,10 +165,8 @@ static int _cluster_do_node_callback(struct local_client *client,
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < _get_num_nodes(); i++) {
 | 
			
		||||
		if (nodes[i].cn_member && nodes[i].cn_nodeid) {
 | 
			
		||||
			int up = (int)(long)dm_hash_lookup_binary(node_updown_hash, (char *)&nodes[i].cn_nodeid, sizeof(int));
 | 
			
		||||
 | 
			
		||||
			callback(client, (char *)&nodes[i].cn_nodeid, up);
 | 
			
		||||
			if (!up)
 | 
			
		||||
			callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
 | 
			
		||||
			if (!node_updown[nodes[i].cn_nodeid])
 | 
			
		||||
				somedown = -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -184,7 +184,7 @@ static void event_callback(cman_handle_t handle, void *private, int reason, int
 | 
			
		||||
		log_notice("clvmd on node %s has died\n", namebuf);
 | 
			
		||||
		DEBUGLOG("Got port closed message, removing node %s\n", namebuf);
 | 
			
		||||
 | 
			
		||||
		dm_hash_insert_binary(node_updown_hash, (char *)&arg, sizeof(int), (void *)0);
 | 
			
		||||
		node_updown[arg] = 0;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CMAN_REASON_STATECHANGE:
 | 
			
		||||
@@ -239,12 +239,28 @@ static void _add_up_node(const char *csid)
 | 
			
		||||
	/* It's up ! */
 | 
			
		||||
	int nodeid = nodeid_from_csid(csid);
 | 
			
		||||
 | 
			
		||||
	dm_hash_insert_binary(node_updown_hash, (char *)&nodeid, sizeof(int), (void *)1);
 | 
			
		||||
	if (nodeid >= max_updown_nodes) {
 | 
			
		||||
	        int new_size = nodeid + 10;
 | 
			
		||||
		int *new_updown = realloc(node_updown, new_size);
 | 
			
		||||
 | 
			
		||||
		if (new_updown) {
 | 
			
		||||
			node_updown = new_updown;
 | 
			
		||||
			max_updown_nodes = new_size;
 | 
			
		||||
			DEBUGLOG("realloced more space for nodes. now %d\n",
 | 
			
		||||
				 max_updown_nodes);
 | 
			
		||||
		} else {
 | 
			
		||||
			log_error
 | 
			
		||||
				("Realloc failed. Node status for clvmd will be wrong. quitting\n");
 | 
			
		||||
			exit(999);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	node_updown[nodeid] = 1;
 | 
			
		||||
	DEBUGLOG("Added new node %d to updown list\n", nodeid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _cluster_closedown(void)
 | 
			
		||||
static void _cluster_closedown()
 | 
			
		||||
{
 | 
			
		||||
	unlock_all();
 | 
			
		||||
	dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
 | 
			
		||||
	cman_finish(c_handle);
 | 
			
		||||
}
 | 
			
		||||
@@ -272,22 +288,15 @@ static void count_clvmds_running(void)
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < num_nodes; i++) {
 | 
			
		||||
		int nodeid = nodes[i].cn_nodeid;
 | 
			
		||||
 | 
			
		||||
		if (is_listening(nodeid) == 1)
 | 
			
		||||
			dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)1);
 | 
			
		||||
		else
 | 
			
		||||
			dm_hash_insert_binary(node_updown_hash, (void *)&nodeid, sizeof(int), (void*)0);
 | 
			
		||||
		node_updown[nodes[i].cn_nodeid] = is_listening(nodes[i].cn_nodeid);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get a list of active cluster members */
 | 
			
		||||
static void get_members(void)
 | 
			
		||||
static void get_members()
 | 
			
		||||
{
 | 
			
		||||
	int retnodes;
 | 
			
		||||
	int status;
 | 
			
		||||
	int i;
 | 
			
		||||
	int high_nodeid = 0;
 | 
			
		||||
 | 
			
		||||
	num_nodes = cman_get_node_count(c_handle);
 | 
			
		||||
	if (num_nodes == -1) {
 | 
			
		||||
@@ -316,10 +325,11 @@ static void get_members(void)
 | 
			
		||||
		exit(6);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get the highest nodeid */
 | 
			
		||||
	for (i=0; i<retnodes; i++) {
 | 
			
		||||
		if (nodes[i].cn_nodeid > high_nodeid)
 | 
			
		||||
			high_nodeid = nodes[i].cn_nodeid;
 | 
			
		||||
	if (node_updown == NULL) {
 | 
			
		||||
		size_t buf_len = sizeof(int) * max(num_nodes, max_updown_nodes);
 | 
			
		||||
		node_updown = malloc(buf_len);
 | 
			
		||||
		if (node_updown)
 | 
			
		||||
			memset(node_updown, 0, buf_len);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -380,7 +390,7 @@ static int nodeid_from_csid(const char *csid)
 | 
			
		||||
	return nodeid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _is_quorate(void)
 | 
			
		||||
static int _is_quorate()
 | 
			
		||||
{
 | 
			
		||||
	return cman_is_quorate(c_handle);
 | 
			
		||||
}
 | 
			
		||||
@@ -478,7 +488,6 @@ static int _get_cluster_name(char *buf, int buflen)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct cluster_ops _cluster_cman_ops = {
 | 
			
		||||
	.name                     = "cman",
 | 
			
		||||
	.cluster_init_completed   = _cluster_init_completed,
 | 
			
		||||
	.cluster_send_message     = _cluster_send_message,
 | 
			
		||||
	.name_from_csid           = _name_from_csid,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
@@ -50,19 +50,32 @@
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "clvmd-common.h"
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
#include <libdlm.h>
 | 
			
		||||
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "locking.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "lvm-functions.h"
 | 
			
		||||
#include "clvmd-comms.h"
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "clvmd.h"
 | 
			
		||||
#include "lvm-globals.h"
 | 
			
		||||
#include "lvm-functions.h"
 | 
			
		||||
 | 
			
		||||
#include "locking.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
 | 
			
		||||
extern struct cluster_ops *clops;
 | 
			
		||||
static int restart_clvmd(void);
 | 
			
		||||
 | 
			
		||||
/* This is where all the real work happens:
 | 
			
		||||
   NOTE: client will be NULL when this is executed on a remote node */
 | 
			
		||||
@@ -73,7 +86,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
 | 
			
		||||
	int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
 | 
			
		||||
	int status = 0;
 | 
			
		||||
	char *lockname;
 | 
			
		||||
	const char *locktype;
 | 
			
		||||
	struct utsname nodeinfo;
 | 
			
		||||
	unsigned char lock_cmd;
 | 
			
		||||
	unsigned char lock_flags;
 | 
			
		||||
@@ -93,77 +105,44 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
 | 
			
		||||
			*buf = new_buf;
 | 
			
		||||
		}
 | 
			
		||||
		if (*buf) {
 | 
			
		||||
			if (uname(&nodeinfo))
 | 
			
		||||
				memset(&nodeinfo, 0, sizeof(nodeinfo));
 | 
			
		||||
 | 
			
		||||
			*retlen = 1 + dm_snprintf(*buf, buflen,
 | 
			
		||||
						  "TEST from %s: %s v%s",
 | 
			
		||||
						  nodeinfo.nodename, args,
 | 
			
		||||
						  nodeinfo.release);
 | 
			
		||||
			uname(&nodeinfo);
 | 
			
		||||
			*retlen = 1 + snprintf(*buf, buflen,
 | 
			
		||||
					       "TEST from %s: %s v%s",
 | 
			
		||||
					       nodeinfo.nodename, args,
 | 
			
		||||
					       nodeinfo.release);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_VG:
 | 
			
		||||
		lock_cmd = args[0];
 | 
			
		||||
		lock_flags = args[1];
 | 
			
		||||
		lockname = &args[2];
 | 
			
		||||
		/* Check to see if the VG is in use by LVM1 */
 | 
			
		||||
		status = do_check_lvm1(lockname);
 | 
			
		||||
		do_lock_vg(lock_cmd, lock_flags, lockname);
 | 
			
		||||
		status = do_check_lvm1(&args[2]);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_LV:
 | 
			
		||||
		/* This is the biggie */
 | 
			
		||||
		lock_cmd = args[0];
 | 
			
		||||
		lock_cmd = args[0] & 0x3F;
 | 
			
		||||
		lock_flags = args[1];
 | 
			
		||||
		lockname = &args[2];
 | 
			
		||||
		status = do_lock_lv(lock_cmd, lock_flags, lockname);
 | 
			
		||||
		/* Replace EIO with something less scary */
 | 
			
		||||
		if (status == EIO) {
 | 
			
		||||
			*retlen = 1 + dm_snprintf(*buf, buflen, "%s",
 | 
			
		||||
						  get_last_lvm_error());
 | 
			
		||||
			*retlen =
 | 
			
		||||
			    1 + snprintf(*buf, buflen, "%s",
 | 
			
		||||
					 get_last_lvm_error());
 | 
			
		||||
			return EIO;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_QUERY:
 | 
			
		||||
		lockname = &args[2];
 | 
			
		||||
		if (buflen < 3)
 | 
			
		||||
			return EIO;
 | 
			
		||||
		if ((locktype = do_lock_query(lockname)))
 | 
			
		||||
			*retlen = 1 + dm_snprintf(*buf, buflen, "%s", locktype);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_REFRESH:
 | 
			
		||||
		do_refresh_cache();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_SYNC_NAMES:
 | 
			
		||||
		lvm_do_fs_unlock();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_SET_DEBUG:
 | 
			
		||||
		clvmd_set_debug((debug_t) args[0]);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_RESTART:
 | 
			
		||||
		status = restart_clvmd();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_GET_CLUSTERNAME:
 | 
			
		||||
		status = clops->get_cluster_name(*buf, buflen);
 | 
			
		||||
		if (!status)
 | 
			
		||||
			*retlen = strlen(*buf)+1;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_VG_BACKUP:
 | 
			
		||||
		/*
 | 
			
		||||
		 * Do not run backup on local node, caller should do that.
 | 
			
		||||
		 */
 | 
			
		||||
		if (!client)
 | 
			
		||||
			lvm_do_backup(&args[2]);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		/* Won't get here because command is validated in pre_command */
 | 
			
		||||
		break;
 | 
			
		||||
@@ -171,63 +150,69 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
 | 
			
		||||
 | 
			
		||||
	/* Check the status of the command and return the error text */
 | 
			
		||||
	if (status) {
 | 
			
		||||
		*retlen = 1 + ((*buf) ? dm_snprintf(*buf, buflen, "%s",
 | 
			
		||||
						    strerror(status)) : -1);
 | 
			
		||||
		*retlen = 1 + snprintf(*buf, buflen, "%s", strerror(status));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int lock_vg(struct local_client *client)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_hash_table *lock_hash;
 | 
			
		||||
	struct clvm_header *header =
 | 
			
		||||
		(struct clvm_header *) client->bits.localsock.cmd;
 | 
			
		||||
	unsigned char lock_cmd;
 | 
			
		||||
	int lock_mode;
 | 
			
		||||
	char *args = header->node + strlen(header->node) + 1;
 | 
			
		||||
	int lkid;
 | 
			
		||||
	int status;
 | 
			
		||||
	char *lockname;
 | 
			
		||||
    struct dm_hash_table *lock_hash;
 | 
			
		||||
    struct clvm_header *header =
 | 
			
		||||
	(struct clvm_header *) client->bits.localsock.cmd;
 | 
			
		||||
    unsigned char lock_cmd;
 | 
			
		||||
    unsigned char lock_flags;
 | 
			
		||||
    char *args = header->node + strlen(header->node) + 1;
 | 
			
		||||
    int lkid;
 | 
			
		||||
    int status = 0;
 | 
			
		||||
    char *lockname;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Keep a track of VG locks in our own hash table. In current
 | 
			
		||||
	 * practice there should only ever be more than two VGs locked
 | 
			
		||||
	 * if a user tries to merge lots of them at once
 | 
			
		||||
	 */
 | 
			
		||||
	if (!client->bits.localsock.private) {
 | 
			
		||||
		if (!(lock_hash = dm_hash_create(3)))
 | 
			
		||||
			return ENOMEM;
 | 
			
		||||
		client->bits.localsock.private = (void *) lock_hash;
 | 
			
		||||
	} else
 | 
			
		||||
		lock_hash = (struct dm_hash_table *) client->bits.localsock.private;
 | 
			
		||||
    /* Keep a track of VG locks in our own hash table. In current
 | 
			
		||||
       practice there should only ever be more than two VGs locked
 | 
			
		||||
       if a user tries to merge lots of them at once */
 | 
			
		||||
    if (client->bits.localsock.private) {
 | 
			
		||||
	lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	lock_hash = dm_hash_create(3);
 | 
			
		||||
	if (!lock_hash)
 | 
			
		||||
	    return ENOMEM;
 | 
			
		||||
	client->bits.localsock.private = (void *)lock_hash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
 | 
			
		||||
	lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
 | 
			
		||||
	/* lock_flags = args[1]; */
 | 
			
		||||
	lockname = &args[2];
 | 
			
		||||
	DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
 | 
			
		||||
    lock_cmd = args[0] & 0x3F;
 | 
			
		||||
    lock_flags = args[1];
 | 
			
		||||
    lockname = &args[2];
 | 
			
		||||
    DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
 | 
			
		||||
 | 
			
		||||
	if (lock_mode == LCK_UNLOCK) {
 | 
			
		||||
		if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
 | 
			
		||||
			return EINVAL;
 | 
			
		||||
    if (lock_cmd == LCK_UNLOCK) {
 | 
			
		||||
 | 
			
		||||
		if ((status = sync_unlock(lockname, lkid)))
 | 
			
		||||
			status = errno;
 | 
			
		||||
		else
 | 
			
		||||
			dm_hash_remove(lock_hash, lockname);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Read locks need to be PR; other modes get passed through */
 | 
			
		||||
		if (lock_mode == LCK_READ)
 | 
			
		||||
			lock_mode = LCK_PREAD;
 | 
			
		||||
	lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
 | 
			
		||||
	if (lkid == 0)
 | 
			
		||||
	    return EINVAL;
 | 
			
		||||
 | 
			
		||||
		if ((status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid)))
 | 
			
		||||
			status = errno;
 | 
			
		||||
		else if (!dm_hash_insert(lock_hash, lockname, (void *) (long) lkid))
 | 
			
		||||
			return ENOMEM;
 | 
			
		||||
	status = sync_unlock(lockname, lkid);
 | 
			
		||||
	if (status)
 | 
			
		||||
	    status = errno;
 | 
			
		||||
	else
 | 
			
		||||
	    dm_hash_remove(lock_hash, lockname);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	/* Read locks need to be PR; other modes get passed through */
 | 
			
		||||
	if ((lock_cmd & LCK_TYPE_MASK) == LCK_READ) {
 | 
			
		||||
	    lock_cmd &= ~LCK_TYPE_MASK;
 | 
			
		||||
	    lock_cmd |= LCK_PREAD;
 | 
			
		||||
	}
 | 
			
		||||
	status = sync_lock(lockname, (int)lock_cmd, (lock_flags & LCK_NONBLOCK) ? LKF_NOQUEUE : 0, &lkid);
 | 
			
		||||
	if (status)
 | 
			
		||||
	    status = errno;
 | 
			
		||||
	else
 | 
			
		||||
	    dm_hash_insert(lock_hash, lockname, (void *)(long)lkid);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -241,22 +226,18 @@ int do_pre_command(struct local_client *client)
 | 
			
		||||
	unsigned char lock_cmd;
 | 
			
		||||
	unsigned char lock_flags;
 | 
			
		||||
	char *args = header->node + strlen(header->node) + 1;
 | 
			
		||||
	int lockid = 0;
 | 
			
		||||
	int lockid;
 | 
			
		||||
	int status = 0;
 | 
			
		||||
	char *lockname;
 | 
			
		||||
 | 
			
		||||
	switch (header->cmd) {
 | 
			
		||||
	case CLVMD_CMD_TEST:
 | 
			
		||||
		status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
 | 
			
		||||
		status = sync_lock("CLVMD_TEST", LKM_EXMODE, 0, &lockid);
 | 
			
		||||
		client->bits.localsock.private = (void *)(long)lockid;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_VG:
 | 
			
		||||
		lockname = &args[2];
 | 
			
		||||
		/* We take out a real lock unless LCK_CACHE was set */
 | 
			
		||||
		if (!strncmp(lockname, "V_", 2) ||
 | 
			
		||||
		    !strncmp(lockname, "P_#", 3))
 | 
			
		||||
			status = lock_vg(client);
 | 
			
		||||
       	        status = lock_vg(client);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_LV:
 | 
			
		||||
@@ -268,11 +249,6 @@ int do_pre_command(struct local_client *client)
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_REFRESH:
 | 
			
		||||
	case CLVMD_CMD_GET_CLUSTERNAME:
 | 
			
		||||
	case CLVMD_CMD_SET_DEBUG:
 | 
			
		||||
	case CLVMD_CMD_VG_BACKUP:
 | 
			
		||||
	case CLVMD_CMD_SYNC_NAMES:
 | 
			
		||||
	case CLVMD_CMD_LOCK_QUERY:
 | 
			
		||||
	case CLVMD_CMD_RESTART:
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
@@ -296,8 +272,13 @@ int do_post_command(struct local_client *client)
 | 
			
		||||
 | 
			
		||||
	switch (header->cmd) {
 | 
			
		||||
	case CLVMD_CMD_TEST:
 | 
			
		||||
		status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
 | 
			
		||||
		client->bits.localsock.private = NULL;
 | 
			
		||||
		status =
 | 
			
		||||
		    sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
 | 
			
		||||
		client->bits.localsock.private = 0;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_VG:
 | 
			
		||||
		/* Nothing to do here */
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CLVMD_CMD_LOCK_LV:
 | 
			
		||||
@@ -306,10 +287,6 @@ int do_post_command(struct local_client *client)
 | 
			
		||||
		lockname = &args[2];
 | 
			
		||||
		status = post_lock_lv(lock_cmd, lock_flags, lockname);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		/* Nothing to do here */
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
@@ -318,97 +295,21 @@ int do_post_command(struct local_client *client)
 | 
			
		||||
/* Called when the client is about to be deleted */
 | 
			
		||||
void cmd_client_cleanup(struct local_client *client)
 | 
			
		||||
{
 | 
			
		||||
    if (client->bits.localsock.private) {
 | 
			
		||||
 | 
			
		||||
	struct dm_hash_node *v;
 | 
			
		||||
	struct dm_hash_table *lock_hash;
 | 
			
		||||
	int lkid;
 | 
			
		||||
	char *lockname;
 | 
			
		||||
 | 
			
		||||
	if (!client->bits.localsock.private)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
 | 
			
		||||
	struct dm_hash_table *lock_hash =
 | 
			
		||||
	    (struct dm_hash_table *)client->bits.localsock.private;
 | 
			
		||||
 | 
			
		||||
	dm_hash_iterate(v, lock_hash) {
 | 
			
		||||
		lkid = (int)(long)dm_hash_get_data(lock_hash, v);
 | 
			
		||||
		lockname = dm_hash_get_key(lock_hash, v);
 | 
			
		||||
		int lkid = (int)(long)dm_hash_get_data(lock_hash, v);
 | 
			
		||||
		char *lockname = dm_hash_get_key(lock_hash, v);
 | 
			
		||||
 | 
			
		||||
		DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
 | 
			
		||||
		(void) sync_unlock(lockname, lkid);
 | 
			
		||||
		sync_unlock(lockname, lkid);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dm_hash_destroy(lock_hash);
 | 
			
		||||
	client->bits.localsock.private = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int restart_clvmd(void)
 | 
			
		||||
{
 | 
			
		||||
	const char **argv;
 | 
			
		||||
	char *lv_name;
 | 
			
		||||
	int argc = 0, max_locks = 0;
 | 
			
		||||
	struct dm_hash_node *hn = NULL;
 | 
			
		||||
	char debug_arg[16];
 | 
			
		||||
	const char *clvmd = getenv("LVM_CLVMD_BINARY") ? : CLVMD_PATH;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("clvmd restart requested\n");
 | 
			
		||||
 | 
			
		||||
	/* Count exclusively-open LVs */
 | 
			
		||||
	do {
 | 
			
		||||
		hn = get_next_excl_lock(hn, &lv_name);
 | 
			
		||||
		if (lv_name) {
 | 
			
		||||
			max_locks++;
 | 
			
		||||
			if (!*lv_name)
 | 
			
		||||
				break; /* FIXME: Is this error ? */
 | 
			
		||||
		}
 | 
			
		||||
	} while (hn);
 | 
			
		||||
 | 
			
		||||
	/* clvmd + locks (-E uuid) + debug (-d X) + NULL */
 | 
			
		||||
	if (!(argv = malloc((max_locks * 2 + 6) * sizeof(*argv))))
 | 
			
		||||
		goto_out;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Build the command-line
 | 
			
		||||
	 */
 | 
			
		||||
	argv[argc++] = "clvmd";
 | 
			
		||||
 | 
			
		||||
	/* Propagate debug options */
 | 
			
		||||
	if (clvmd_get_debug()) {
 | 
			
		||||
		if (dm_snprintf(debug_arg, sizeof(debug_arg), "-d%u", clvmd_get_debug()) < 0)
 | 
			
		||||
			goto_out;
 | 
			
		||||
		argv[argc++] = debug_arg;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Propagate foreground options */
 | 
			
		||||
	if (clvmd_get_foreground())
 | 
			
		||||
		argv[argc++] = "-f";
 | 
			
		||||
 | 
			
		||||
	argv[argc++] = "-I";
 | 
			
		||||
	argv[argc++] = clops->name;
 | 
			
		||||
 | 
			
		||||
	/* Now add the exclusively-open LVs */
 | 
			
		||||
	hn = NULL;
 | 
			
		||||
	do {
 | 
			
		||||
		hn = get_next_excl_lock(hn, &lv_name);
 | 
			
		||||
		if (lv_name) {
 | 
			
		||||
			if (!*lv_name)
 | 
			
		||||
				break; /* FIXME: Is this error ? */
 | 
			
		||||
			argv[argc++] = "-E";
 | 
			
		||||
			argv[argc++] = lv_name;
 | 
			
		||||
			DEBUGLOG("excl lock: %s\n", lv_name);
 | 
			
		||||
		}
 | 
			
		||||
	} while (hn);
 | 
			
		||||
	argv[argc] = NULL;
 | 
			
		||||
 | 
			
		||||
	/* Exec new clvmd */
 | 
			
		||||
	DEBUGLOG("--- Restarting %s ---\n", clvmd);
 | 
			
		||||
	for (argc = 1; argv[argc]; argc++) DEBUGLOG("--- %d: %s\n", argc, argv[argc]);
 | 
			
		||||
 | 
			
		||||
	/* NOTE: This will fail when downgrading! */
 | 
			
		||||
	execvp(clvmd, (char **)argv);
 | 
			
		||||
out:
 | 
			
		||||
	/* We failed */
 | 
			
		||||
	DEBUGLOG("Restart of clvmd failed.\n");
 | 
			
		||||
 | 
			
		||||
	free(argv);
 | 
			
		||||
 | 
			
		||||
	return EIO;
 | 
			
		||||
	client->bits.localsock.private = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This file must be included first by every clvmd source file.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLVMD_COMMON_H
 | 
			
		||||
#define _LVM_CLVMD_COMMON_H
 | 
			
		||||
 | 
			
		||||
#include "configure.h"
 | 
			
		||||
 | 
			
		||||
#define _REENTRANT
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#define _FILE_OFFSET_BITS 64
 | 
			
		||||
 | 
			
		||||
#include "libdevmapper.h"
 | 
			
		||||
#include "lvm-logging.h"
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
@@ -23,7 +23,6 @@
 | 
			
		||||
struct local_client;
 | 
			
		||||
 | 
			
		||||
struct cluster_ops {
 | 
			
		||||
	const char *name;
 | 
			
		||||
	void (*cluster_init_completed) (void);
 | 
			
		||||
 | 
			
		||||
	int (*cluster_send_message) (const void *buf, int msglen,
 | 
			
		||||
@@ -55,6 +54,13 @@ struct cluster_ops {
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef USE_GULM
 | 
			
		||||
#  include "tcp-comms.h"
 | 
			
		||||
struct cluster_ops *init_gulm_cluster(void);
 | 
			
		||||
#define MAX_CSID_LEN 			GULM_MAX_CSID_LEN
 | 
			
		||||
#define MAX_CLUSTER_MEMBER_NAME_LEN	GULM_MAX_CLUSTER_MEMBER_NAME_LEN
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USE_CMAN
 | 
			
		||||
#  include <netinet/in.h>
 | 
			
		||||
#  include "libcman.h"
 | 
			
		||||
@@ -71,7 +77,7 @@ struct cluster_ops *init_cman_cluster(void);
 | 
			
		||||
 | 
			
		||||
#ifdef USE_OPENAIS
 | 
			
		||||
#  include <openais/saAis.h>
 | 
			
		||||
#  include <corosync/totem/totem.h>
 | 
			
		||||
#  include <openais/totem/totem.h>
 | 
			
		||||
#  define OPENAIS_CSID_LEN (sizeof(int))
 | 
			
		||||
#  define OPENAIS_MAX_CLUSTER_MESSAGE         MESSAGE_SIZE_MAX
 | 
			
		||||
#  define OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
 | 
			
		||||
@@ -87,33 +93,5 @@ struct cluster_ops *init_cman_cluster(void);
 | 
			
		||||
struct cluster_ops *init_openais_cluster(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USE_COROSYNC
 | 
			
		||||
#  include <corosync/corotypes.h>
 | 
			
		||||
#  define COROSYNC_CSID_LEN (sizeof(int))
 | 
			
		||||
#  define COROSYNC_MAX_CLUSTER_MESSAGE         65535
 | 
			
		||||
#  define COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
 | 
			
		||||
#  ifndef MAX_CLUSTER_MEMBER_NAME_LEN
 | 
			
		||||
#    define MAX_CLUSTER_MEMBER_NAME_LEN       CS_MAX_NAME_LENGTH
 | 
			
		||||
#  endif
 | 
			
		||||
#  ifndef CMAN_MAX_CLUSTER_MESSAGE
 | 
			
		||||
#    define CMAN_MAX_CLUSTER_MESSAGE          65535
 | 
			
		||||
#  endif
 | 
			
		||||
#  ifndef MAX_CSID_LEN
 | 
			
		||||
#    define MAX_CSID_LEN sizeof(int)
 | 
			
		||||
#  endif
 | 
			
		||||
struct cluster_ops *init_corosync_cluster(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USE_SINGLENODE
 | 
			
		||||
#  define SINGLENODE_CSID_LEN (sizeof(int))
 | 
			
		||||
#  ifndef MAX_CLUSTER_MEMBER_NAME_LEN
 | 
			
		||||
#    define MAX_CLUSTER_MEMBER_NAME_LEN       64
 | 
			
		||||
#  endif
 | 
			
		||||
#  define SINGLENODE_MAX_CLUSTER_MESSAGE          65535
 | 
			
		||||
#  ifndef MAX_CSID_LEN
 | 
			
		||||
#    define MAX_CSID_LEN sizeof(int)
 | 
			
		||||
#  endif
 | 
			
		||||
struct cluster_ops *init_singlenode_cluster(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,658 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009-2012 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This provides the interface between clvmd and corosync/DLM as the cluster
 | 
			
		||||
 * and lock manager.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clvmd-common.h"
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "clvmd-comms.h"
 | 
			
		||||
#include "clvmd.h"
 | 
			
		||||
#include "lvm-functions.h"
 | 
			
		||||
 | 
			
		||||
#include "locking.h"
 | 
			
		||||
 | 
			
		||||
#include <corosync/cpg.h>
 | 
			
		||||
#include <corosync/quorum.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_COROSYNC_CONFDB_H
 | 
			
		||||
#  include <corosync/confdb.h>
 | 
			
		||||
#elif defined HAVE_COROSYNC_CMAP_H
 | 
			
		||||
#  include <corosync/cmap.h>
 | 
			
		||||
#else
 | 
			
		||||
#  error "Either HAVE_COROSYNC_CONFDB_H or HAVE_COROSYNC_CMAP_H must be defined."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <libdlm.h>
 | 
			
		||||
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
/* Timeout value for several corosync calls */
 | 
			
		||||
#define LOCKSPACE_NAME "clvmd"
 | 
			
		||||
 | 
			
		||||
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
 | 
			
		||||
				  const struct cpg_name *groupName,
 | 
			
		||||
				  uint32_t nodeid,
 | 
			
		||||
				  uint32_t pid,
 | 
			
		||||
				  void *msg,
 | 
			
		||||
				  size_t msg_len);
 | 
			
		||||
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
				 const struct cpg_name *groupName,
 | 
			
		||||
				 const struct cpg_address *member_list, size_t member_list_entries,
 | 
			
		||||
				 const struct cpg_address *left_list, size_t left_list_entries,
 | 
			
		||||
				 const struct cpg_address *joined_list, size_t joined_list_entries);
 | 
			
		||||
static void _cluster_closedown(void);
 | 
			
		||||
 | 
			
		||||
/* Hash list of nodes in the cluster */
 | 
			
		||||
static struct dm_hash_table *node_hash;
 | 
			
		||||
 | 
			
		||||
/* Number of active nodes */
 | 
			
		||||
static int num_nodes;
 | 
			
		||||
static unsigned int our_nodeid;
 | 
			
		||||
 | 
			
		||||
static struct local_client *cluster_client;
 | 
			
		||||
 | 
			
		||||
/* Corosync handles */
 | 
			
		||||
static cpg_handle_t cpg_handle;
 | 
			
		||||
static quorum_handle_t quorum_handle;
 | 
			
		||||
 | 
			
		||||
/* DLM Handle */
 | 
			
		||||
static dlm_lshandle_t *lockspace;
 | 
			
		||||
 | 
			
		||||
static struct cpg_name cpg_group_name;
 | 
			
		||||
 | 
			
		||||
/* Corosync callback structs */
 | 
			
		||||
cpg_callbacks_t corosync_cpg_callbacks = {
 | 
			
		||||
	.cpg_deliver_fn =            corosync_cpg_deliver_callback,
 | 
			
		||||
	.cpg_confchg_fn =            corosync_cpg_confchg_callback,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
quorum_callbacks_t quorum_callbacks = {
 | 
			
		||||
	.quorum_notify_fn = NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct node_info
 | 
			
		||||
{
 | 
			
		||||
	enum {NODE_DOWN, NODE_CLVMD} state;
 | 
			
		||||
	int nodeid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Set errno to something approximating the right value and return 0 or -1 */
 | 
			
		||||
static int cs_to_errno(cs_error_t err)
 | 
			
		||||
{
 | 
			
		||||
	switch(err)
 | 
			
		||||
	{
 | 
			
		||||
	case CS_OK:
 | 
			
		||||
		return 0;
 | 
			
		||||
        case CS_ERR_LIBRARY:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_VERSION:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_INIT:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_TIMEOUT:
 | 
			
		||||
		errno = ETIME;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_TRY_AGAIN:
 | 
			
		||||
		errno = EAGAIN;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_INVALID_PARAM:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NO_MEMORY:
 | 
			
		||||
		errno = ENOMEM;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_BAD_HANDLE:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_BUSY:
 | 
			
		||||
		errno = EBUSY;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_ACCESS:
 | 
			
		||||
		errno = EPERM;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NOT_EXIST:
 | 
			
		||||
		errno = ENOENT;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NAME_TOO_LONG:
 | 
			
		||||
		errno = ENAMETOOLONG;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_EXIST:
 | 
			
		||||
		errno = EEXIST;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NO_SPACE:
 | 
			
		||||
		errno = ENOSPC;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_INTERRUPT:
 | 
			
		||||
		errno = EINTR;
 | 
			
		||||
		break;
 | 
			
		||||
	case CS_ERR_NAME_NOT_FOUND:
 | 
			
		||||
		errno = ENOENT;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NO_RESOURCES:
 | 
			
		||||
		errno = ENOMEM;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NOT_SUPPORTED:
 | 
			
		||||
		errno = EOPNOTSUPP;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_BAD_OPERATION:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_FAILED_OPERATION:
 | 
			
		||||
		errno = EIO;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_MESSAGE_ERROR:
 | 
			
		||||
		errno = EIO;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_QUEUE_FULL:
 | 
			
		||||
		errno = EXFULL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_QUEUE_NOT_AVAILABLE:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_BAD_FLAGS:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_TOO_BIG:
 | 
			
		||||
		errno = E2BIG;
 | 
			
		||||
		break;
 | 
			
		||||
        case CS_ERR_NO_SECTIONS:
 | 
			
		||||
		errno = ENOMEM;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *print_corosync_csid(const char *csid)
 | 
			
		||||
{
 | 
			
		||||
	static char buf[128];
 | 
			
		||||
	int id;
 | 
			
		||||
 | 
			
		||||
	memcpy(&id, csid, sizeof(int));
 | 
			
		||||
	sprintf(buf, "%d", id);
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
 | 
			
		||||
				  const struct cpg_name *groupName,
 | 
			
		||||
				  uint32_t nodeid,
 | 
			
		||||
				  uint32_t pid,
 | 
			
		||||
				  void *msg,
 | 
			
		||||
				  size_t msg_len)
 | 
			
		||||
{
 | 
			
		||||
	int target_nodeid;
 | 
			
		||||
 | 
			
		||||
	memcpy(&target_nodeid, msg, COROSYNC_CSID_LEN);
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("%u got message from nodeid %d for %d. len %zd\n",
 | 
			
		||||
		 our_nodeid, nodeid, target_nodeid, msg_len-4);
 | 
			
		||||
 | 
			
		||||
	if (nodeid != our_nodeid)
 | 
			
		||||
		if (target_nodeid == our_nodeid || target_nodeid == 0)
 | 
			
		||||
			process_message(cluster_client, (char *)msg+COROSYNC_CSID_LEN,
 | 
			
		||||
					msg_len-COROSYNC_CSID_LEN, (char*)&nodeid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
				 const struct cpg_name *groupName,
 | 
			
		||||
				 const struct cpg_address *member_list, size_t member_list_entries,
 | 
			
		||||
				 const struct cpg_address *left_list, size_t left_list_entries,
 | 
			
		||||
				 const struct cpg_address *joined_list, size_t joined_list_entries)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("confchg callback. %zd joined, %zd left, %zd members\n",
 | 
			
		||||
		 joined_list_entries, left_list_entries, member_list_entries);
 | 
			
		||||
 | 
			
		||||
	for (i=0; i<joined_list_entries; i++) {
 | 
			
		||||
		ninfo = dm_hash_lookup_binary(node_hash,
 | 
			
		||||
					      (char *)&joined_list[i].nodeid,
 | 
			
		||||
					      COROSYNC_CSID_LEN);
 | 
			
		||||
		if (!ninfo) {
 | 
			
		||||
			ninfo = malloc(sizeof(struct node_info));
 | 
			
		||||
			if (!ninfo) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ninfo->nodeid = joined_list[i].nodeid;
 | 
			
		||||
				dm_hash_insert_binary(node_hash,
 | 
			
		||||
						      (char *)&ninfo->nodeid,
 | 
			
		||||
						      COROSYNC_CSID_LEN, ninfo);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ninfo->state = NODE_CLVMD;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i=0; i<left_list_entries; i++) {
 | 
			
		||||
		ninfo = dm_hash_lookup_binary(node_hash,
 | 
			
		||||
					      (char *)&left_list[i].nodeid,
 | 
			
		||||
					      COROSYNC_CSID_LEN);
 | 
			
		||||
		if (ninfo)
 | 
			
		||||
			ninfo->state = NODE_DOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	num_nodes = member_list_entries;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _init_cluster(void)
 | 
			
		||||
{
 | 
			
		||||
	cs_error_t err;
 | 
			
		||||
 | 
			
		||||
#ifdef QUORUM_SET	/* corosync/quorum.h */
 | 
			
		||||
	uint32_t quorum_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	node_hash = dm_hash_create(100);
 | 
			
		||||
 | 
			
		||||
	err = cpg_initialize(&cpg_handle,
 | 
			
		||||
			     &corosync_cpg_callbacks);
 | 
			
		||||
	if (err != CS_OK) {
 | 
			
		||||
		syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d",
 | 
			
		||||
		       err);
 | 
			
		||||
		DEBUGLOG("Cannot initialise Corosync CPG service: %d", err);
 | 
			
		||||
		return cs_to_errno(err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef QUORUM_SET
 | 
			
		||||
	err = quorum_initialize(&quorum_handle,
 | 
			
		||||
				&quorum_callbacks,
 | 
			
		||||
				&quorum_type);
 | 
			
		||||
 | 
			
		||||
	if (quorum_type != QUORUM_SET) {
 | 
			
		||||
		syslog(LOG_ERR, "Corosync quorum service is not configured");
 | 
			
		||||
		DEBUGLOG("Corosync quorum service is not configured");
 | 
			
		||||
		return EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	err = quorum_initialize(&quorum_handle,
 | 
			
		||||
				&quorum_callbacks);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (err != CS_OK) {
 | 
			
		||||
		syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d",
 | 
			
		||||
		       err);
 | 
			
		||||
		DEBUGLOG("Cannot initialise Corosync quorum service: %d", err);
 | 
			
		||||
		return cs_to_errno(err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Create a lockspace for LV & VG locks to live in */
 | 
			
		||||
	lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
 | 
			
		||||
	if (!lockspace) {
 | 
			
		||||
		lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
 | 
			
		||||
		if (!lockspace) {
 | 
			
		||||
			syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m");
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		DEBUGLOG("Created DLM lockspace for CLVMD.\n");
 | 
			
		||||
	} else
 | 
			
		||||
		DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n");
 | 
			
		||||
 | 
			
		||||
	dlm_ls_pthread_init(lockspace);
 | 
			
		||||
	DEBUGLOG("DLM initialisation complete\n");
 | 
			
		||||
 | 
			
		||||
	/* Connect to the clvmd group */
 | 
			
		||||
	strcpy((char *)cpg_group_name.value, "clvmd");
 | 
			
		||||
	cpg_group_name.length = strlen((char *)cpg_group_name.value);
 | 
			
		||||
	err = cpg_join(cpg_handle, &cpg_group_name);
 | 
			
		||||
	if (err != CS_OK) {
 | 
			
		||||
		cpg_finalize(cpg_handle);
 | 
			
		||||
		quorum_finalize(quorum_handle);
 | 
			
		||||
		dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
 | 
			
		||||
		syslog(LOG_ERR, "Cannot join clvmd process group");
 | 
			
		||||
		DEBUGLOG("Cannot join clvmd process group: %d\n", err);
 | 
			
		||||
		return cs_to_errno(err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = cpg_local_get(cpg_handle,
 | 
			
		||||
			    &our_nodeid);
 | 
			
		||||
	if (err != CS_OK) {
 | 
			
		||||
		cpg_finalize(cpg_handle);
 | 
			
		||||
		quorum_finalize(quorum_handle);
 | 
			
		||||
		dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
 | 
			
		||||
		syslog(LOG_ERR, "Cannot get local node id\n");
 | 
			
		||||
		return cs_to_errno(err);
 | 
			
		||||
	}
 | 
			
		||||
	DEBUGLOG("Our local node id is %d\n", our_nodeid);
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("Connected to Corosync\n");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _cluster_closedown(void)
 | 
			
		||||
{
 | 
			
		||||
	dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
 | 
			
		||||
	cpg_finalize(cpg_handle);
 | 
			
		||||
	quorum_finalize(quorum_handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _get_our_csid(char *csid)
 | 
			
		||||
{
 | 
			
		||||
	memcpy(csid, &our_nodeid, sizeof(int));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Corosync doesn't really have nmode names so we
 | 
			
		||||
   just use the node ID in hex instead */
 | 
			
		||||
static int _csid_from_name(char *csid, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	int nodeid;
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
 | 
			
		||||
	if (sscanf(name, "%x", &nodeid) == 1) {
 | 
			
		||||
		ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
 | 
			
		||||
		if (ninfo)
 | 
			
		||||
			return nodeid;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _name_from_csid(const char *csid, char *name)
 | 
			
		||||
{
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
 | 
			
		||||
	ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
 | 
			
		||||
	if (!ninfo)
 | 
			
		||||
	{
 | 
			
		||||
		sprintf(name, "UNKNOWN %s", print_corosync_csid(csid));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sprintf(name, "%x", ninfo->nodeid);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_num_nodes(void)
 | 
			
		||||
{
 | 
			
		||||
	DEBUGLOG("num_nodes = %d\n", num_nodes);
 | 
			
		||||
	return num_nodes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Node is now known to be running a clvmd */
 | 
			
		||||
static void _add_up_node(const char *csid)
 | 
			
		||||
{
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
 | 
			
		||||
	ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
 | 
			
		||||
	if (!ninfo) {
 | 
			
		||||
		DEBUGLOG("corosync_add_up_node no node_hash entry for csid %s\n",
 | 
			
		||||
			 print_corosync_csid(csid));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("corosync_add_up_node %d\n", ninfo->nodeid);
 | 
			
		||||
 | 
			
		||||
	ninfo->state = NODE_CLVMD;
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Call a callback for each node, so the caller knows whether it's up or down */
 | 
			
		||||
static int _cluster_do_node_callback(struct local_client *master_client,
 | 
			
		||||
				     void (*callback)(struct local_client *,
 | 
			
		||||
						      const char *csid, int node_up))
 | 
			
		||||
{
 | 
			
		||||
	struct dm_hash_node *hn;
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
 | 
			
		||||
	dm_hash_iterate(hn, node_hash)
 | 
			
		||||
	{
 | 
			
		||||
		char csid[COROSYNC_CSID_LEN];
 | 
			
		||||
 | 
			
		||||
		ninfo = dm_hash_get_data(node_hash, hn);
 | 
			
		||||
		memcpy(csid, dm_hash_get_key(node_hash, hn), COROSYNC_CSID_LEN);
 | 
			
		||||
 | 
			
		||||
		DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
 | 
			
		||||
			 ninfo->state);
 | 
			
		||||
 | 
			
		||||
		if (ninfo->state == NODE_CLVMD)
 | 
			
		||||
			callback(master_client, csid, 1);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Real locking */
 | 
			
		||||
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
 | 
			
		||||
{
 | 
			
		||||
	struct dlm_lksb lksb;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
 | 
			
		||||
 | 
			
		||||
	if (flags & LKF_CONVERT)
 | 
			
		||||
		lksb.sb_lkid = *lockid;
 | 
			
		||||
 | 
			
		||||
	err = dlm_ls_lock_wait(lockspace,
 | 
			
		||||
			       mode,
 | 
			
		||||
			       &lksb,
 | 
			
		||||
			       flags,
 | 
			
		||||
			       resource,
 | 
			
		||||
			       strlen(resource),
 | 
			
		||||
			       0,
 | 
			
		||||
			       NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
	if (err != 0)
 | 
			
		||||
	{
 | 
			
		||||
		DEBUGLOG("dlm_ls_lock returned %d\n", errno);
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
	if (lksb.sb_status != 0)
 | 
			
		||||
	{
 | 
			
		||||
		DEBUGLOG("dlm_ls_lock returns lksb.sb_status %d\n", lksb.sb_status);
 | 
			
		||||
		errno = lksb.sb_status;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("lock_resource returning %d, lock_id=%x\n", err, lksb.sb_lkid);
 | 
			
		||||
 | 
			
		||||
	*lockid = lksb.sb_lkid;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int _unlock_resource(const char *resource, int lockid)
 | 
			
		||||
{
 | 
			
		||||
	struct dlm_lksb lksb;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("unlock_resource: %s lockid: %x\n", resource, lockid);
 | 
			
		||||
	lksb.sb_lkid = lockid;
 | 
			
		||||
 | 
			
		||||
	err = dlm_ls_unlock_wait(lockspace,
 | 
			
		||||
				 lockid,
 | 
			
		||||
				 0,
 | 
			
		||||
				 &lksb);
 | 
			
		||||
	if (err != 0)
 | 
			
		||||
	{
 | 
			
		||||
		DEBUGLOG("Unlock returned %d\n", err);
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
	if (lksb.sb_status != EUNLOCK)
 | 
			
		||||
	{
 | 
			
		||||
		DEBUGLOG("dlm_ls_unlock_wait returns lksb.sb_status: %d\n", lksb.sb_status);
 | 
			
		||||
		errno = lksb.sb_status;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}   
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _is_quorate(void)
 | 
			
		||||
{
 | 
			
		||||
	int quorate;
 | 
			
		||||
	if (quorum_getquorate(quorum_handle, &quorate) == CS_OK)
 | 
			
		||||
		return quorate;
 | 
			
		||||
	else
 | 
			
		||||
		return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_main_cluster_fd(void)
 | 
			
		||||
{
 | 
			
		||||
	int select_fd;
 | 
			
		||||
 | 
			
		||||
	cpg_fd_get(cpg_handle, &select_fd);
 | 
			
		||||
	return select_fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
 | 
			
		||||
				const char *csid,
 | 
			
		||||
				struct local_client **new_client)
 | 
			
		||||
{
 | 
			
		||||
	cluster_client = fd;
 | 
			
		||||
	*new_client = NULL;
 | 
			
		||||
	cpg_dispatch(cpg_handle, CS_DISPATCH_ONE);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
 | 
			
		||||
				 const char *errtext)
 | 
			
		||||
{
 | 
			
		||||
	struct iovec iov[2];
 | 
			
		||||
	cs_error_t err;
 | 
			
		||||
	int target_node;
 | 
			
		||||
 | 
			
		||||
	if (csid)
 | 
			
		||||
		memcpy(&target_node, csid, COROSYNC_CSID_LEN);
 | 
			
		||||
	else
 | 
			
		||||
		target_node = 0;
 | 
			
		||||
 | 
			
		||||
	iov[0].iov_base = &target_node;
 | 
			
		||||
	iov[0].iov_len = sizeof(int);
 | 
			
		||||
	iov[1].iov_base = (char *)buf;
 | 
			
		||||
	iov[1].iov_len = msglen;
 | 
			
		||||
 | 
			
		||||
	err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
 | 
			
		||||
	return cs_to_errno(err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_COROSYNC_CONFDB_H
 | 
			
		||||
/*
 | 
			
		||||
 * We are not necessarily connected to a Red Hat Cluster system,
 | 
			
		||||
 * but if we are, this returns the cluster name from cluster.conf.
 | 
			
		||||
 * I've used confdb rather than ccs to reduce the inter-package
 | 
			
		||||
 * dependancies as well as to allow people to set a cluster name
 | 
			
		||||
 * for themselves even if they are not running on RH cluster.
 | 
			
		||||
 */
 | 
			
		||||
static int _get_cluster_name(char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
	confdb_handle_t handle;
 | 
			
		||||
	int result;
 | 
			
		||||
	size_t namelen = buflen;
 | 
			
		||||
	hdb_handle_t cluster_handle;
 | 
			
		||||
	confdb_callbacks_t callbacks = {
 | 
			
		||||
		.confdb_key_change_notify_fn = NULL,
 | 
			
		||||
		.confdb_object_create_change_notify_fn = NULL,
 | 
			
		||||
		.confdb_object_delete_change_notify_fn = NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/* This is a default in case everything else fails */
 | 
			
		||||
	strncpy(buf, "Corosync", buflen);
 | 
			
		||||
 | 
			
		||||
	/* Look for a cluster name in confdb */
 | 
			
		||||
	result = confdb_initialize (&handle, &callbacks);
 | 
			
		||||
        if (result != CS_OK)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
        result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
 | 
			
		||||
	if (result != CS_OK)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
        result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
 | 
			
		||||
        if (result != CS_OK)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
        result = confdb_key_get(handle, cluster_handle, (void *)"name", strlen("name"), buf, &namelen);
 | 
			
		||||
        if (result != CS_OK)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	buf[namelen] = '\0';
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	confdb_finalize(handle);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined HAVE_COROSYNC_CMAP_H
 | 
			
		||||
 | 
			
		||||
static int _get_cluster_name(char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
	cmap_handle_t cmap_handle = 0;
 | 
			
		||||
	int result;
 | 
			
		||||
	char *name = NULL;
 | 
			
		||||
 | 
			
		||||
	/* This is a default in case everything else fails */
 | 
			
		||||
	strncpy(buf, "Corosync", buflen);
 | 
			
		||||
 | 
			
		||||
	/* Look for a cluster name in cmap */
 | 
			
		||||
	result = cmap_initialize(&cmap_handle);
 | 
			
		||||
	if (result != CS_OK)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	result = cmap_get_string(cmap_handle, "totem.cluster_name", &name);
 | 
			
		||||
	if (result != CS_OK)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	memset(buf, 0, buflen);
 | 
			
		||||
	strncpy(buf, name, buflen - 1);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	if (name)
 | 
			
		||||
		free(name);
 | 
			
		||||
	cmap_finalize(cmap_handle);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static struct cluster_ops _cluster_corosync_ops = {
 | 
			
		||||
	.name                     = "corosync",
 | 
			
		||||
	.cluster_init_completed   = NULL,
 | 
			
		||||
	.cluster_send_message     = _cluster_send_message,
 | 
			
		||||
	.name_from_csid           = _name_from_csid,
 | 
			
		||||
	.csid_from_name           = _csid_from_name,
 | 
			
		||||
	.get_num_nodes            = _get_num_nodes,
 | 
			
		||||
	.cluster_fd_callback      = _cluster_fd_callback,
 | 
			
		||||
	.get_main_cluster_fd      = _get_main_cluster_fd,
 | 
			
		||||
	.cluster_do_node_callback = _cluster_do_node_callback,
 | 
			
		||||
	.is_quorate               = _is_quorate,
 | 
			
		||||
	.get_our_csid             = _get_our_csid,
 | 
			
		||||
	.add_up_node              = _add_up_node,
 | 
			
		||||
	.reread_config            = NULL,
 | 
			
		||||
	.cluster_closedown        = _cluster_closedown,
 | 
			
		||||
	.get_cluster_name         = _get_cluster_name,
 | 
			
		||||
	.sync_lock                = _lock_resource,
 | 
			
		||||
	.sync_unlock              = _unlock_resource,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cluster_ops *init_corosync_cluster(void)
 | 
			
		||||
{
 | 
			
		||||
	if (!_init_cluster())
 | 
			
		||||
		return &_cluster_corosync_ops;
 | 
			
		||||
	else
 | 
			
		||||
		return NULL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1009
									
								
								daemons/clvmd/clvmd-gulm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1009
									
								
								daemons/clvmd/clvmd-gulm.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										13
									
								
								daemons/clvmd/clvmd-gulm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								daemons/clvmd/clvmd-gulm.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
 | 
			
		||||
/* DLM constant that clvmd uses as a generic NONBLOCK lock flag */
 | 
			
		||||
#define LKF_NOQUEUE 1
 | 
			
		||||
 | 
			
		||||
extern int get_next_node_csid(void **context, char *csid);
 | 
			
		||||
extern void add_down_node(char *csid);
 | 
			
		||||
extern int gulm_fd(void);
 | 
			
		||||
extern int get_ip_address(const char *node, char *addr);
 | 
			
		||||
extern void tcp_remove_client(const char *csid);
 | 
			
		||||
extern int alloc_client(int fd, const char *csid, struct local_client **new_client);
 | 
			
		||||
 | 
			
		||||
void gulm_add_up_node(const char *csid);
 | 
			
		||||
int gulm_name_from_csid(const char *csid, char *name);
 | 
			
		||||
@@ -1,35 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*******************************************************************************
 | 
			
		||||
**
 | 
			
		||||
**  Copyright (C) 2007 Red Hat, Inc. All rights reserved.
 | 
			
		||||
**
 | 
			
		||||
*******************************************************************************
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This provides the interface between clvmd and OpenAIS as the cluster
 | 
			
		||||
/* This provides the interface between clvmd and OpenAIS as the cluster
 | 
			
		||||
 * and lock manager.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clvmd-common.h"
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <utmpx.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
 | 
			
		||||
#include <openais/saAis.h>
 | 
			
		||||
#include <openais/saLck.h>
 | 
			
		||||
#include <openais/cpg.h>
 | 
			
		||||
 | 
			
		||||
#include <corosync/corotypes.h>
 | 
			
		||||
#include <corosync/cpg.h>
 | 
			
		||||
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "locking.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "clvmd-comms.h"
 | 
			
		||||
#include "lvm-functions.h"
 | 
			
		||||
@@ -38,18 +50,22 @@
 | 
			
		||||
/* Timeout value for several openais calls */
 | 
			
		||||
#define TIMEOUT 10
 | 
			
		||||
 | 
			
		||||
static void openais_cpg_deliver_callback (cpg_handle_t handle,
 | 
			
		||||
				  const struct cpg_name *groupName,
 | 
			
		||||
static void lck_lock_callback(SaInvocationT invocation,
 | 
			
		||||
			      SaLckLockStatusT lockStatus,
 | 
			
		||||
			      SaAisErrorT error);
 | 
			
		||||
static void lck_unlock_callback(SaInvocationT invocation,
 | 
			
		||||
				SaAisErrorT error);
 | 
			
		||||
static void cpg_deliver_callback (cpg_handle_t handle,
 | 
			
		||||
				  struct cpg_name *groupName,
 | 
			
		||||
				  uint32_t nodeid,
 | 
			
		||||
				  uint32_t pid,
 | 
			
		||||
				  void *msg,
 | 
			
		||||
				  size_t msg_len);
 | 
			
		||||
static void openais_cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
				 const struct cpg_name *groupName,
 | 
			
		||||
				 const struct cpg_address *member_list, size_t member_list_entries,
 | 
			
		||||
				 const struct cpg_address *left_list, size_t left_list_entries,
 | 
			
		||||
				 const struct cpg_address *joined_list, size_t joined_list_entries);
 | 
			
		||||
 | 
			
		||||
				  int msg_len);
 | 
			
		||||
static void cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
				 struct cpg_name *groupName,
 | 
			
		||||
				 struct cpg_address *member_list, int member_list_entries,
 | 
			
		||||
				 struct cpg_address *left_list, int left_list_entries,
 | 
			
		||||
				 struct cpg_address *joined_list, int joined_list_entries);
 | 
			
		||||
static void _cluster_closedown(void);
 | 
			
		||||
 | 
			
		||||
/* Hash list of nodes in the cluster */
 | 
			
		||||
@@ -71,9 +87,14 @@ static SaLckHandleT lck_handle;
 | 
			
		||||
static struct cpg_name cpg_group_name;
 | 
			
		||||
 | 
			
		||||
/* Openais callback structs */
 | 
			
		||||
cpg_callbacks_t openais_cpg_callbacks = {
 | 
			
		||||
	.cpg_deliver_fn =            openais_cpg_deliver_callback,
 | 
			
		||||
	.cpg_confchg_fn =            openais_cpg_confchg_callback,
 | 
			
		||||
cpg_callbacks_t cpg_callbacks = {
 | 
			
		||||
	.cpg_deliver_fn =            cpg_deliver_callback,
 | 
			
		||||
	.cpg_confchg_fn =            cpg_confchg_callback,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
SaLckCallbacksT lck_callbacks = {
 | 
			
		||||
        .saLckLockGrantCallback      = lck_lock_callback,
 | 
			
		||||
        .saLckResourceUnlockCallback = lck_unlock_callback
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct node_info
 | 
			
		||||
@@ -89,6 +110,13 @@ struct lock_info
 | 
			
		||||
	SaNameT              lock_name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct lock_wait
 | 
			
		||||
{
 | 
			
		||||
	pthread_cond_t cond;
 | 
			
		||||
	pthread_mutex_t mutex;
 | 
			
		||||
	int status;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Set errno to something approximating the right value and return 0 or -1 */
 | 
			
		||||
static int ais_to_errno(SaAisErrorT err)
 | 
			
		||||
{
 | 
			
		||||
@@ -181,7 +209,7 @@ static int ais_to_errno(SaAisErrorT err)
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *print_openais_csid(const char *csid)
 | 
			
		||||
static char *print_csid(const char *csid)
 | 
			
		||||
{
 | 
			
		||||
	static char buf[128];
 | 
			
		||||
	int id;
 | 
			
		||||
@@ -197,11 +225,14 @@ static int add_internal_client(int fd, fd_callback_t callback)
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("Add_internal_client, fd = %d\n", fd);
 | 
			
		||||
 | 
			
		||||
	if (!(client = dm_zalloc(sizeof(*client)))) {
 | 
			
		||||
	client = malloc(sizeof(struct local_client));
 | 
			
		||||
	if (!client)
 | 
			
		||||
	{
 | 
			
		||||
		DEBUGLOG("malloc failed\n");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memset(client, 0, sizeof(struct local_client));
 | 
			
		||||
	client->fd = fd;
 | 
			
		||||
	client->type = CLUSTER_INTERNAL;
 | 
			
		||||
	client->callback = callback;
 | 
			
		||||
@@ -213,37 +244,35 @@ static int add_internal_client(int fd, fd_callback_t callback)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void openais_cpg_deliver_callback (cpg_handle_t handle,
 | 
			
		||||
				  const struct cpg_name *groupName,
 | 
			
		||||
static void cpg_deliver_callback (cpg_handle_t handle,
 | 
			
		||||
				  struct cpg_name *groupName,
 | 
			
		||||
				  uint32_t nodeid,
 | 
			
		||||
				  uint32_t pid,
 | 
			
		||||
				  void *msg,
 | 
			
		||||
				  size_t msg_len)
 | 
			
		||||
				  int msg_len)
 | 
			
		||||
{
 | 
			
		||||
	int target_nodeid;
 | 
			
		||||
 | 
			
		||||
	memcpy(&target_nodeid, msg, OPENAIS_CSID_LEN);
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("%u got message from nodeid %d for %d. len %" PRIsize_t "\n",
 | 
			
		||||
		 our_nodeid, nodeid, target_nodeid, msg_len-4);
 | 
			
		||||
	DEBUGLOG("Got message from nodeid %d for %d. len %d\n",
 | 
			
		||||
		 nodeid, target_nodeid, msg_len-4);
 | 
			
		||||
 | 
			
		||||
	if (nodeid != our_nodeid)
 | 
			
		||||
		if (target_nodeid == our_nodeid || target_nodeid == 0)
 | 
			
		||||
			process_message(cluster_client, (char *)msg+OPENAIS_CSID_LEN,
 | 
			
		||||
					msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
 | 
			
		||||
	if (target_nodeid == our_nodeid)
 | 
			
		||||
		process_message(cluster_client, (char *)msg+OPENAIS_CSID_LEN,
 | 
			
		||||
				msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void openais_cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
				 const struct cpg_name *groupName,
 | 
			
		||||
				 const struct cpg_address *member_list, size_t member_list_entries,
 | 
			
		||||
				 const struct cpg_address *left_list, size_t left_list_entries,
 | 
			
		||||
				 const struct cpg_address *joined_list, size_t joined_list_entries)
 | 
			
		||||
static void cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
				 struct cpg_name *groupName,
 | 
			
		||||
				 struct cpg_address *member_list, int member_list_entries,
 | 
			
		||||
				 struct cpg_address *left_list, int left_list_entries,
 | 
			
		||||
				 struct cpg_address *joined_list, int joined_list_entries)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("confchg callback. %" PRIsize_t " joined, "
 | 
			
		||||
		 "%" PRIsize_t " left, %" PRIsize_t " members\n",
 | 
			
		||||
	DEBUGLOG("confchg callback. %d joined, %d left, %d members\n",
 | 
			
		||||
		 joined_list_entries, left_list_entries, member_list_entries);
 | 
			
		||||
 | 
			
		||||
	for (i=0; i<joined_list_entries; i++) {
 | 
			
		||||
@@ -273,27 +302,34 @@ static void openais_cpg_confchg_callback(cpg_handle_t handle,
 | 
			
		||||
			ninfo->state = NODE_DOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i=0; i<member_list_entries; i++) {
 | 
			
		||||
		if (member_list[i].nodeid == 0) continue;
 | 
			
		||||
		ninfo = dm_hash_lookup_binary(node_hash,
 | 
			
		||||
				(char *)&member_list[i].nodeid,
 | 
			
		||||
				OPENAIS_CSID_LEN);
 | 
			
		||||
		if (!ninfo) {
 | 
			
		||||
			ninfo = malloc(sizeof(struct node_info));
 | 
			
		||||
			if (!ninfo) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ninfo->nodeid = member_list[i].nodeid;
 | 
			
		||||
				dm_hash_insert_binary(node_hash,
 | 
			
		||||
						(char *)&ninfo->nodeid,
 | 
			
		||||
						OPENAIS_CSID_LEN, ninfo);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ninfo->state = NODE_CLVMD;
 | 
			
		||||
	}
 | 
			
		||||
	num_nodes = joined_list_entries;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	num_nodes = member_list_entries;
 | 
			
		||||
static void lck_lock_callback(SaInvocationT invocation,
 | 
			
		||||
			      SaLckLockStatusT lockStatus,
 | 
			
		||||
			      SaAisErrorT error)
 | 
			
		||||
{
 | 
			
		||||
	struct lock_wait *lwait = (struct lock_wait *)(long)invocation;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("lck_lock_callback, error = %d\n", error);
 | 
			
		||||
 | 
			
		||||
	lwait->status = error;
 | 
			
		||||
	pthread_mutex_lock(&lwait->mutex);
 | 
			
		||||
	pthread_cond_signal(&lwait->cond);
 | 
			
		||||
	pthread_mutex_unlock(&lwait->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lck_unlock_callback(SaInvocationT invocation,
 | 
			
		||||
				SaAisErrorT error)
 | 
			
		||||
{
 | 
			
		||||
	struct lock_wait *lwait = (struct lock_wait *)(long)invocation;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("lck_unlock_callback\n");
 | 
			
		||||
 | 
			
		||||
	lwait->status = SA_AIS_OK;
 | 
			
		||||
	pthread_mutex_lock(&lwait->mutex);
 | 
			
		||||
	pthread_cond_signal(&lwait->cond);
 | 
			
		||||
	pthread_mutex_unlock(&lwait->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int lck_dispatch(struct local_client *client, char *buf, int len,
 | 
			
		||||
@@ -314,7 +350,7 @@ static int _init_cluster(void)
 | 
			
		||||
	lock_hash = dm_hash_create(10);
 | 
			
		||||
 | 
			
		||||
	err = cpg_initialize(&cpg_handle,
 | 
			
		||||
			     &openais_cpg_callbacks);
 | 
			
		||||
			     &cpg_callbacks);
 | 
			
		||||
	if (err != SA_AIS_OK) {
 | 
			
		||||
		syslog(LOG_ERR, "Cannot initialise OpenAIS CPG service: %d",
 | 
			
		||||
		       err);
 | 
			
		||||
@@ -323,10 +359,10 @@ static int _init_cluster(void)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = saLckInitialize(&lck_handle,
 | 
			
		||||
					NULL,
 | 
			
		||||
			      &lck_callbacks,
 | 
			
		||||
			      &ver);
 | 
			
		||||
	if (err != SA_AIS_OK) {
 | 
			
		||||
		cpg_initialize(&cpg_handle, &openais_cpg_callbacks);
 | 
			
		||||
		cpg_initialize(&cpg_handle, &cpg_callbacks);
 | 
			
		||||
		syslog(LOG_ERR, "Cannot initialise OpenAIS lock service: %d",
 | 
			
		||||
		       err);
 | 
			
		||||
		DEBUGLOG("Cannot initialise OpenAIS lock service: %d\n\n", err);
 | 
			
		||||
@@ -365,6 +401,9 @@ static int _init_cluster(void)
 | 
			
		||||
 | 
			
		||||
static void _cluster_closedown(void)
 | 
			
		||||
{
 | 
			
		||||
	DEBUGLOG("cluster_closedown\n");
 | 
			
		||||
	unlock_all();
 | 
			
		||||
 | 
			
		||||
	saLckFinalize(lck_handle);
 | 
			
		||||
	cpg_finalize(cpg_handle);
 | 
			
		||||
}
 | 
			
		||||
@@ -396,7 +435,7 @@ static int _name_from_csid(const char *csid, char *name)
 | 
			
		||||
	ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
 | 
			
		||||
	if (!ninfo)
 | 
			
		||||
	{
 | 
			
		||||
		sprintf(name, "UNKNOWN %s", print_openais_csid(csid));
 | 
			
		||||
		sprintf(name, "UNKNOWN %s", print_csid(csid));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -418,7 +457,7 @@ static void _add_up_node(const char *csid)
 | 
			
		||||
	ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
 | 
			
		||||
	if (!ninfo) {
 | 
			
		||||
		DEBUGLOG("openais_add_up_node no node_hash entry for csid %s\n",
 | 
			
		||||
			 print_openais_csid(csid));
 | 
			
		||||
			 print_csid(csid));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -436,7 +475,6 @@ static int _cluster_do_node_callback(struct local_client *master_client,
 | 
			
		||||
{
 | 
			
		||||
	struct dm_hash_node *hn;
 | 
			
		||||
	struct node_info *ninfo;
 | 
			
		||||
	int somedown = 0;
 | 
			
		||||
 | 
			
		||||
	dm_hash_iterate(hn, node_hash)
 | 
			
		||||
	{
 | 
			
		||||
@@ -450,20 +488,22 @@ static int _cluster_do_node_callback(struct local_client *master_client,
 | 
			
		||||
 | 
			
		||||
		if (ninfo->state != NODE_DOWN)
 | 
			
		||||
			callback(master_client, csid, ninfo->state == NODE_CLVMD);
 | 
			
		||||
		if (ninfo->state != NODE_CLVMD)
 | 
			
		||||
			somedown = -1;
 | 
			
		||||
	}
 | 
			
		||||
	return somedown;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Real locking */
 | 
			
		||||
static int _lock_resource(char *resource, int mode, int flags, int *lockid)
 | 
			
		||||
{
 | 
			
		||||
	struct lock_wait lwait;
 | 
			
		||||
	struct lock_info *linfo;
 | 
			
		||||
	SaLckResourceHandleT res_handle;
 | 
			
		||||
	SaAisErrorT err;
 | 
			
		||||
	SaLckLockIdT lock_id;
 | 
			
		||||
	SaLckLockStatusT lockStatus;
 | 
			
		||||
 | 
			
		||||
	pthread_cond_init(&lwait.cond, NULL);
 | 
			
		||||
	pthread_mutex_init(&lwait.mutex, NULL);
 | 
			
		||||
	pthread_mutex_lock(&lwait.mutex);
 | 
			
		||||
 | 
			
		||||
	/* This needs to be converted from DLM/LVM2 value for OpenAIS LCK */
 | 
			
		||||
	if (flags & LCK_NONBLOCK) flags = SA_LCK_LOCK_NO_QUEUE;
 | 
			
		||||
@@ -486,15 +526,13 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
 | 
			
		||||
		return ais_to_errno(err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = saLckResourceLock(
 | 
			
		||||
			res_handle,
 | 
			
		||||
			&lock_id,
 | 
			
		||||
			mode,
 | 
			
		||||
			flags,
 | 
			
		||||
			0,
 | 
			
		||||
			SA_TIME_END,
 | 
			
		||||
			&lockStatus);
 | 
			
		||||
	if (err != SA_AIS_OK && lockStatus != SA_LCK_LOCK_GRANTED)
 | 
			
		||||
	err = saLckResourceLockAsync(res_handle,
 | 
			
		||||
				     (SaInvocationT)(long)&lwait,
 | 
			
		||||
				     &lock_id,
 | 
			
		||||
				     mode,
 | 
			
		||||
				     flags,
 | 
			
		||||
				     0);
 | 
			
		||||
	if (err != SA_AIS_OK)
 | 
			
		||||
	{
 | 
			
		||||
		free(linfo);
 | 
			
		||||
		saLckResourceClose(res_handle);
 | 
			
		||||
@@ -502,43 +540,54 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wait for it to complete */
 | 
			
		||||
	pthread_cond_wait(&lwait.cond, &lwait.mutex);
 | 
			
		||||
	pthread_mutex_unlock(&lwait.mutex);
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("lock_resource returning %d, lock_id=%" PRIx64 "\n",
 | 
			
		||||
		 err, lock_id);
 | 
			
		||||
	DEBUGLOG("lock_resource returning %d, lock_id=%llx\n", lwait.status,
 | 
			
		||||
		 lock_id);
 | 
			
		||||
 | 
			
		||||
	linfo->lock_id = lock_id;
 | 
			
		||||
	linfo->res_handle = res_handle;
 | 
			
		||||
 | 
			
		||||
	dm_hash_insert(lock_hash, resource, linfo);
 | 
			
		||||
 | 
			
		||||
	return ais_to_errno(err);
 | 
			
		||||
	return ais_to_errno(lwait.status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int _unlock_resource(char *resource, int lockid)
 | 
			
		||||
{
 | 
			
		||||
	struct lock_wait lwait;
 | 
			
		||||
	SaAisErrorT err;
 | 
			
		||||
	struct lock_info *linfo;
 | 
			
		||||
 | 
			
		||||
	pthread_cond_init(&lwait.cond, NULL);
 | 
			
		||||
	pthread_mutex_init(&lwait.mutex, NULL);
 | 
			
		||||
	pthread_mutex_lock(&lwait.mutex);
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("unlock_resource %s\n", resource);
 | 
			
		||||
	linfo = dm_hash_lookup(lock_hash, resource);
 | 
			
		||||
	if (!linfo)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("unlock_resource: lockid: %" PRIx64 "\n", linfo->lock_id);
 | 
			
		||||
	err = saLckResourceUnlock(linfo->lock_id, SA_TIME_END);
 | 
			
		||||
	DEBUGLOG("unlock_resource: lockid: %llx\n", linfo->lock_id);
 | 
			
		||||
	err = saLckResourceUnlockAsync((SaInvocationT)(long)&lwait, linfo->lock_id);
 | 
			
		||||
	if (err != SA_AIS_OK)
 | 
			
		||||
	{
 | 
			
		||||
		DEBUGLOG("Unlock returned %d\n", err);
 | 
			
		||||
		return ais_to_errno(err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wait for it to complete */
 | 
			
		||||
	pthread_cond_wait(&lwait.cond, &lwait.mutex);
 | 
			
		||||
	pthread_mutex_unlock(&lwait.mutex);
 | 
			
		||||
 | 
			
		||||
	/* Release the resource */
 | 
			
		||||
	dm_hash_remove(lock_hash, resource);
 | 
			
		||||
	saLckResourceClose(linfo->res_handle);
 | 
			
		||||
	free(linfo);
 | 
			
		||||
 | 
			
		||||
	return ais_to_errno(err);
 | 
			
		||||
	return ais_to_errno(lwait.status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _sync_lock(const char *resource, int mode, int flags, int *lockid)
 | 
			
		||||
@@ -661,7 +710,6 @@ static int _get_cluster_name(char *buf, int buflen)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct cluster_ops _cluster_openais_ops = {
 | 
			
		||||
	.name                     = "openais",
 | 
			
		||||
	.cluster_init_completed   = NULL,
 | 
			
		||||
	.cluster_send_message     = _cluster_send_message,
 | 
			
		||||
	.name_from_csid           = _name_from_csid,
 | 
			
		||||
@@ -684,6 +732,6 @@ struct cluster_ops *init_openais_cluster(void)
 | 
			
		||||
{
 | 
			
		||||
	if (!_init_cluster())
 | 
			
		||||
		return &_cluster_openais_ops;
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
	else
 | 
			
		||||
		return NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,382 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009-2013 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clvmd-common.h"
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#include "locking.h"
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "clvmd-comms.h"
 | 
			
		||||
#include "clvmd.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
static const char SINGLENODE_CLVMD_SOCKNAME[] = DEFAULT_RUN_DIR "/clvmd_singlenode.sock";
 | 
			
		||||
static int listen_fd = -1;
 | 
			
		||||
 | 
			
		||||
static struct dm_hash_table *_locks;
 | 
			
		||||
static int _lockid;
 | 
			
		||||
 | 
			
		||||
static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
/* Using one common condition for all locks for simplicity */
 | 
			
		||||
static pthread_cond_t _lock_cond = PTHREAD_COND_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
struct lock {
 | 
			
		||||
	struct dm_list list;
 | 
			
		||||
	int lockid;
 | 
			
		||||
	int mode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void close_comms(void)
 | 
			
		||||
{
 | 
			
		||||
	if (listen_fd != -1 && close(listen_fd))
 | 
			
		||||
		stack;
 | 
			
		||||
	(void)unlink(SINGLENODE_CLVMD_SOCKNAME);
 | 
			
		||||
	listen_fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int init_comms(void)
 | 
			
		||||
{
 | 
			
		||||
	mode_t old_mask;
 | 
			
		||||
	struct sockaddr_un addr = { .sun_family = AF_UNIX };
 | 
			
		||||
 | 
			
		||||
	if (!dm_strncpy(addr.sun_path, SINGLENODE_CLVMD_SOCKNAME,
 | 
			
		||||
			sizeof(addr.sun_path))) {
 | 
			
		||||
		DEBUGLOG("%s: singlenode socket name too long.",
 | 
			
		||||
			 SINGLENODE_CLVMD_SOCKNAME);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	close_comms();
 | 
			
		||||
 | 
			
		||||
	(void) dm_prepare_selinux_context(SINGLENODE_CLVMD_SOCKNAME, S_IFSOCK);
 | 
			
		||||
	old_mask = umask(0077);
 | 
			
		||||
 | 
			
		||||
	listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
 | 
			
		||||
	if (listen_fd < 0) {
 | 
			
		||||
		DEBUGLOG("Can't create local socket: %s\n", strerror(errno));
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
	/* Set Close-on-exec */
 | 
			
		||||
	if (fcntl(listen_fd, F_SETFD, 1)) {
 | 
			
		||||
		DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
 | 
			
		||||
		DEBUGLOG("Can't bind local socket: %s\n", strerror(errno));
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
	if (listen(listen_fd, 10) < 0) {
 | 
			
		||||
		DEBUGLOG("Can't listen local socket: %s\n", strerror(errno));
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	umask(old_mask);
 | 
			
		||||
	(void) dm_prepare_selinux_context(NULL, 0);
 | 
			
		||||
	return 0;
 | 
			
		||||
error:
 | 
			
		||||
	umask(old_mask);
 | 
			
		||||
	(void) dm_prepare_selinux_context(NULL, 0);
 | 
			
		||||
	close_comms();
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _init_cluster(void)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if (!(_locks = dm_hash_create(128))) {
 | 
			
		||||
		DEBUGLOG("Failed to allocate single-node hash table.\n");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = init_comms();
 | 
			
		||||
	if (r) {
 | 
			
		||||
		dm_hash_destroy(_locks);
 | 
			
		||||
		_locks = NULL;
 | 
			
		||||
		return r;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("Single-node cluster initialised.\n");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _cluster_closedown(void)
 | 
			
		||||
{
 | 
			
		||||
	close_comms();
 | 
			
		||||
 | 
			
		||||
	/* If there is any awaited resource, kill it softly */
 | 
			
		||||
	pthread_mutex_lock(&_lock_mutex);
 | 
			
		||||
	dm_hash_destroy(_locks);
 | 
			
		||||
	_locks = NULL;
 | 
			
		||||
	_lockid = 0;
 | 
			
		||||
	pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
 | 
			
		||||
	pthread_mutex_unlock(&_lock_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _get_our_csid(char *csid)
 | 
			
		||||
{
 | 
			
		||||
	int nodeid = 1;
 | 
			
		||||
	memcpy(csid, &nodeid, sizeof(int));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _csid_from_name(char *csid, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _name_from_csid(const char *csid, char *name)
 | 
			
		||||
{
 | 
			
		||||
	strcpy(name, "SINGLENODE");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_num_nodes(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Node is now known to be running a clvmd */
 | 
			
		||||
static void _add_up_node(const char *csid)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Call a callback for each node, so the caller knows whether it's up or down */
 | 
			
		||||
static int _cluster_do_node_callback(struct local_client *master_client,
 | 
			
		||||
				     void (*callback)(struct local_client *,
 | 
			
		||||
				     const char *csid, int node_up))
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _lock_file(const char *file, uint32_t flags);
 | 
			
		||||
 | 
			
		||||
static const char *_get_mode(int mode)
 | 
			
		||||
{
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
	case LCK_NULL: return "NULL";
 | 
			
		||||
	case LCK_READ: return "READ";
 | 
			
		||||
	case LCK_PREAD: return "PREAD";
 | 
			
		||||
	case LCK_WRITE: return "WRITE";
 | 
			
		||||
	case LCK_EXCL: return "EXCLUSIVE";
 | 
			
		||||
	case LCK_UNLOCK: return "UNLOCK";
 | 
			
		||||
	default: return "????";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Real locking */
 | 
			
		||||
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
 | 
			
		||||
{
 | 
			
		||||
	/* DLM table of allowed transition states */
 | 
			
		||||
	static const int _dlm_table[6][6] = {
 | 
			
		||||
	/* Mode	   NL	CR	CW	PR	PW	EX */
 | 
			
		||||
	/* NL */ { 1,	 1,	 1,	 1,	 1,	 1},
 | 
			
		||||
	/* CR */ { 1,	 1,	 1,	 1,	 1,	 0},
 | 
			
		||||
	/* CW */ { 1,	 1,	 1,	 0,	 0,	 0},
 | 
			
		||||
	/* PR */ { 1,	 1,	 0,	 1,	 0,	 0},
 | 
			
		||||
	/* PW */ { 1,	 1,	 0,	 0,	 0,	 0},
 | 
			
		||||
	/* EX */ { 1,	 0,	 0,	 0,	 0,	 0}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct lock *lck = NULL, *lckt;
 | 
			
		||||
	struct dm_list *head;
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("Locking resource %s, flags=0x%02x (%s%s%s), mode=%s (%d)\n",
 | 
			
		||||
		 resource, flags,
 | 
			
		||||
		 (flags & LCKF_NOQUEUE) ? "NOQUEUE" : "",
 | 
			
		||||
		 ((flags & (LCKF_NOQUEUE | LCKF_CONVERT)) ==
 | 
			
		||||
		  (LCKF_NOQUEUE | LCKF_CONVERT)) ? "|" : "",
 | 
			
		||||
		 (flags & LCKF_CONVERT) ? "CONVERT" : "",
 | 
			
		||||
		 _get_mode(mode), mode);
 | 
			
		||||
 | 
			
		||||
	mode &= LCK_TYPE_MASK;
 | 
			
		||||
	pthread_mutex_lock(&_lock_mutex);
 | 
			
		||||
 | 
			
		||||
retry:
 | 
			
		||||
	if (!(head = dm_hash_lookup(_locks, resource))) {
 | 
			
		||||
		if (flags & LCKF_CONVERT) {
 | 
			
		||||
			/* In real DLM, lock is identified only by lockid, resource is not used */
 | 
			
		||||
			DEBUGLOG("Unlocked resource %s cannot be converted\n", resource);
 | 
			
		||||
			goto_bad;
 | 
			
		||||
		}
 | 
			
		||||
		/* Add new locked resource */
 | 
			
		||||
		if (!(head = dm_malloc(sizeof(struct dm_list))) ||
 | 
			
		||||
		    !dm_hash_insert(_locks, resource, head)) {
 | 
			
		||||
			dm_free(head);
 | 
			
		||||
			goto_bad;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		dm_list_init(head);
 | 
			
		||||
	} else	/* Update/convert locked resource */
 | 
			
		||||
		dm_list_iterate_items(lck, head) {
 | 
			
		||||
			/* Check is all locks are compatible with requested lock */
 | 
			
		||||
			if (flags & LCKF_CONVERT) {
 | 
			
		||||
				if (lck->lockid != *lockid)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				DEBUGLOG("Converting resource %s lockid=%d mode:%s -> %s...\n",
 | 
			
		||||
					 resource, lck->lockid, _get_mode(lck->mode), _get_mode(mode));
 | 
			
		||||
				dm_list_iterate_items(lckt, head) {
 | 
			
		||||
					if ((lckt->lockid != *lockid) &&
 | 
			
		||||
					    !_dlm_table[mode][lckt->mode]) {
 | 
			
		||||
						if (!(flags & LCKF_NOQUEUE) &&
 | 
			
		||||
						    /* TODO: Real dlm uses here conversion queues */
 | 
			
		||||
						    !pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
 | 
			
		||||
						    _locks) /* End of the game? */
 | 
			
		||||
							goto retry;
 | 
			
		||||
						goto bad;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				lck->mode = mode; /* Lock is now converted */
 | 
			
		||||
				goto out;
 | 
			
		||||
			} else if (!_dlm_table[mode][lck->mode]) {
 | 
			
		||||
				DEBUGLOG("Resource %s already locked lockid=%d, mode:%s\n",
 | 
			
		||||
					 resource, lck->lockid, _get_mode(lck->mode));
 | 
			
		||||
				if (!(flags & LCKF_NOQUEUE) &&
 | 
			
		||||
				    !pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
 | 
			
		||||
				    _locks) { /* End of the game? */
 | 
			
		||||
					DEBUGLOG("Resource %s retrying lock in mode:%s...\n",
 | 
			
		||||
						 resource, _get_mode(mode));
 | 
			
		||||
					goto retry;
 | 
			
		||||
				}
 | 
			
		||||
				goto bad;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	if (!(flags & LCKF_CONVERT)) {
 | 
			
		||||
		if (!(lck = dm_malloc(sizeof(struct lock))))
 | 
			
		||||
			goto_bad;
 | 
			
		||||
 | 
			
		||||
		*lockid = lck->lockid = ++_lockid;
 | 
			
		||||
		lck->mode = mode;
 | 
			
		||||
		dm_list_add(head, &lck->list);
 | 
			
		||||
	}
 | 
			
		||||
out:
 | 
			
		||||
	pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
 | 
			
		||||
	pthread_mutex_unlock(&_lock_mutex);
 | 
			
		||||
	DEBUGLOG("Locked resource %s, lockid=%d, mode=%s\n",
 | 
			
		||||
		 resource, lck->lockid, _get_mode(lck->mode));
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
bad:
 | 
			
		||||
	pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
 | 
			
		||||
	pthread_mutex_unlock(&_lock_mutex);
 | 
			
		||||
	DEBUGLOG("Failed to lock resource %s\n", resource);
 | 
			
		||||
 | 
			
		||||
	return 1; /* fail */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _unlock_resource(const char *resource, int lockid)
 | 
			
		||||
{
 | 
			
		||||
	struct lock *lck;
 | 
			
		||||
	struct dm_list *head;
 | 
			
		||||
	int r = 1;
 | 
			
		||||
 | 
			
		||||
	if (lockid < 0) {
 | 
			
		||||
		DEBUGLOG("Not tracking unlock of lockid -1: %s, lockid=%d\n",
 | 
			
		||||
			 resource, lockid);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("Unlocking resource %s, lockid=%d\n", resource, lockid);
 | 
			
		||||
	pthread_mutex_lock(&_lock_mutex);
 | 
			
		||||
	pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
 | 
			
		||||
 | 
			
		||||
	if (!(head = dm_hash_lookup(_locks, resource))) {
 | 
			
		||||
		pthread_mutex_unlock(&_lock_mutex);
 | 
			
		||||
		DEBUGLOG("Resource %s is not locked.\n", resource);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dm_list_iterate_items(lck, head)
 | 
			
		||||
		if (lck->lockid == lockid) {
 | 
			
		||||
			dm_list_del(&lck->list);
 | 
			
		||||
			dm_free(lck);
 | 
			
		||||
			r = 0;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	DEBUGLOG("Resource %s has wrong lockid %d.\n", resource, lockid);
 | 
			
		||||
out:
 | 
			
		||||
	if (dm_list_empty(head)) {
 | 
			
		||||
		//DEBUGLOG("Resource %s is no longer hashed (lockid=%d).\n", resource, lockid);
 | 
			
		||||
		dm_hash_remove(_locks, resource);
 | 
			
		||||
		dm_free(head);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pthread_mutex_unlock(&_lock_mutex);
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _is_quorate(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_main_cluster_fd(void)
 | 
			
		||||
{
 | 
			
		||||
	return listen_fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
 | 
			
		||||
				const char *csid,
 | 
			
		||||
				struct local_client **new_client)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _cluster_send_message(const void *buf, int msglen,
 | 
			
		||||
				 const char *csid,
 | 
			
		||||
				 const char *errtext)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _get_cluster_name(char *buf, int buflen)
 | 
			
		||||
{
 | 
			
		||||
	return dm_strncpy(buf, "localcluster", buflen) ? 0 : 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct cluster_ops _cluster_singlenode_ops = {
 | 
			
		||||
	.name                     = "singlenode",
 | 
			
		||||
	.cluster_init_completed   = NULL,
 | 
			
		||||
	.cluster_send_message     = _cluster_send_message,
 | 
			
		||||
	.name_from_csid           = _name_from_csid,
 | 
			
		||||
	.csid_from_name           = _csid_from_name,
 | 
			
		||||
	.get_num_nodes            = _get_num_nodes,
 | 
			
		||||
	.cluster_fd_callback      = _cluster_fd_callback,
 | 
			
		||||
	.get_main_cluster_fd      = _get_main_cluster_fd,
 | 
			
		||||
	.cluster_do_node_callback = _cluster_do_node_callback,
 | 
			
		||||
	.is_quorate               = _is_quorate,
 | 
			
		||||
	.get_our_csid             = _get_our_csid,
 | 
			
		||||
	.add_up_node              = _add_up_node,
 | 
			
		||||
	.reread_config            = NULL,
 | 
			
		||||
	.cluster_closedown        = _cluster_closedown,
 | 
			
		||||
	.get_cluster_name         = _get_cluster_name,
 | 
			
		||||
	.sync_lock                = _lock_resource,
 | 
			
		||||
	.sync_unlock              = _unlock_resource,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cluster_ops *init_singlenode_cluster(void)
 | 
			
		||||
{
 | 
			
		||||
	if (!_init_cluster())
 | 
			
		||||
		return &_cluster_singlenode_ops;
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -20,6 +20,9 @@
 | 
			
		||||
#define CLVMD_MINOR_VERSION 2
 | 
			
		||||
#define CLVMD_PATCH_VERSION 1
 | 
			
		||||
 | 
			
		||||
/* Name of the cluster LVM admin lock */
 | 
			
		||||
#define ADMIN_LOCK_NAME "CLVMD_ADMIN"
 | 
			
		||||
 | 
			
		||||
/* Default time (in seconds) we will wait for all remote commands to execute
 | 
			
		||||
   before declaring them dead */
 | 
			
		||||
#define DEFAULT_CMD_TIMEOUT 60
 | 
			
		||||
@@ -32,8 +35,6 @@ struct node_reply {
 | 
			
		||||
	struct node_reply *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef enum {DEBUG_OFF, DEBUG_STDERR, DEBUG_SYSLOG} debug_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These exist for the use of local sockets only when we are
 | 
			
		||||
 * collecting responses from all cluster nodes
 | 
			
		||||
@@ -53,12 +54,13 @@ struct localsock_bits {
 | 
			
		||||
	int finished;		/* Flag to tell subthread to exit */
 | 
			
		||||
	int all_success;	/* Set to 0 if any node (or the pre_command)
 | 
			
		||||
				   failed */
 | 
			
		||||
	int cleanup_needed;     /* helper for cleanup_zombie */
 | 
			
		||||
	struct local_client *pipe_client;
 | 
			
		||||
	pthread_t threadid;
 | 
			
		||||
	enum { PRE_COMMAND, POST_COMMAND } state;
 | 
			
		||||
	enum { PRE_COMMAND, POST_COMMAND, QUIT } state;
 | 
			
		||||
	pthread_mutex_t mutex;	/* Main thread and worker synchronisation */
 | 
			
		||||
	pthread_cond_t cond;
 | 
			
		||||
 | 
			
		||||
	pthread_mutex_t reply_mutex;	/* Protect reply structure */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Entries for PIPE clients */
 | 
			
		||||
@@ -94,7 +96,7 @@ struct local_client {
 | 
			
		||||
	} bits;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEBUGLOG(fmt, args...) debuglog(fmt, ## args)
 | 
			
		||||
#define DEBUGLOG(fmt, args...) debuglog(fmt, ## args);
 | 
			
		||||
 | 
			
		||||
#ifndef max
 | 
			
		||||
#define max(a,b) ((a)>(b)?(a):(b))
 | 
			
		||||
@@ -111,15 +113,11 @@ extern void cmd_client_cleanup(struct local_client *client);
 | 
			
		||||
extern int add_client(struct local_client *new_client);
 | 
			
		||||
 | 
			
		||||
extern void clvmd_cluster_init_completed(void);
 | 
			
		||||
extern void process_message(struct local_client *client, char *buf,
 | 
			
		||||
extern void process_message(struct local_client *client, const char *buf,
 | 
			
		||||
			    int len, const char *csid);
 | 
			
		||||
extern void debuglog(const char *fmt, ... )
 | 
			
		||||
  __attribute__ ((format(printf, 1, 2)));
 | 
			
		||||
 | 
			
		||||
void clvmd_set_debug(debug_t new_de);
 | 
			
		||||
debug_t clvmd_get_debug(void);
 | 
			
		||||
int clvmd_get_foreground(void);
 | 
			
		||||
 | 
			
		||||
int sync_lock(const char *resource, int mode, int flags, int *lockid);
 | 
			
		||||
int sync_unlock(const char *resource, int lockid);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										226
									
								
								daemons/clvmd/cnxman-socket.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								daemons/clvmd/cnxman-socket.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*******************************************************************************
 | 
			
		||||
**
 | 
			
		||||
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
 | 
			
		||||
**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
 | 
			
		||||
**
 | 
			
		||||
**  This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
**  modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
**  of the GNU General Public License v.2.
 | 
			
		||||
**
 | 
			
		||||
*******************************************************************************
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* CMAN socket interface header,
 | 
			
		||||
   may be include by user or kernel code */
 | 
			
		||||
 | 
			
		||||
#ifndef __CNXMAN_SOCKET_H
 | 
			
		||||
#define __CNXMAN_SOCKET_H
 | 
			
		||||
 | 
			
		||||
/* A currently unused number. TIPC also uses this number and you're unlikely
 | 
			
		||||
   to be using both.
 | 
			
		||||
 */
 | 
			
		||||
#define AF_CLUSTER 30
 | 
			
		||||
#define PF_CLUSTER AF_CLUSTER
 | 
			
		||||
 | 
			
		||||
/* Protocol(socket) types */
 | 
			
		||||
#define CLPROTO_MASTER 2
 | 
			
		||||
#define CLPROTO_CLIENT 3
 | 
			
		||||
 | 
			
		||||
/* ioctls -- should register these properly */
 | 
			
		||||
#define SIOCCLUSTER_NOTIFY            _IOW('x', 0x01, int)
 | 
			
		||||
#define SIOCCLUSTER_REMOVENOTIFY      _IO( 'x', 0x02)
 | 
			
		||||
#define SIOCCLUSTER_GETMEMBERS        _IOR('x', 0x03, struct cl_cluster_nodelist)
 | 
			
		||||
#define SIOCCLUSTER_SETEXPECTED_VOTES _IOW('x', 0x04, int)
 | 
			
		||||
#define SIOCCLUSTER_ISQUORATE         _IO( 'x', 0x05)
 | 
			
		||||
#define SIOCCLUSTER_ISLISTENING       _IOW('x', 0x06, struct cl_listen_request)
 | 
			
		||||
#define SIOCCLUSTER_GETALLMEMBERS     _IOR('x', 0x07, struct cl_cluster_nodelist)
 | 
			
		||||
#define SIOCCLUSTER_SET_VOTES         _IOW('x', 0x08, int)
 | 
			
		||||
#define SIOCCLUSTER_GET_VERSION       _IOR('x', 0x09, struct cl_version)
 | 
			
		||||
#define SIOCCLUSTER_SET_VERSION       _IOW('x', 0x0a, struct cl_version)
 | 
			
		||||
#define SIOCCLUSTER_ISACTIVE          _IO( 'x', 0x0b)
 | 
			
		||||
#define SIOCCLUSTER_KILLNODE          _IOW('x', 0x0c, int)
 | 
			
		||||
#define SIOCCLUSTER_GET_JOINCOUNT     _IO( 'x', 0x0d)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_REGISTER  _IOW('x', 0x0e, char)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_UNREGISTER _IO('x', 0x0f)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_JOIN      _IO( 'x', 0x10)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_LEAVE     _IO( 'x', 0x20)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_SETSIGNAL _IOW('x', 0x30, int)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_STARTDONE _IOW('x', 0x40, unsigned int)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_GETEVENT  _IOR('x', 0x50, struct cl_service_event)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_GETMEMBERS _IOR('x', 0x60, struct cl_cluster_nodelist)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_GLOBALID  _IOR('x', 0x70, uint32_t)
 | 
			
		||||
#define SIOCCLUSTER_SERVICE_SETLEVEL  _IOR('x', 0x80, int)
 | 
			
		||||
#define SIOCCLUSTER_GETNODE	      _IOWR('x', 0x90, struct cl_cluster_node)
 | 
			
		||||
#define SIOCCLUSTER_BARRIER           _IOW('x', 0x0a0, struct cl_barrier_info)
 | 
			
		||||
 | 
			
		||||
/* These were setsockopts */
 | 
			
		||||
#define SIOCCLUSTER_PASS_SOCKET       _IOW('x', 0x0b0, struct cl_passed_sock)
 | 
			
		||||
#define SIOCCLUSTER_SET_NODENAME      _IOW('x', 0x0b1, char *)
 | 
			
		||||
#define SIOCCLUSTER_SET_NODEID        _IOW('x', 0x0b2, int)
 | 
			
		||||
#define SIOCCLUSTER_JOIN_CLUSTER      _IOW('x', 0x0b3, struct cl_join_cluster_info)
 | 
			
		||||
#define SIOCCLUSTER_LEAVE_CLUSTER     _IOW('x', 0x0b4, int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Maximum size of a cluster message */
 | 
			
		||||
#define CMAN_MAX_CLUSTER_MESSAGE          1500
 | 
			
		||||
#define CMAN_MAX_CLUSTER_MEMBER_NAME_LEN   255
 | 
			
		||||
#define MAX_BARRIER_NAME_LEN           33
 | 
			
		||||
#define MAX_SA_ADDR_LEN                12
 | 
			
		||||
#define MAX_CLUSTER_NAME_LEN           16
 | 
			
		||||
 | 
			
		||||
/* Well-known cluster port numbers */
 | 
			
		||||
#define CLUSTER_PORT_MEMBERSHIP  1	/* Mustn't block during cluster
 | 
			
		||||
					 * transitions! */
 | 
			
		||||
#define CLUSTER_PORT_SERVICES    2
 | 
			
		||||
#define CLUSTER_PORT_SYSMAN      10	/* Remote execution daemon */
 | 
			
		||||
#define CLUSTER_PORT_CLVMD       11	/* Cluster LVM daemon */
 | 
			
		||||
#define CLUSTER_PORT_SLM         12	/* LVM SLM (simple lock manager) */
 | 
			
		||||
 | 
			
		||||
/* Port numbers above this will be blocked when the cluster is inquorate or in
 | 
			
		||||
 * transition */
 | 
			
		||||
#define HIGH_PROTECTED_PORT      9
 | 
			
		||||
 | 
			
		||||
/* Reasons for leaving the cluster */
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_DOWN     0	/* Normal shutdown */
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_KILLED   1
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_PANIC    2
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_REMOVED  3	/* This one can reduce quorum */
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_REJECTED 4	/* Not allowed into the cluster in the
 | 
			
		||||
					 * first place */
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_INCONSISTENT 5	/* Our view of the cluster is
 | 
			
		||||
						 * in a minority */
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_DEAD         6	/* Discovered to be dead */
 | 
			
		||||
#define CLUSTER_LEAVEFLAG_FORCE     0x10	/* Forced by command-line */
 | 
			
		||||
 | 
			
		||||
/* OOB messages sent to a local socket */
 | 
			
		||||
#define CLUSTER_OOB_MSG_PORTCLOSED  1
 | 
			
		||||
#define CLUSTER_OOB_MSG_STATECHANGE 2
 | 
			
		||||
#define CLUSTER_OOB_MSG_SERVICEEVENT 3
 | 
			
		||||
 | 
			
		||||
/* Sendmsg flags, these are above the normal sendmsg flags so they don't
 | 
			
		||||
 * interfere */
 | 
			
		||||
#define MSG_NOACK     0x010000	/* Don't need an ACK for this message */
 | 
			
		||||
#define MSG_QUEUE     0x020000	/* Queue the message for sending later */
 | 
			
		||||
#define MSG_MULTICAST 0x080000	/* Message was sent to all nodes in the cluster
 | 
			
		||||
				 */
 | 
			
		||||
#define MSG_ALLINT    0x100000	/* Send out of all interfaces */
 | 
			
		||||
#define MSG_REPLYEXP  0x200000	/* Reply is expected */
 | 
			
		||||
 | 
			
		||||
typedef enum { NODESTATE_REMOTEMEMBER, NODESTATE_JOINING, NODESTATE_MEMBER,
 | 
			
		||||
	       NODESTATE_DEAD } nodestate_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct sockaddr_cl {
 | 
			
		||||
	unsigned short scl_family;
 | 
			
		||||
	unsigned char scl_flags;
 | 
			
		||||
	unsigned char scl_port;
 | 
			
		||||
	int           scl_nodeid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This is how we pass the multicast & receive sockets into kernel space.
 | 
			
		||||
 */
 | 
			
		||||
struct cl_passed_sock {
 | 
			
		||||
	int fd;			/* FD of master socket to do multicast on */
 | 
			
		||||
	int number;		/* Socket number, to match up recvonly & bcast
 | 
			
		||||
				 * sockets */
 | 
			
		||||
        int multicast;          /* Is it multicast or receive ? */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Cluster configuration info passed when we join the cluster */
 | 
			
		||||
struct cl_join_cluster_info {
 | 
			
		||||
	unsigned char votes;
 | 
			
		||||
	unsigned int expected_votes;
 | 
			
		||||
	unsigned int two_node;
 | 
			
		||||
	unsigned int config_version;
 | 
			
		||||
 | 
			
		||||
        char cluster_name[17];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This is the structure, per node, returned from the membership ioctl */
 | 
			
		||||
struct cl_cluster_node {
 | 
			
		||||
	unsigned int size;
 | 
			
		||||
	unsigned int node_id;
 | 
			
		||||
	unsigned int us;
 | 
			
		||||
	unsigned int leave_reason;
 | 
			
		||||
	unsigned int incarnation;
 | 
			
		||||
	nodestate_t state;
 | 
			
		||||
	char name[CMAN_MAX_CLUSTER_MEMBER_NAME_LEN];
 | 
			
		||||
	unsigned char votes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* The struct passed to the membership ioctls */
 | 
			
		||||
struct cl_cluster_nodelist {
 | 
			
		||||
        uint32_t max_members;
 | 
			
		||||
        struct cl_cluster_node *nodes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Structure passed to SIOCCLUSTER_ISLISTENING */
 | 
			
		||||
struct cl_listen_request {
 | 
			
		||||
	unsigned char port;
 | 
			
		||||
        int           nodeid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* A Cluster PORTCLOSED message - received by a local user as an OOB message */
 | 
			
		||||
struct cl_portclosed_oob {
 | 
			
		||||
	unsigned char cmd;	/* CLUSTER_OOB_MSG_PORTCLOSED */
 | 
			
		||||
	unsigned char port;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Get all version numbers or set the config version */
 | 
			
		||||
struct cl_version {
 | 
			
		||||
	unsigned int major;
 | 
			
		||||
	unsigned int minor;
 | 
			
		||||
	unsigned int patch;
 | 
			
		||||
	unsigned int config;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* structure passed to barrier ioctls */
 | 
			
		||||
struct cl_barrier_info {
 | 
			
		||||
	char cmd;
 | 
			
		||||
	char name[MAX_BARRIER_NAME_LEN];
 | 
			
		||||
	unsigned int flags;
 | 
			
		||||
	unsigned long arg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef enum { SERVICE_EVENT_STOP, SERVICE_EVENT_START, SERVICE_EVENT_FINISH,
 | 
			
		||||
		SERVICE_EVENT_LEAVEDONE } service_event_t;
 | 
			
		||||
 | 
			
		||||
typedef enum { SERVICE_START_FAILED, SERVICE_START_JOIN, SERVICE_START_LEAVE }
 | 
			
		||||
		service_start_t;
 | 
			
		||||
 | 
			
		||||
struct cl_service_event {
 | 
			
		||||
	service_event_t type;
 | 
			
		||||
	service_start_t start_type;
 | 
			
		||||
	unsigned int event_id;
 | 
			
		||||
	unsigned int last_stop;
 | 
			
		||||
	unsigned int last_start;
 | 
			
		||||
	unsigned int last_finish;
 | 
			
		||||
	unsigned int node_count;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Commands to the barrier ioctl */
 | 
			
		||||
#define BARRIER_IOCTL_REGISTER 1
 | 
			
		||||
#define BARRIER_IOCTL_CHANGE   2
 | 
			
		||||
#define BARRIER_IOCTL_DELETE   3
 | 
			
		||||
#define BARRIER_IOCTL_WAIT     4
 | 
			
		||||
 | 
			
		||||
/* Attributes of a barrier - bitmask */
 | 
			
		||||
#define BARRIER_ATTR_AUTODELETE 1
 | 
			
		||||
#define BARRIER_ATTR_MULTISTEP  2
 | 
			
		||||
#define BARRIER_ATTR_MANUAL     4
 | 
			
		||||
#define BARRIER_ATTR_ENABLED    8
 | 
			
		||||
#define BARRIER_ATTR_CALLBACK  16
 | 
			
		||||
 | 
			
		||||
/* Attribute setting commands */
 | 
			
		||||
#define BARRIER_SETATTR_AUTODELETE 1
 | 
			
		||||
#define BARRIER_SETATTR_MULTISTEP  2
 | 
			
		||||
#define BARRIER_SETATTR_ENABLED    3
 | 
			
		||||
#define BARRIER_SETATTR_NODES      4
 | 
			
		||||
#define BARRIER_SETATTR_CALLBACK   5
 | 
			
		||||
#define BARRIER_SETATTR_TIMEOUT    6
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
@@ -22,20 +22,16 @@ extern int pre_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
 | 
			
		||||
		       char *resource);
 | 
			
		||||
extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
 | 
			
		||||
		      char *resource);
 | 
			
		||||
extern const char *do_lock_query(char *resource);
 | 
			
		||||
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
 | 
			
		||||
			char *resource);
 | 
			
		||||
extern int do_check_lvm1(const char *vgname);
 | 
			
		||||
extern int do_check_lvm1(char *vgname);
 | 
			
		||||
extern int do_refresh_cache(void);
 | 
			
		||||
extern int init_clvm(struct dm_hash_table *excl_uuid);
 | 
			
		||||
extern void destroy_lvm(void);
 | 
			
		||||
extern int init_lvm(int using_gulm);
 | 
			
		||||
extern void init_lvhash(void);
 | 
			
		||||
extern void destroy_lvhash(void);
 | 
			
		||||
extern void lvm_do_backup(const char *vgname);
 | 
			
		||||
 | 
			
		||||
extern int hold_unlock(char *resource);
 | 
			
		||||
extern int hold_lock(char *resource, int mode, int flags);
 | 
			
		||||
extern void unlock_all(void);
 | 
			
		||||
extern char *get_last_lvm_error(void);
 | 
			
		||||
extern void do_lock_vg(unsigned char command, unsigned char lock_flags,
 | 
			
		||||
		      char *resource);
 | 
			
		||||
extern struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name);
 | 
			
		||||
void lvm_do_fs_unlock(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
@@ -13,20 +13,22 @@
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* FIXME Remove duplicated functions from this file. */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Send a command to a running clvmd from the command-line
 | 
			
		||||
 * Tell all clvmds in a cluster to refresh their toolcontext
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clvmd-common.h"
 | 
			
		||||
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "refresh_clvmd.h"
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "refresh_clvmd.h"
 | 
			
		||||
 | 
			
		||||
typedef struct lvm_response {
 | 
			
		||||
	char node[255];
 | 
			
		||||
@@ -43,16 +45,11 @@ typedef struct lvm_response {
 | 
			
		||||
 | 
			
		||||
static int _clvmd_sock = -1;
 | 
			
		||||
 | 
			
		||||
/* Open connection to the clvm daemon */
 | 
			
		||||
/* Open connection to the Cluster Manager daemon */
 | 
			
		||||
static int _open_local_sock(void)
 | 
			
		||||
{
 | 
			
		||||
	int local_socket;
 | 
			
		||||
	struct sockaddr_un sockaddr = { .sun_family = AF_UNIX };
 | 
			
		||||
 | 
			
		||||
	if (!dm_strncpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(sockaddr.sun_path))) {
 | 
			
		||||
		fprintf(stderr, "%s: clvmd socket name too long.", CLVMD_SOCKNAME);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	struct sockaddr_un sockaddr;
 | 
			
		||||
 | 
			
		||||
	/* Open local socket */
 | 
			
		||||
	if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
 | 
			
		||||
@@ -60,6 +57,11 @@ static int _open_local_sock(void)
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memset(&sockaddr, 0, sizeof(sockaddr));
 | 
			
		||||
	memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));
 | 
			
		||||
 | 
			
		||||
	sockaddr.sun_family = AF_UNIX;
 | 
			
		||||
 | 
			
		||||
	if (connect(local_socket,(struct sockaddr *) &sockaddr,
 | 
			
		||||
		    sizeof(sockaddr))) {
 | 
			
		||||
		int saved_errno = errno;
 | 
			
		||||
@@ -77,12 +79,12 @@ static int _open_local_sock(void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Send a request and return the status */
 | 
			
		||||
static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_response)
 | 
			
		||||
static int _send_request(char *inbuf, int inlen, char **retbuf)
 | 
			
		||||
{
 | 
			
		||||
	char outbuf[PIPE_BUF];
 | 
			
		||||
	struct clvm_header *outheader = (struct clvm_header *) outbuf;
 | 
			
		||||
	int len;
 | 
			
		||||
	unsigned off;
 | 
			
		||||
	int off;
 | 
			
		||||
	int buflen;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
@@ -94,8 +96,6 @@ static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_res
 | 
			
		||||
		fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (no_response)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	/* Get the response */
 | 
			
		||||
 reread:
 | 
			
		||||
@@ -151,38 +151,36 @@ static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_res
 | 
			
		||||
 | 
			
		||||
/* Build the structure header and parse-out wildcard node names */
 | 
			
		||||
static void _build_header(struct clvm_header *head, int cmd, const char *node,
 | 
			
		||||
			  unsigned int len)
 | 
			
		||||
			  int len)
 | 
			
		||||
{
 | 
			
		||||
	head->cmd = cmd;
 | 
			
		||||
	head->status = 0;
 | 
			
		||||
	head->flags = 0;
 | 
			
		||||
	head->xid = 0;
 | 
			
		||||
	head->clientid = 0;
 | 
			
		||||
	if (len)
 | 
			
		||||
		/* 1 byte is used from struct clvm_header.args[1], so -> len - 1 */
 | 
			
		||||
		head->arglen = len - 1;
 | 
			
		||||
	else {
 | 
			
		||||
		head->arglen = 0;
 | 
			
		||||
		*head->args = '\0';
 | 
			
		||||
	}
 | 
			
		||||
	head->arglen = len;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Translate special node names.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!node || !strcmp(node, NODE_ALL))
 | 
			
		||||
		head->node[0] = '\0';
 | 
			
		||||
	else if (!strcmp(node, NODE_LOCAL)) {
 | 
			
		||||
		head->node[0] = '\0';
 | 
			
		||||
		head->flags = CLVMD_FLAG_LOCAL;
 | 
			
		||||
	if (node) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Allow a couple of special node names:
 | 
			
		||||
		 * "*" for all nodes,
 | 
			
		||||
		 * "." for the local node only
 | 
			
		||||
		 */
 | 
			
		||||
		if (strcmp(node, "*") == 0) {
 | 
			
		||||
			head->node[0] = '\0';
 | 
			
		||||
		} else if (strcmp(node, ".") == 0) {
 | 
			
		||||
			head->node[0] = '\0';
 | 
			
		||||
			head->flags = CLVMD_FLAG_LOCAL;
 | 
			
		||||
		} else
 | 
			
		||||
			strcpy(head->node, node);
 | 
			
		||||
	} else
 | 
			
		||||
		strcpy(head->node, node);
 | 
			
		||||
		head->node[0] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Send a message to a(or all) node(s) in the cluster and wait for replies
 | 
			
		||||
 */
 | 
			
		||||
static int _cluster_request(char cmd, const char *node, void *data, int len,
 | 
			
		||||
			    lvm_response_t ** response, int *num, int no_response)
 | 
			
		||||
			   lvm_response_t ** response, int *num)
 | 
			
		||||
{
 | 
			
		||||
	char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
 | 
			
		||||
	char *inptr;
 | 
			
		||||
@@ -202,12 +200,11 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	_build_header(head, cmd, node, len);
 | 
			
		||||
	if (len)
 | 
			
		||||
		memcpy(head->node + strlen(head->node) + 1, data, len);
 | 
			
		||||
	memcpy(head->node + strlen(head->node) + 1, data, len);
 | 
			
		||||
 | 
			
		||||
	status = _send_request(outbuf, sizeof(struct clvm_header) +
 | 
			
		||||
			       strlen(head->node) + len, &retbuf, no_response);
 | 
			
		||||
	if (!status || no_response)
 | 
			
		||||
			      strlen(head->node) + len, &retbuf);
 | 
			
		||||
	if (!status)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	/* Count the number of responses we got */
 | 
			
		||||
@@ -225,14 +222,16 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
 | 
			
		||||
	 * With an extra pair of INTs on the front to sanity
 | 
			
		||||
	 * check the pointer when we are given it back to free
 | 
			
		||||
	 */
 | 
			
		||||
	*response = NULL;
 | 
			
		||||
	if (!(rarray = dm_malloc(sizeof(lvm_response_t) * num_responses +
 | 
			
		||||
				 sizeof(int) * 2))) {
 | 
			
		||||
	*response = dm_malloc(sizeof(lvm_response_t) * num_responses +
 | 
			
		||||
			    sizeof(int) * 2);
 | 
			
		||||
	if (!*response) {
 | 
			
		||||
		errno = ENOMEM;
 | 
			
		||||
		status = 0;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rarray = *response;
 | 
			
		||||
 | 
			
		||||
	/* Unpack the response into an lvm_response_t array */
 | 
			
		||||
	inptr = head->args;
 | 
			
		||||
	i = 0;
 | 
			
		||||
@@ -249,9 +248,9 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
 | 
			
		||||
			int j;
 | 
			
		||||
			for (j = 0; j < i; j++)
 | 
			
		||||
				dm_free(rarray[i].response);
 | 
			
		||||
			dm_free(rarray);
 | 
			
		||||
			free(*response);
 | 
			
		||||
			errno = ENOMEM;
 | 
			
		||||
			status = 0;
 | 
			
		||||
			status = -1;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +263,8 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
 | 
			
		||||
	*response = rarray;
 | 
			
		||||
 | 
			
		||||
      out:
 | 
			
		||||
	dm_free(retbuf);
 | 
			
		||||
	if (retbuf)
 | 
			
		||||
		dm_free(retbuf);
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
@@ -283,16 +283,16 @@ static int _cluster_free_request(lvm_response_t * response, int num)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int refresh_clvmd(int all_nodes)
 | 
			
		||||
int refresh_clvmd()
 | 
			
		||||
{
 | 
			
		||||
	int num_responses;
 | 
			
		||||
	char args[1]; // No args really.
 | 
			
		||||
	lvm_response_t *response = NULL;
 | 
			
		||||
	lvm_response_t *response;
 | 
			
		||||
	int saved_errno;
 | 
			
		||||
	int status;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	status = _cluster_request(CLVMD_CMD_REFRESH, all_nodes ? NODE_ALL : NODE_LOCAL, args, 0, &response, &num_responses, 0);
 | 
			
		||||
	status = _cluster_request(CLVMD_CMD_REFRESH, "*", args, 0, &response, &num_responses);
 | 
			
		||||
 | 
			
		||||
	/* If any nodes were down then display them and return an error */
 | 
			
		||||
	for (i = 0; i < num_responses; i++) {
 | 
			
		||||
@@ -318,65 +318,3 @@ int refresh_clvmd(int all_nodes)
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int restart_clvmd(int all_nodes)
 | 
			
		||||
{
 | 
			
		||||
	int dummy, status;
 | 
			
		||||
 | 
			
		||||
	status = _cluster_request(CLVMD_CMD_RESTART, all_nodes ? NODE_ALL : NODE_LOCAL, NULL, 0, NULL, &dummy, 1);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * FIXME: we cannot receive response, clvmd re-exec before it.
 | 
			
		||||
	 *        but also should not close socket too early (the whole rq is dropped then).
 | 
			
		||||
	 * FIXME: This should be handled this way:
 | 
			
		||||
	 *  - client waits for RESTART ack (and socket close)
 | 
			
		||||
	 *  - server restarts
 | 
			
		||||
	 *  - client checks that server is ready again (VERSION command?)
 | 
			
		||||
	 */
 | 
			
		||||
	usleep(500000);
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int debug_clvmd(int level, int clusterwide)
 | 
			
		||||
{
 | 
			
		||||
	int num_responses;
 | 
			
		||||
	char args[1];
 | 
			
		||||
	const char *nodes;
 | 
			
		||||
	lvm_response_t *response = NULL;
 | 
			
		||||
	int saved_errno;
 | 
			
		||||
	int status;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	args[0] = level;
 | 
			
		||||
	if (clusterwide)
 | 
			
		||||
		nodes = NODE_ALL;
 | 
			
		||||
	else
 | 
			
		||||
		nodes = NODE_LOCAL;
 | 
			
		||||
 | 
			
		||||
	status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses, 0);
 | 
			
		||||
 | 
			
		||||
	/* If any nodes were down then display them and return an error */
 | 
			
		||||
	for (i = 0; i < num_responses; i++) {
 | 
			
		||||
		if (response[i].status == EHOSTDOWN) {
 | 
			
		||||
			fprintf(stderr, "clvmd not running on node %s",
 | 
			
		||||
				  response[i].node);
 | 
			
		||||
			status = 0;
 | 
			
		||||
			errno = response[i].status;
 | 
			
		||||
		} else if (response[i].status) {
 | 
			
		||||
			fprintf(stderr, "Error setting debug on node %s: %s",
 | 
			
		||||
				  response[i].node,
 | 
			
		||||
				  response[i].response[0] ?
 | 
			
		||||
				  	response[i].response :
 | 
			
		||||
				  	strerror(response[i].status));
 | 
			
		||||
			status = 0;
 | 
			
		||||
			errno = response[i].status;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	saved_errno = errno;
 | 
			
		||||
	_cluster_free_request(response, num_responses);
 | 
			
		||||
	errno = saved_errno;
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,2 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int refresh_clvmd(int all_nodes);
 | 
			
		||||
int restart_clvmd(int all_nodes);
 | 
			
		||||
int debug_clvmd(int level, int clusterwide);
 | 
			
		||||
int refresh_clvmd(void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										501
									
								
								daemons/clvmd/tcp-comms.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										501
									
								
								daemons/clvmd/tcp-comms.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,501 @@
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*******************************************************************************
 | 
			
		||||
**
 | 
			
		||||
**  Copyright (C) Sistina Software, Inc.  2002-2003  All rights reserved.
 | 
			
		||||
**  Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
**
 | 
			
		||||
*******************************************************************************
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* This provides the inter-clvmd communications for a system without CMAN.
 | 
			
		||||
   There is a listening TCP socket which accepts new connections in the
 | 
			
		||||
   normal way.
 | 
			
		||||
   It can also make outgoing connnections to the other clvmd nodes.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
 | 
			
		||||
#include "clvm.h"
 | 
			
		||||
#include "clvmd-comms.h"
 | 
			
		||||
#include "clvmd.h"
 | 
			
		||||
#include "clvmd-gulm.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_TCP_PORT 21064
 | 
			
		||||
 | 
			
		||||
static int listen_fd = -1;
 | 
			
		||||
static int tcp_port;
 | 
			
		||||
struct dm_hash_table *sock_hash;
 | 
			
		||||
 | 
			
		||||
static int get_our_ip_address(char *addr, int *family);
 | 
			
		||||
static int read_from_tcpsock(struct local_client *fd, char *buf, int len, char *csid,
 | 
			
		||||
			     struct local_client **new_client);
 | 
			
		||||
 | 
			
		||||
/* Called by init_cluster() to open up the listening socket */
 | 
			
		||||
int init_comms(unsigned short port)
 | 
			
		||||
{
 | 
			
		||||
    struct sockaddr_in6 addr;
 | 
			
		||||
 | 
			
		||||
    sock_hash = dm_hash_create(100);
 | 
			
		||||
    tcp_port = port ? : DEFAULT_TCP_PORT;
 | 
			
		||||
 | 
			
		||||
    listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
 | 
			
		||||
 | 
			
		||||
    if (listen_fd < 0)
 | 
			
		||||
    {
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
	int one = 1;
 | 
			
		||||
	setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
 | 
			
		||||
	setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(&addr, 0, sizeof(addr)); // Bind to INADDR_ANY
 | 
			
		||||
    addr.sin6_family = AF_INET6;
 | 
			
		||||
    addr.sin6_port = htons(tcp_port);
 | 
			
		||||
 | 
			
		||||
    if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
	DEBUGLOG("Can't bind to port: %s\n", strerror(errno));
 | 
			
		||||
	syslog(LOG_ERR, "Can't bind to port %d, is clvmd already running ?", tcp_port);
 | 
			
		||||
	close(listen_fd);
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    listen(listen_fd, 5);
 | 
			
		||||
 | 
			
		||||
    /* Set Close-on-exec */
 | 
			
		||||
    fcntl(listen_fd, F_SETFD, 1);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tcp_remove_client(const char *c_csid)
 | 
			
		||||
{
 | 
			
		||||
    struct local_client *client;
 | 
			
		||||
    char csid[GULM_MAX_CSID_LEN];
 | 
			
		||||
    unsigned int i;
 | 
			
		||||
    memcpy(csid, c_csid, sizeof csid);
 | 
			
		||||
    DEBUGLOG("tcp_remove_client\n");
 | 
			
		||||
 | 
			
		||||
    /* Don't actually close the socket here - that's the
 | 
			
		||||
       job of clvmd.c whch will do the job when it notices the
 | 
			
		||||
       other end has gone. We just need to remove the client(s) from
 | 
			
		||||
       the hash table so we don't try to use it for sending any more */
 | 
			
		||||
    for (i = 0; i < 2; i++)
 | 
			
		||||
    {
 | 
			
		||||
	client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 | 
			
		||||
	if (client)
 | 
			
		||||
	{
 | 
			
		||||
	    dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 | 
			
		||||
	    client->removeme = 1;
 | 
			
		||||
	    close(client->fd);
 | 
			
		||||
	}
 | 
			
		||||
	/* Look for a mangled one too, on the 2nd iteration. */
 | 
			
		||||
	csid[0] ^= 0x80;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int alloc_client(int fd, const char *c_csid, struct local_client **new_client)
 | 
			
		||||
{
 | 
			
		||||
    struct local_client *client;
 | 
			
		||||
    char csid[GULM_MAX_CSID_LEN];
 | 
			
		||||
    memcpy(csid, c_csid, sizeof csid);
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("alloc_client %d csid = %s\n", fd, print_csid(csid));
 | 
			
		||||
 | 
			
		||||
    /* Create a local_client and return it */
 | 
			
		||||
    client = malloc(sizeof(struct local_client));
 | 
			
		||||
    if (!client)
 | 
			
		||||
    {
 | 
			
		||||
	DEBUGLOG("malloc failed\n");
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(client, 0, sizeof(struct local_client));
 | 
			
		||||
    client->fd = fd;
 | 
			
		||||
    client->type = CLUSTER_DATA_SOCK;
 | 
			
		||||
    client->callback = read_from_tcpsock;
 | 
			
		||||
    if (new_client)
 | 
			
		||||
	*new_client = client;
 | 
			
		||||
 | 
			
		||||
    /* Add to our list of node sockets */
 | 
			
		||||
    if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
 | 
			
		||||
    {
 | 
			
		||||
	DEBUGLOG("alloc_client mangling CSID for second connection\n");
 | 
			
		||||
	/* This is a duplicate connection but we can't close it because
 | 
			
		||||
	   the other end may already have started sending.
 | 
			
		||||
	   So, we mangle the IP address and keep it, all sending will
 | 
			
		||||
	   go out of the main FD
 | 
			
		||||
	*/
 | 
			
		||||
	csid[0] ^= 0x80;
 | 
			
		||||
	client->bits.net.flags = 1; /* indicate mangled CSID */
 | 
			
		||||
 | 
			
		||||
        /* If it still exists then kill the connection as we should only
 | 
			
		||||
           ever have one incoming connection from each node */
 | 
			
		||||
        if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
 | 
			
		||||
        {
 | 
			
		||||
	    DEBUGLOG("Multiple incoming connections from node\n");
 | 
			
		||||
            syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
 | 
			
		||||
 | 
			
		||||
	    free(client);
 | 
			
		||||
            errno = ECONNREFUSED;
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int get_main_gulm_cluster_fd()
 | 
			
		||||
{
 | 
			
		||||
    return listen_fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Read on main comms (listen) socket, accept it */
 | 
			
		||||
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, const char *csid,
 | 
			
		||||
			struct local_client **new_client)
 | 
			
		||||
{
 | 
			
		||||
    int newfd;
 | 
			
		||||
    struct sockaddr_in6 addr;
 | 
			
		||||
    socklen_t addrlen = sizeof(addr);
 | 
			
		||||
    int status;
 | 
			
		||||
    char name[GULM_MAX_CLUSTER_MEMBER_NAME_LEN];
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("cluster_fd_callback\n");
 | 
			
		||||
    *new_client = NULL;
 | 
			
		||||
    newfd = accept(listen_fd, (struct sockaddr *)&addr, &addrlen);
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("cluster_fd_callback, newfd=%d (errno=%d)\n", newfd, errno);
 | 
			
		||||
    if (!newfd)
 | 
			
		||||
    {
 | 
			
		||||
	syslog(LOG_ERR, "error in accept: %m");
 | 
			
		||||
	errno = EAGAIN;
 | 
			
		||||
	return -1; /* Don't return an error or clvmd will close the listening FD */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Check that the client is a member of the cluster
 | 
			
		||||
       and reject if not.
 | 
			
		||||
    */
 | 
			
		||||
    if (gulm_name_from_csid((char *)&addr.sin6_addr, name) < 0)
 | 
			
		||||
    {
 | 
			
		||||
	syslog(LOG_ERR, "Got connect from non-cluster node %s\n",
 | 
			
		||||
	       print_csid((char *)&addr.sin6_addr));
 | 
			
		||||
	DEBUGLOG("Got connect from non-cluster node %s\n",
 | 
			
		||||
		 print_csid((char *)&addr.sin6_addr));
 | 
			
		||||
	close(newfd);
 | 
			
		||||
 | 
			
		||||
	errno = EAGAIN;
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    status = alloc_client(newfd, (char *)&addr.sin6_addr, new_client);
 | 
			
		||||
    if (status)
 | 
			
		||||
    {
 | 
			
		||||
	DEBUGLOG("cluster_fd_callback, alloc_client failed, status = %d\n", status);
 | 
			
		||||
	close(newfd);
 | 
			
		||||
	/* See above... */
 | 
			
		||||
	errno = EAGAIN;
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
    DEBUGLOG("cluster_fd_callback, returning %d, %p\n", newfd, *new_client);
 | 
			
		||||
    return newfd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Try to get at least 'len' bytes from the socket */
 | 
			
		||||
static int really_read(int fd, char *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
	int got, offset;
 | 
			
		||||
 | 
			
		||||
	got = offset = 0;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		got = read(fd, buf+offset, len-offset);
 | 
			
		||||
		DEBUGLOG("really_read. got %d bytes\n", got);
 | 
			
		||||
		offset += got;
 | 
			
		||||
	} while (got > 0 && offset < len);
 | 
			
		||||
 | 
			
		||||
	if (got < 0)
 | 
			
		||||
		return got;
 | 
			
		||||
	else
 | 
			
		||||
		return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int read_from_tcpsock(struct local_client *client, char *buf, int len, char *csid,
 | 
			
		||||
			     struct local_client **new_client)
 | 
			
		||||
{
 | 
			
		||||
    struct sockaddr_in6 addr;
 | 
			
		||||
    socklen_t slen = sizeof(addr);
 | 
			
		||||
    struct clvm_header *header = (struct clvm_header *)buf;
 | 
			
		||||
    int status;
 | 
			
		||||
    uint32_t arglen;
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("read_from_tcpsock fd %d\n", client->fd);
 | 
			
		||||
    *new_client = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Get "csid" */
 | 
			
		||||
    getpeername(client->fd, (struct sockaddr *)&addr, &slen);
 | 
			
		||||
    memcpy(csid, &addr.sin6_addr, GULM_MAX_CSID_LEN);
 | 
			
		||||
 | 
			
		||||
    /* Read just the header first, then get the rest if there is any.
 | 
			
		||||
     * Stream sockets, sigh.
 | 
			
		||||
     */
 | 
			
		||||
    status = really_read(client->fd, buf, sizeof(struct clvm_header));
 | 
			
		||||
    if (status > 0)
 | 
			
		||||
    {
 | 
			
		||||
	    int status2;
 | 
			
		||||
 | 
			
		||||
	    arglen = ntohl(header->arglen);
 | 
			
		||||
 | 
			
		||||
	    /* Get the rest */
 | 
			
		||||
	    if (arglen && arglen < GULM_MAX_CLUSTER_MESSAGE)
 | 
			
		||||
	    {
 | 
			
		||||
		    status2 = really_read(client->fd, buf+status, arglen);
 | 
			
		||||
		    if (status2 > 0)
 | 
			
		||||
			    status += status2;
 | 
			
		||||
		    else
 | 
			
		||||
			    status = status2;
 | 
			
		||||
	    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("read_from_tcpsock, status = %d(errno = %d)\n", status, errno);
 | 
			
		||||
 | 
			
		||||
    /* Remove it from the hash table if there's an error, clvmd will
 | 
			
		||||
       remove the socket from its lists and free the client struct */
 | 
			
		||||
    if (status == 0 ||
 | 
			
		||||
	(status < 0 && errno != EAGAIN && errno != EINTR))
 | 
			
		||||
    {
 | 
			
		||||
	char remcsid[GULM_MAX_CSID_LEN];
 | 
			
		||||
 | 
			
		||||
	memcpy(remcsid, csid, GULM_MAX_CSID_LEN);
 | 
			
		||||
	close(client->fd);
 | 
			
		||||
 | 
			
		||||
	/* If the csid was mangled, then make sure we remove the right entry */
 | 
			
		||||
	if (client->bits.net.flags)
 | 
			
		||||
	    remcsid[0] ^= 0x80;
 | 
			
		||||
	dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
 | 
			
		||||
 | 
			
		||||
	/* Tell cluster manager layer */
 | 
			
		||||
	add_down_node(remcsid);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	    gulm_add_up_node(csid);
 | 
			
		||||
	    /* Send it back to clvmd */
 | 
			
		||||
	    process_message(client, buf, status, csid);
 | 
			
		||||
    }
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int gulm_connect_csid(const char *csid, struct local_client **newclient)
 | 
			
		||||
{
 | 
			
		||||
    int fd;
 | 
			
		||||
    struct sockaddr_in6 addr;
 | 
			
		||||
    int status;
 | 
			
		||||
    int one = 1;
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("Connecting socket\n");
 | 
			
		||||
    fd = socket(PF_INET6, SOCK_STREAM, 0);
 | 
			
		||||
 | 
			
		||||
    if (fd < 0)
 | 
			
		||||
    {
 | 
			
		||||
	syslog(LOG_ERR, "Unable to create new socket: %m");
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addr.sin6_family = AF_INET6;
 | 
			
		||||
    memcpy(&addr.sin6_addr, csid, GULM_MAX_CSID_LEN);
 | 
			
		||||
    addr.sin6_port = htons(tcp_port);
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("Connecting socket %d\n", fd);
 | 
			
		||||
    if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) < 0)
 | 
			
		||||
    {
 | 
			
		||||
	/* "Connection refused" is "normal" because clvmd may not yet be running
 | 
			
		||||
	 * on that node.
 | 
			
		||||
	 */
 | 
			
		||||
	if (errno != ECONNREFUSED)
 | 
			
		||||
	{
 | 
			
		||||
	    syslog(LOG_ERR, "Unable to connect to remote node: %m");
 | 
			
		||||
	}
 | 
			
		||||
	DEBUGLOG("Unable to connect to remote node: %s\n", strerror(errno));
 | 
			
		||||
	close(fd);
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Set Close-on-exec */
 | 
			
		||||
    fcntl(fd, F_SETFD, 1);
 | 
			
		||||
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
 | 
			
		||||
 | 
			
		||||
    status = alloc_client(fd, csid, newclient);
 | 
			
		||||
    if (status)
 | 
			
		||||
	close(fd);
 | 
			
		||||
    else
 | 
			
		||||
	add_client(*newclient);
 | 
			
		||||
 | 
			
		||||
    /* If we can connect to it, it must be running a clvmd */
 | 
			
		||||
    gulm_add_up_node(csid);
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Send a message to a known CSID */
 | 
			
		||||
static int tcp_send_message(void *buf, int msglen, const char *csid, const char *errtext)
 | 
			
		||||
{
 | 
			
		||||
    int status;
 | 
			
		||||
    struct local_client *client;
 | 
			
		||||
    char ourcsid[GULM_MAX_CSID_LEN];
 | 
			
		||||
 | 
			
		||||
    assert(csid);
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("tcp_send_message, csid = %s, msglen = %d\n", print_csid(csid), msglen);
 | 
			
		||||
 | 
			
		||||
    /* Don't connect to ourself */
 | 
			
		||||
    get_our_gulm_csid(ourcsid);
 | 
			
		||||
    if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
 | 
			
		||||
	return msglen;
 | 
			
		||||
 | 
			
		||||
    client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 | 
			
		||||
    if (!client)
 | 
			
		||||
    {
 | 
			
		||||
	status = gulm_connect_csid(csid, &client);
 | 
			
		||||
	if (status)
 | 
			
		||||
	    return -1;
 | 
			
		||||
    }
 | 
			
		||||
    DEBUGLOG("tcp_send_message, fd = %d\n", client->fd);
 | 
			
		||||
 | 
			
		||||
    return write(client->fd, buf, msglen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int gulm_cluster_send_message(void *buf, int msglen, const char *csid, const char *errtext)
 | 
			
		||||
{
 | 
			
		||||
    int status=0;
 | 
			
		||||
 | 
			
		||||
    DEBUGLOG("cluster send message, csid = %p, msglen = %d\n", csid, msglen);
 | 
			
		||||
 | 
			
		||||
    /* If csid is NULL then send to all known (not just connected) nodes */
 | 
			
		||||
    if (!csid)
 | 
			
		||||
    {
 | 
			
		||||
	void *context = NULL;
 | 
			
		||||
	char loop_csid[GULM_MAX_CSID_LEN];
 | 
			
		||||
 | 
			
		||||
	/* Loop round all gulm-known nodes */
 | 
			
		||||
	while (get_next_node_csid(&context, loop_csid))
 | 
			
		||||
	{
 | 
			
		||||
	    status = tcp_send_message(buf, msglen, loop_csid, errtext);
 | 
			
		||||
	    if (status == 0 ||
 | 
			
		||||
		(status < 0 && (errno == EAGAIN || errno == EINTR)))
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
	status = tcp_send_message(buf, msglen, csid, errtext);
 | 
			
		||||
    }
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* To get our own IP address we get the locally bound address of the
 | 
			
		||||
   socket that's talking to GULM in the assumption(eek) that it will
 | 
			
		||||
   be on the "right" network in a multi-homed system */
 | 
			
		||||
static int get_our_ip_address(char *addr, int *family)
 | 
			
		||||
{
 | 
			
		||||
	struct utsname info;
 | 
			
		||||
 | 
			
		||||
	uname(&info);
 | 
			
		||||
	get_ip_address(info.nodename, addr);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Public version of above for those that don't care what protocol
 | 
			
		||||
   we're using */
 | 
			
		||||
void get_our_gulm_csid(char *csid)
 | 
			
		||||
{
 | 
			
		||||
    static char our_csid[GULM_MAX_CSID_LEN];
 | 
			
		||||
    static int got_csid = 0;
 | 
			
		||||
 | 
			
		||||
    if (!got_csid)
 | 
			
		||||
    {
 | 
			
		||||
	int family;
 | 
			
		||||
 | 
			
		||||
	memset(our_csid, 0, sizeof(our_csid));
 | 
			
		||||
	if (get_our_ip_address(our_csid, &family))
 | 
			
		||||
	{
 | 
			
		||||
	    got_csid = 1;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(csid, our_csid, GULM_MAX_CSID_LEN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void map_v4_to_v6(struct in_addr *ip4, struct in6_addr *ip6)
 | 
			
		||||
{
 | 
			
		||||
   ip6->s6_addr32[0] = 0;
 | 
			
		||||
   ip6->s6_addr32[1] = 0;
 | 
			
		||||
   ip6->s6_addr32[2] = htonl(0xffff);
 | 
			
		||||
   ip6->s6_addr32[3] = ip4->s_addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get someone else's IP address from DNS */
 | 
			
		||||
int get_ip_address(const char *node, char *addr)
 | 
			
		||||
{
 | 
			
		||||
    struct hostent *he;
 | 
			
		||||
 | 
			
		||||
    memset(addr, 0, GULM_MAX_CSID_LEN);
 | 
			
		||||
 | 
			
		||||
    // TODO: what do we do about multi-homed hosts ???
 | 
			
		||||
    // CCSs ip_interfaces solved this but some bugger removed it.
 | 
			
		||||
 | 
			
		||||
    /* Try IPv6 first. The man page for gethostbyname implies that
 | 
			
		||||
       it will lookup ip6 & ip4 names, but it seems not to */
 | 
			
		||||
    he = gethostbyname2(node, AF_INET6);
 | 
			
		||||
    if (he)
 | 
			
		||||
    {
 | 
			
		||||
	memcpy(addr, he->h_addr_list[0],
 | 
			
		||||
	       he->h_length);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
	he = gethostbyname2(node, AF_INET);
 | 
			
		||||
	if (!he)
 | 
			
		||||
	    return -1;
 | 
			
		||||
	map_v4_to_v6((struct in_addr *)he->h_addr_list[0], (struct in6_addr *)addr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *print_csid(const char *csid)
 | 
			
		||||
{
 | 
			
		||||
    static char buf[128];
 | 
			
		||||
    int *icsid = (int *)csid;
 | 
			
		||||
 | 
			
		||||
    sprintf(buf, "[%x.%x.%x.%x]",
 | 
			
		||||
	    icsid[0],icsid[1],icsid[2],icsid[3]);
 | 
			
		||||
 | 
			
		||||
    return buf;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								daemons/clvmd/tcp-comms.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								daemons/clvmd/tcp-comms.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
#define GULM_MAX_CLUSTER_MESSAGE 1600
 | 
			
		||||
#define GULM_MAX_CSID_LEN sizeof(struct in6_addr)
 | 
			
		||||
#define GULM_MAX_CLUSTER_MEMBER_NAME_LEN 128
 | 
			
		||||
 | 
			
		||||
extern int init_comms(unsigned short);
 | 
			
		||||
extern char *print_csid(const char *);
 | 
			
		||||
int get_main_gulm_cluster_fd(void);
 | 
			
		||||
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, const char *csid, struct local_client **new_client);
 | 
			
		||||
int gulm_cluster_send_message(void *buf, int msglen, const char *csid, const char *errtext);
 | 
			
		||||
void get_our_gulm_csid(char *csid);
 | 
			
		||||
int gulm_connect_csid(const char *csid, struct local_client **newclient);
 | 
			
		||||
@@ -1,39 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2009-2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU General Public License v.2.
 | 
			
		||||
#
 | 
			
		||||
# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
CPG_LIBS = @CPG_LIBS@
 | 
			
		||||
CPG_CFLAGS = @CPG_CFLAGS@
 | 
			
		||||
SACKPT_LIBS = @SACKPT_LIBS@
 | 
			
		||||
SACKPT_CFLAGS = @SACKPT_CFLAGS@
 | 
			
		||||
 | 
			
		||||
SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
 | 
			
		||||
 | 
			
		||||
TARGETS = cmirrord
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
LIBS += -ldevmapper
 | 
			
		||||
LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
 | 
			
		||||
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) $(EXTRA_EXEC_CFLAGS)
 | 
			
		||||
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
 | 
			
		||||
 | 
			
		||||
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
 | 
			
		||||
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
 | 
			
		||||
		$(LVMLIBS) $(LMLIBS) $(LIBS)
 | 
			
		||||
 | 
			
		||||
install: $(TARGETS)
 | 
			
		||||
	$(INSTALL_PROGRAM) -D cmirrord $(usrsbindir)/cmirrord
 | 
			
		||||
@@ -1,256 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU General Public License v.2.
 | 
			
		||||
 *
 | 
			
		||||
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#include "logging.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "functions.h"
 | 
			
		||||
#include "link_mon.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
static volatile sig_atomic_t exit_now = 0;
 | 
			
		||||
/* FIXME Review signal handling.  Should be volatile sig_atomic_t */
 | 
			
		||||
static sigset_t signal_mask;
 | 
			
		||||
static volatile sig_atomic_t signal_received;
 | 
			
		||||
 | 
			
		||||
static void process_signals(void);
 | 
			
		||||
static void daemonize(void);
 | 
			
		||||
static void init_all(void);
 | 
			
		||||
static void cleanup_all(void);
 | 
			
		||||
 | 
			
		||||
int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	daemonize();
 | 
			
		||||
 | 
			
		||||
	init_all();
 | 
			
		||||
 | 
			
		||||
	/* Parent can now exit, we're ready to handle requests */
 | 
			
		||||
	kill(getppid(), SIGTERM);
 | 
			
		||||
 | 
			
		||||
	LOG_PRINT("Starting cmirrord:");
 | 
			
		||||
	LOG_PRINT(" Built: "__DATE__" "__TIME__"\n");
 | 
			
		||||
	LOG_DBG(" Compiled with debugging.");
 | 
			
		||||
 | 
			
		||||
	while (!exit_now) {
 | 
			
		||||
		links_monitor();
 | 
			
		||||
 | 
			
		||||
		links_issue_callbacks();
 | 
			
		||||
 | 
			
		||||
		process_signals();
 | 
			
		||||
	}
 | 
			
		||||
	exit(EXIT_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * parent_exit_handler: exit the parent
 | 
			
		||||
 * @sig: the signal
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static void parent_exit_handler(int sig __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	exit_now = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sig_handler(int sig)
 | 
			
		||||
{
 | 
			
		||||
	/* FIXME Races - don't touch signal_mask here. */
 | 
			
		||||
	sigaddset(&signal_mask, sig);
 | 
			
		||||
	signal_received = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void process_signal(int sig){
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	switch(sig) {
 | 
			
		||||
	case SIGINT:
 | 
			
		||||
	case SIGQUIT:
 | 
			
		||||
	case SIGTERM:
 | 
			
		||||
	case SIGHUP:
 | 
			
		||||
		r += log_status();
 | 
			
		||||
		break;
 | 
			
		||||
	case SIGUSR1:
 | 
			
		||||
	case SIGUSR2:
 | 
			
		||||
		log_debug();
 | 
			
		||||
		/*local_debug();*/
 | 
			
		||||
		cluster_debug();
 | 
			
		||||
		return;
 | 
			
		||||
	default:
 | 
			
		||||
		LOG_PRINT("Unknown signal received... ignoring");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!r) {
 | 
			
		||||
		LOG_DBG("No current cluster logs... safe to exit.");
 | 
			
		||||
		cleanup_all();
 | 
			
		||||
		exit(EXIT_SUCCESS);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOG_ERROR("Cluster logs exist.  Refusing to exit.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void process_signals(void)
 | 
			
		||||
{
 | 
			
		||||
	int x;
 | 
			
		||||
 | 
			
		||||
	if (!signal_received)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	signal_received = 0;
 | 
			
		||||
 | 
			
		||||
	for (x = 1; x < _NSIG; x++) {
 | 
			
		||||
		if (sigismember(&signal_mask, x)) {
 | 
			
		||||
			sigdelset(&signal_mask, x);
 | 
			
		||||
			process_signal(x);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void remove_lockfile(void)
 | 
			
		||||
{
 | 
			
		||||
	if (unlink(CMIRRORD_PIDFILE))
 | 
			
		||||
		LOG_ERROR("Unable to remove \"" CMIRRORD_PIDFILE "\" %s", strerror(errno));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * daemonize
 | 
			
		||||
 *
 | 
			
		||||
 * Performs the steps necessary to become a daemon.
 | 
			
		||||
 */
 | 
			
		||||
static void daemonize(void)
 | 
			
		||||
{
 | 
			
		||||
	int pid;
 | 
			
		||||
	int status;
 | 
			
		||||
	int devnull;
 | 
			
		||||
 | 
			
		||||
	if ((devnull = open("/dev/null", O_RDWR)) == -1) {
 | 
			
		||||
		LOG_ERROR("Can't open /dev/null: %s", strerror(errno));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	signal(SIGTERM, &parent_exit_handler);
 | 
			
		||||
 | 
			
		||||
	pid = fork();
 | 
			
		||||
 | 
			
		||||
	if (pid < 0) {
 | 
			
		||||
		LOG_ERROR("Unable to fork()");
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pid) {
 | 
			
		||||
		/* Parent waits here for child to get going */
 | 
			
		||||
		while (!waitpid(pid, &status, WNOHANG) && !exit_now);
 | 
			
		||||
		if (exit_now)
 | 
			
		||||
			exit(EXIT_SUCCESS);
 | 
			
		||||
 | 
			
		||||
		switch (WEXITSTATUS(status)) {
 | 
			
		||||
		case EXIT_LOCKFILE:
 | 
			
		||||
			LOG_ERROR("Failed to create lockfile");
 | 
			
		||||
			LOG_ERROR("Process already running?");
 | 
			
		||||
			break;
 | 
			
		||||
		case EXIT_KERNEL_SOCKET:
 | 
			
		||||
			LOG_ERROR("Unable to create netlink socket");
 | 
			
		||||
			break;
 | 
			
		||||
		case EXIT_KERNEL_BIND:
 | 
			
		||||
			LOG_ERROR("Unable to bind to netlink socket");
 | 
			
		||||
			break;
 | 
			
		||||
		case EXIT_KERNEL_SETSOCKOPT:
 | 
			
		||||
			LOG_ERROR("Unable to setsockopt on netlink socket");
 | 
			
		||||
			break;
 | 
			
		||||
		case EXIT_CLUSTER_CKPT_INIT:
 | 
			
		||||
			LOG_ERROR("Unable to initialize checkpoint service");
 | 
			
		||||
			LOG_ERROR("Has the cluster infrastructure been started?");
 | 
			
		||||
			break;
 | 
			
		||||
		case EXIT_FAILURE:
 | 
			
		||||
			LOG_ERROR("Failed to start: Generic error");
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_ERROR("Failed to start: Unknown error");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setsid();
 | 
			
		||||
	if (chdir("/")) {
 | 
			
		||||
		LOG_ERROR("Failed to chdir /: %s", strerror(errno));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	umask(0);
 | 
			
		||||
 | 
			
		||||
	if (close(0) || close(1) || close(2)) {
 | 
			
		||||
		LOG_ERROR("Failed to close terminal FDs");
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((dup2(devnull, 0) < 0) || /* reopen stdin */
 | 
			
		||||
	    (dup2(devnull, 1) < 0) || /* reopen stdout */
 | 
			
		||||
	    (dup2(devnull, 2) < 0))   /* reopen stderr */
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
 | 
			
		||||
	if ((devnull > STDERR_FILENO) && close(devnull)) {
 | 
			
		||||
		LOG_ERROR("Failed to close descriptor %d: %s",
 | 
			
		||||
			  devnull, strerror(errno));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
 | 
			
		||||
 | 
			
		||||
	(void) dm_prepare_selinux_context(CMIRRORD_PIDFILE, S_IFREG);
 | 
			
		||||
	if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
 | 
			
		||||
		exit(EXIT_LOCKFILE);
 | 
			
		||||
	(void) dm_prepare_selinux_context(NULL, 0);
 | 
			
		||||
 | 
			
		||||
	atexit(remove_lockfile);
 | 
			
		||||
 | 
			
		||||
	/* FIXME Replace with sigaction. (deprecated) */
 | 
			
		||||
	signal(SIGINT, &sig_handler);
 | 
			
		||||
	signal(SIGQUIT, &sig_handler);
 | 
			
		||||
	signal(SIGTERM, &sig_handler);
 | 
			
		||||
	signal(SIGHUP, &sig_handler);
 | 
			
		||||
	signal(SIGPIPE, SIG_IGN);
 | 
			
		||||
	signal(SIGUSR1, &sig_handler);
 | 
			
		||||
	signal(SIGUSR2, &sig_handler);
 | 
			
		||||
	sigemptyset(&signal_mask);
 | 
			
		||||
	signal_received = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * init_all
 | 
			
		||||
 *
 | 
			
		||||
 * Initialize modules.  Exit on failure.
 | 
			
		||||
 */
 | 
			
		||||
static void init_all(void)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if ((r = init_local()) ||
 | 
			
		||||
	    (r = init_cluster())) {
 | 
			
		||||
		exit(r);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * cleanup_all
 | 
			
		||||
 *
 | 
			
		||||
 * Clean up before exiting
 | 
			
		||||
 */
 | 
			
		||||
static void cleanup_all(void)
 | 
			
		||||
{
 | 
			
		||||
	cleanup_local();
 | 
			
		||||
	cleanup_cluster();
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,76 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLOG_CLUSTER_H
 | 
			
		||||
#define _LVM_CLOG_CLUSTER_H
 | 
			
		||||
 | 
			
		||||
#include "dm-log-userspace.h"
 | 
			
		||||
#include "libdevmapper.h"
 | 
			
		||||
 | 
			
		||||
#define DM_ULOG_RESPONSE 0x1000U /* in last byte of 32-bit value */
 | 
			
		||||
#define DM_ULOG_CHECKPOINT_READY 21
 | 
			
		||||
#define DM_ULOG_MEMBER_JOIN      22
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * There is other information in addition to what can
 | 
			
		||||
 * be found in the dm_ulog_request structure that we
 | 
			
		||||
 * need for processing.  'clog_request' is the wrapping
 | 
			
		||||
 * structure we use to make the additional fields
 | 
			
		||||
 * available.
 | 
			
		||||
 */
 | 
			
		||||
struct clog_request {
 | 
			
		||||
	/*
 | 
			
		||||
	 * If we don't use a union, the structure size will
 | 
			
		||||
	 * vary between 32-bit and 64-bit machines.  So, we
 | 
			
		||||
	 * pack two 64-bit version numbers in there to force
 | 
			
		||||
	 * the size of the structure to be the same.
 | 
			
		||||
	 *
 | 
			
		||||
	 * The two version numbers also help us with endian
 | 
			
		||||
	 * issues.  The first is always little endian, while
 | 
			
		||||
	 * the second is in native format of the sending
 | 
			
		||||
	 * machine.  If the two are equal, there is no need
 | 
			
		||||
	 * to do endian conversions.
 | 
			
		||||
	 */
 | 
			
		||||
	union {
 | 
			
		||||
		uint64_t version[2]; /* LE version and native version */
 | 
			
		||||
		struct dm_list list;
 | 
			
		||||
	} u;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 'originator' is the machine from which the requests
 | 
			
		||||
	 * was made.
 | 
			
		||||
	 */
 | 
			
		||||
	uint32_t originator;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 'pit_server' is the "point-in-time" server for the
 | 
			
		||||
	 * request.  (I.e.  The machine that was the server at
 | 
			
		||||
	 * the time the request was issued - only important during
 | 
			
		||||
	 * startup.
 | 
			
		||||
	 */
 | 
			
		||||
	uint32_t pit_server;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The request from the kernel that is being processed
 | 
			
		||||
	 */
 | 
			
		||||
	struct dm_ulog_request u_rq;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int init_cluster(void);
 | 
			
		||||
void cleanup_cluster(void);
 | 
			
		||||
void cluster_debug(void);
 | 
			
		||||
 | 
			
		||||
int create_cluster_cpg(char *uuid, uint64_t luid);
 | 
			
		||||
int destroy_cluster_cpg(char *uuid);
 | 
			
		||||
 | 
			
		||||
int cluster_send(struct clog_request *rq);
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_CLUSTER_H */
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLOG_COMMON_H
 | 
			
		||||
#define _LVM_CLOG_COMMON_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * If there are problems when forking off to become a daemon,
 | 
			
		||||
 * the child will exist with one of these codes.  This allows
 | 
			
		||||
 * the parent to know the reason for the failure and print it
 | 
			
		||||
 * to the launching terminal.
 | 
			
		||||
 *
 | 
			
		||||
 * #define EXIT_SUCCESS 0 (from stdlib.h)
 | 
			
		||||
 * #define EXIT_FAILURE 1 (from stdlib.h)
 | 
			
		||||
 */
 | 
			
		||||
#define EXIT_LOCKFILE              2
 | 
			
		||||
#define EXIT_KERNEL_SOCKET         3 /* Failed netlink socket create */
 | 
			
		||||
#define EXIT_KERNEL_BIND           4
 | 
			
		||||
#define EXIT_KERNEL_SETSOCKOPT     5
 | 
			
		||||
#define EXIT_CLUSTER_CKPT_INIT     6 /* Failed to init checkpoint */
 | 
			
		||||
#define EXIT_QUEUE_NOMEM           7
 | 
			
		||||
 | 
			
		||||
#define DM_ULOG_REQUEST_SIZE 1024
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_COMMON_H */
 | 
			
		||||
@@ -1,210 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 */
 | 
			
		||||
#include "logging.h"
 | 
			
		||||
#include "cluster.h"
 | 
			
		||||
#include "compat.h"
 | 
			
		||||
#include "xlate.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Older versions of the log daemon communicate with different
 | 
			
		||||
 * versions of the inter-machine communication structure, which
 | 
			
		||||
 * varies in size and fields.  The older versions append the
 | 
			
		||||
 * standard upstream version of the structure to every request.
 | 
			
		||||
 * COMPAT_OFFSET is where the upstream structure starts.
 | 
			
		||||
 */
 | 
			
		||||
#define COMPAT_OFFSET 256
 | 
			
		||||
 | 
			
		||||
static void v5_data_endian_switch(struct clog_request *rq, int to_network __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	int i, end;
 | 
			
		||||
	int64_t *pi64;
 | 
			
		||||
	uint64_t *pu64;
 | 
			
		||||
	uint32_t rq_type = rq->u_rq.request_type & ~DM_ULOG_RESPONSE;
 | 
			
		||||
 | 
			
		||||
	if (rq->u_rq.request_type & DM_ULOG_RESPONSE) {
 | 
			
		||||
		switch (rq_type) {
 | 
			
		||||
		case DM_ULOG_CTR:
 | 
			
		||||
		case DM_ULOG_DTR:
 | 
			
		||||
			LOG_ERROR("Invalid response type in endian switch");
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
 | 
			
		||||
		case DM_ULOG_PRESUSPEND:
 | 
			
		||||
		case DM_ULOG_POSTSUSPEND:
 | 
			
		||||
		case DM_ULOG_RESUME:
 | 
			
		||||
		case DM_ULOG_FLUSH:
 | 
			
		||||
		case DM_ULOG_MARK_REGION:
 | 
			
		||||
		case DM_ULOG_CLEAR_REGION:
 | 
			
		||||
		case DM_ULOG_SET_REGION_SYNC:
 | 
			
		||||
		case DM_ULOG_CHECKPOINT_READY:
 | 
			
		||||
		case DM_ULOG_MEMBER_JOIN:
 | 
			
		||||
		case DM_ULOG_STATUS_INFO:
 | 
			
		||||
		case DM_ULOG_STATUS_TABLE:
 | 
			
		||||
			/* No outbound data */
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case DM_ULOG_GET_REGION_SIZE:
 | 
			
		||||
		case DM_ULOG_GET_SYNC_COUNT:
 | 
			
		||||
			pu64 = (uint64_t *)rq->u_rq.data;
 | 
			
		||||
			*pu64 = xlate64(*pu64);
 | 
			
		||||
			break;
 | 
			
		||||
		case DM_ULOG_IS_CLEAN:
 | 
			
		||||
		case DM_ULOG_IN_SYNC:
 | 
			
		||||
			pi64 = (int64_t *)rq->u_rq.data;
 | 
			
		||||
			*pi64 = xlate64(*pi64);
 | 
			
		||||
			break;
 | 
			
		||||
		case DM_ULOG_GET_RESYNC_WORK:
 | 
			
		||||
		case DM_ULOG_IS_REMOTE_RECOVERING:
 | 
			
		||||
			pi64 = (int64_t *)rq->u_rq.data;
 | 
			
		||||
			pu64 = ((uint64_t *)rq->u_rq.data) + 1;
 | 
			
		||||
			*pi64 = xlate64(*pi64);
 | 
			
		||||
			*pu64 = xlate64(*pu64);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_ERROR("Unknown request type, %u", rq_type);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		switch (rq_type) {
 | 
			
		||||
		case DM_ULOG_CTR:
 | 
			
		||||
		case DM_ULOG_DTR:
 | 
			
		||||
			LOG_ERROR("Invalid request type in endian switch");
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
 | 
			
		||||
		case DM_ULOG_PRESUSPEND:
 | 
			
		||||
		case DM_ULOG_POSTSUSPEND:
 | 
			
		||||
		case DM_ULOG_RESUME:
 | 
			
		||||
		case DM_ULOG_GET_REGION_SIZE:
 | 
			
		||||
		case DM_ULOG_FLUSH:
 | 
			
		||||
		case DM_ULOG_GET_RESYNC_WORK:
 | 
			
		||||
		case DM_ULOG_GET_SYNC_COUNT:
 | 
			
		||||
		case DM_ULOG_STATUS_INFO:
 | 
			
		||||
		case DM_ULOG_STATUS_TABLE:
 | 
			
		||||
		case DM_ULOG_CHECKPOINT_READY:
 | 
			
		||||
		case DM_ULOG_MEMBER_JOIN:
 | 
			
		||||
			/* No incoming data */
 | 
			
		||||
			break;
 | 
			
		||||
		case DM_ULOG_IS_CLEAN:
 | 
			
		||||
		case DM_ULOG_IN_SYNC:
 | 
			
		||||
		case DM_ULOG_IS_REMOTE_RECOVERING:
 | 
			
		||||
			pu64 = (uint64_t *)rq->u_rq.data;
 | 
			
		||||
			*pu64 = xlate64(*pu64);
 | 
			
		||||
			break;
 | 
			
		||||
		case DM_ULOG_MARK_REGION:
 | 
			
		||||
		case DM_ULOG_CLEAR_REGION:
 | 
			
		||||
			end = rq->u_rq.data_size/sizeof(uint64_t);
 | 
			
		||||
 | 
			
		||||
			pu64 = (uint64_t *)rq->u_rq.data;
 | 
			
		||||
			for (i = 0; i < end; i++)
 | 
			
		||||
				pu64[i] = xlate64(pu64[i]);
 | 
			
		||||
			break;
 | 
			
		||||
		case DM_ULOG_SET_REGION_SYNC:
 | 
			
		||||
			pu64 = (uint64_t *)rq->u_rq.data;
 | 
			
		||||
			pi64 = ((int64_t *)rq->u_rq.data) + 1;
 | 
			
		||||
			*pu64 = xlate64(*pu64);
 | 
			
		||||
			*pi64 = xlate64(*pi64);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG_ERROR("Unknown request type, %u", rq_type);
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int v5_endian_to_network(struct clog_request *rq)
 | 
			
		||||
{
 | 
			
		||||
	int size;
 | 
			
		||||
	struct dm_ulog_request *u_rq = &rq->u_rq;
 | 
			
		||||
 | 
			
		||||
	size = sizeof(*rq) + u_rq->data_size;
 | 
			
		||||
 | 
			
		||||
	u_rq->error = xlate32(u_rq->error);
 | 
			
		||||
	u_rq->seq = xlate32(u_rq->seq);
 | 
			
		||||
 | 
			
		||||
	rq->originator = xlate32(rq->originator);
 | 
			
		||||
 | 
			
		||||
	v5_data_endian_switch(rq, 1);
 | 
			
		||||
 | 
			
		||||
	u_rq->request_type = xlate32(u_rq->request_type);
 | 
			
		||||
	u_rq->data_size = xlate32(u_rq->data_size);
 | 
			
		||||
 | 
			
		||||
	return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int clog_request_to_network(struct clog_request *rq)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	/* FIXME: Remove this safety check */
 | 
			
		||||
	if (rq->u.version[0] != xlate64(rq->u.version[1])) {
 | 
			
		||||
		LOG_ERROR("Programmer error:  version[0] must be LE");
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Are we already running in the endian mode we send
 | 
			
		||||
	 * over the wire?
 | 
			
		||||
	 */
 | 
			
		||||
	if (rq->u.version[0] == rq->u.version[1])
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	r = v5_endian_to_network(rq);
 | 
			
		||||
	if (r < 0)
 | 
			
		||||
		return r;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int v5_endian_from_network(struct clog_request *rq)
 | 
			
		||||
{
 | 
			
		||||
	int size;
 | 
			
		||||
	struct dm_ulog_request *u_rq = &rq->u_rq;
 | 
			
		||||
 | 
			
		||||
	u_rq->error = xlate32(u_rq->error);
 | 
			
		||||
	u_rq->seq = xlate32(u_rq->seq);
 | 
			
		||||
	u_rq->request_type = xlate32(u_rq->request_type);
 | 
			
		||||
	u_rq->data_size = xlate32(u_rq->data_size);
 | 
			
		||||
 | 
			
		||||
	rq->originator = xlate32(rq->originator);
 | 
			
		||||
 | 
			
		||||
	size = sizeof(*rq) + u_rq->data_size;
 | 
			
		||||
 | 
			
		||||
	v5_data_endian_switch(rq, 0);
 | 
			
		||||
 | 
			
		||||
	return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int clog_request_from_network(void *data, size_t data_len)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t *vp = data;
 | 
			
		||||
	uint64_t version = xlate64(vp[0]);
 | 
			
		||||
	struct clog_request *rq = data;
 | 
			
		||||
 | 
			
		||||
	switch (version) {
 | 
			
		||||
	case 5: /* Upstream */
 | 
			
		||||
		if (version == vp[0])
 | 
			
		||||
			return 0;
 | 
			
		||||
		break;
 | 
			
		||||
	case 4: /* RHEL 5.[45] */
 | 
			
		||||
	case 3: /* RHEL 5.3 */
 | 
			
		||||
	case 2: /* RHEL 5.2 */
 | 
			
		||||
		/* FIXME: still need to account for payload */
 | 
			
		||||
		if (data_len < (COMPAT_OFFSET + sizeof(*rq)))
 | 
			
		||||
			return -ENOSPC;
 | 
			
		||||
 | 
			
		||||
		rq = (struct clog_request *)((char *)data + COMPAT_OFFSET);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		LOG_ERROR("Unable to process cluster message: "
 | 
			
		||||
			  "Incompatible version");
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v5_endian_from_network(rq);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLOG_COMPAT_H
 | 
			
		||||
#define _LVM_CLOG_COMPAT_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The intermachine communication structure version are:
 | 
			
		||||
 *	0: Unused
 | 
			
		||||
 *	1: Never in the wild
 | 
			
		||||
 *	2: RHEL 5.2
 | 
			
		||||
 *	3: RHEL 5.3
 | 
			
		||||
 *	4: RHEL 5.4, RHEL 5.5
 | 
			
		||||
 *	5: RHEL 6, Current Upstream Format
 | 
			
		||||
 */
 | 
			
		||||
#define CLOG_TFR_VERSION 5
 | 
			
		||||
 | 
			
		||||
int clog_request_to_network(struct clog_request *rq);
 | 
			
		||||
int clog_request_from_network(void *data, size_t data_len);
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_COMPAT_H */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,34 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLOG_FUNCTIONS_H
 | 
			
		||||
#define _LVM_CLOG_FUNCTIONS_H
 | 
			
		||||
 | 
			
		||||
#include "dm-log-userspace.h"
 | 
			
		||||
#include "cluster.h"
 | 
			
		||||
 | 
			
		||||
#define LOG_RESUMED   1
 | 
			
		||||
#define LOG_SUSPENDED 2
 | 
			
		||||
 | 
			
		||||
int local_resume(struct dm_ulog_request *rq);
 | 
			
		||||
int cluster_postsuspend(char *, uint64_t);
 | 
			
		||||
 | 
			
		||||
int do_request(struct clog_request *rq, int server);
 | 
			
		||||
int push_state(const char *uuid, uint64_t luid,
 | 
			
		||||
	       const char *which, char **buf, uint32_t debug_who);
 | 
			
		||||
int pull_state(const char *uuid, uint64_t luid,
 | 
			
		||||
	       const char *which, char *buf, int size);
 | 
			
		||||
 | 
			
		||||
int log_get_state(struct dm_ulog_request *rq);
 | 
			
		||||
int log_status(void);
 | 
			
		||||
void log_debug(void);
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_FUNCTIONS_H */
 | 
			
		||||
@@ -1,151 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#include "logging.h"
 | 
			
		||||
#include "link_mon.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
struct link_callback {
 | 
			
		||||
	int fd;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	void *data;
 | 
			
		||||
	int (*callback)(void *data);
 | 
			
		||||
 | 
			
		||||
	struct link_callback *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static unsigned used_pfds = 0;
 | 
			
		||||
static unsigned free_pfds = 0;
 | 
			
		||||
static struct pollfd *pfds = NULL;
 | 
			
		||||
static struct link_callback *callbacks = NULL;
 | 
			
		||||
 | 
			
		||||
int links_register(int fd, const char *name, int (*callback)(void *data), void *data)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	struct link_callback *lc;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < used_pfds; i++) {
 | 
			
		||||
		if (fd == pfds[i].fd) {
 | 
			
		||||
			LOG_ERROR("links_register: Duplicate file descriptor");
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lc = malloc(sizeof(*lc));
 | 
			
		||||
	if (!lc)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	lc->fd = fd;
 | 
			
		||||
	lc->name = name;
 | 
			
		||||
	lc->data = data;
 | 
			
		||||
	lc->callback = callback;
 | 
			
		||||
 | 
			
		||||
	if (!free_pfds) {
 | 
			
		||||
		struct pollfd *tmp;
 | 
			
		||||
		tmp = realloc(pfds, sizeof(struct pollfd) * ((used_pfds*2) + 1));
 | 
			
		||||
		if (!tmp) {
 | 
			
		||||
			free(lc);
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pfds = tmp;
 | 
			
		||||
		free_pfds = used_pfds + 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free_pfds--;
 | 
			
		||||
	pfds[used_pfds].fd = fd;
 | 
			
		||||
	pfds[used_pfds].events = POLLIN;
 | 
			
		||||
	pfds[used_pfds].revents = 0;
 | 
			
		||||
	used_pfds++;
 | 
			
		||||
 | 
			
		||||
	lc->next = callbacks;
 | 
			
		||||
	callbacks = lc;
 | 
			
		||||
	LOG_DBG("Adding %s/%d", lc->name, lc->fd);
 | 
			
		||||
	LOG_DBG(" used_pfds = %u, free_pfds = %u",
 | 
			
		||||
		used_pfds, free_pfds);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int links_unregister(int fd)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	struct link_callback *p, *c;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < used_pfds; i++)
 | 
			
		||||
		if (fd == pfds[i].fd) {
 | 
			
		||||
			/* entire struct is copied (overwritten) */
 | 
			
		||||
			pfds[i] = pfds[used_pfds - 1];
 | 
			
		||||
			used_pfds--;
 | 
			
		||||
			free_pfds++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	for (p = NULL, c = callbacks; c; p = c, c = c->next)
 | 
			
		||||
		if (fd == c->fd) {
 | 
			
		||||
			LOG_DBG("Freeing up %s/%d", c->name, c->fd);
 | 
			
		||||
			LOG_DBG(" used_pfds = %u, free_pfds = %u",
 | 
			
		||||
				used_pfds, free_pfds);
 | 
			
		||||
			if (p)
 | 
			
		||||
				p->next = c->next;
 | 
			
		||||
			else
 | 
			
		||||
				callbacks = c->next;
 | 
			
		||||
			free(c);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int links_monitor(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < used_pfds; i++) {
 | 
			
		||||
		pfds[i].revents = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = poll(pfds, used_pfds, -1);
 | 
			
		||||
	if (r <= 0)
 | 
			
		||||
		return r;
 | 
			
		||||
 | 
			
		||||
	r = 0;
 | 
			
		||||
	/* FIXME: handle POLLHUP */
 | 
			
		||||
	for (i = 0; i < used_pfds; i++)
 | 
			
		||||
		if (pfds[i].revents & POLLIN) {
 | 
			
		||||
			LOG_DBG("Data ready on %d", pfds[i].fd);
 | 
			
		||||
 | 
			
		||||
			/* FIXME: Add this back return 1;*/
 | 
			
		||||
			r++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int links_issue_callbacks(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	struct link_callback *lc;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < used_pfds; i++)
 | 
			
		||||
		if (pfds[i].revents & POLLIN)
 | 
			
		||||
			for (lc = callbacks; lc; lc = lc->next)
 | 
			
		||||
				if (pfds[i].fd == lc->fd) {
 | 
			
		||||
					LOG_DBG("Issuing callback on %s/%d",
 | 
			
		||||
						lc->name, lc->fd);
 | 
			
		||||
					lc->callback(lc->data);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLOG_LINK_MON_H
 | 
			
		||||
#define _LVM_CLOG_LINK_MON_H
 | 
			
		||||
 | 
			
		||||
int links_register(int fd, const char *name, int (*callback)(void *data), void *data);
 | 
			
		||||
int links_unregister(int fd);
 | 
			
		||||
int links_monitor(void);
 | 
			
		||||
int links_issue_callbacks(void);
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_LINK_MON_H */
 | 
			
		||||
@@ -1,424 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#include "logging.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "functions.h"
 | 
			
		||||
#include "link_mon.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <linux/connector.h>
 | 
			
		||||
#include <linux/netlink.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#ifndef CN_IDX_DM
 | 
			
		||||
/* Kernel 2.6.31 is required to run this code */
 | 
			
		||||
#define CN_IDX_DM                       0x7     /* Device Mapper */
 | 
			
		||||
#define CN_VAL_DM_USERSPACE_LOG         0x1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int cn_fd = -1;  /* Connector (netlink) socket fd */
 | 
			
		||||
static char recv_buf[2048];
 | 
			
		||||
static char send_buf[2048];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* FIXME: merge this function with kernel_send_helper */
 | 
			
		||||
static int kernel_ack(uint32_t seq, int error)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	struct nlmsghdr *nlh = (struct nlmsghdr *)send_buf;
 | 
			
		||||
	struct cn_msg *msg = NLMSG_DATA(nlh);
 | 
			
		||||
 | 
			
		||||
	if (error < 0) {
 | 
			
		||||
		LOG_ERROR("Programmer error: error codes must be positive");
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memset(send_buf, 0, sizeof(send_buf));
 | 
			
		||||
 | 
			
		||||
	nlh->nlmsg_seq = 0;
 | 
			
		||||
	nlh->nlmsg_pid = getpid();
 | 
			
		||||
	nlh->nlmsg_type = NLMSG_DONE;
 | 
			
		||||
	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg));
 | 
			
		||||
	nlh->nlmsg_flags = 0;
 | 
			
		||||
 | 
			
		||||
	msg->len = 0;
 | 
			
		||||
	msg->id.idx = CN_IDX_DM;
 | 
			
		||||
	msg->id.val = CN_VAL_DM_USERSPACE_LOG;
 | 
			
		||||
	msg->seq = seq;
 | 
			
		||||
	msg->ack = error;
 | 
			
		||||
 | 
			
		||||
	r = send(cn_fd, nlh, NLMSG_LENGTH(sizeof(struct cn_msg)), 0);
 | 
			
		||||
	/* FIXME: do better error processing */
 | 
			
		||||
	if (r <= 0)
 | 
			
		||||
		return -EBADE;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * kernel_recv
 | 
			
		||||
 * @rq: the newly allocated request from kernel
 | 
			
		||||
 *
 | 
			
		||||
 * Read requests from the kernel and allocate space for the new request.
 | 
			
		||||
 * If there is no request from the kernel, *rq is NULL.
 | 
			
		||||
 *
 | 
			
		||||
 * This function is not thread safe due to returned stack pointer.  In fact,
 | 
			
		||||
 * the returned pointer must not be in-use when this function is called again.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 0 on success, -EXXX on error
 | 
			
		||||
 */
 | 
			
		||||
static int kernel_recv(struct clog_request **rq)
 | 
			
		||||
{
 | 
			
		||||
	int r = 0;
 | 
			
		||||
	ssize_t len;
 | 
			
		||||
	char *foo;
 | 
			
		||||
	struct cn_msg *msg;
 | 
			
		||||
	struct dm_ulog_request *u_rq;
 | 
			
		||||
	struct nlmsghdr *nlmsg_h;
 | 
			
		||||
 | 
			
		||||
	*rq = NULL;
 | 
			
		||||
	memset(recv_buf, 0, sizeof(recv_buf));
 | 
			
		||||
 | 
			
		||||
	len = recv(cn_fd, recv_buf, sizeof(recv_buf), 0);
 | 
			
		||||
	if (len < 0) {
 | 
			
		||||
		LOG_ERROR("Failed to recv message from kernel");
 | 
			
		||||
		r = -errno;
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nlmsg_h = (struct nlmsghdr *)recv_buf;
 | 
			
		||||
	switch (nlmsg_h->nlmsg_type) {
 | 
			
		||||
	case NLMSG_ERROR:
 | 
			
		||||
		LOG_ERROR("Unable to recv message from kernel: NLMSG_ERROR");
 | 
			
		||||
		r = -EBADE;
 | 
			
		||||
		goto fail;
 | 
			
		||||
	case NLMSG_DONE:
 | 
			
		||||
		msg = (struct cn_msg *)NLMSG_DATA((struct nlmsghdr *)recv_buf);
 | 
			
		||||
		len -= (ssize_t)sizeof(struct nlmsghdr);
 | 
			
		||||
 | 
			
		||||
		if (len < (ssize_t)sizeof(struct cn_msg)) {
 | 
			
		||||
			LOG_ERROR("Incomplete request from kernel received");
 | 
			
		||||
			r = -EBADE;
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (msg->len > DM_ULOG_REQUEST_SIZE) {
 | 
			
		||||
			LOG_ERROR("Not enough space to receive kernel request (%d/%d)",
 | 
			
		||||
				  msg->len, DM_ULOG_REQUEST_SIZE);
 | 
			
		||||
			r = -EBADE;
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!msg->len)
 | 
			
		||||
			LOG_ERROR("Zero length message received");
 | 
			
		||||
 | 
			
		||||
		len -= (ssize_t)sizeof(struct cn_msg);
 | 
			
		||||
 | 
			
		||||
		if (len < msg->len)
 | 
			
		||||
			LOG_ERROR("len = %zd, msg->len = %" PRIu16, len, msg->len);
 | 
			
		||||
 | 
			
		||||
		msg->data[msg->len] = '\0'; /* Cleaner way to ensure this? */
 | 
			
		||||
		u_rq = (struct dm_ulog_request *)msg->data;
 | 
			
		||||
 | 
			
		||||
		if (!u_rq->request_type) {
 | 
			
		||||
			LOG_DBG("Bad transmission, requesting resend [%u]",
 | 
			
		||||
				msg->seq);
 | 
			
		||||
			r = -EAGAIN;
 | 
			
		||||
 | 
			
		||||
			if (kernel_ack(msg->seq, EAGAIN)) {
 | 
			
		||||
				LOG_ERROR("Failed to NACK kernel transmission [%u]",
 | 
			
		||||
					  msg->seq);
 | 
			
		||||
				r = -EBADE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Now we've got sizeof(struct cn_msg) + sizeof(struct nlmsghdr)
 | 
			
		||||
		 * worth of space that precede the request structure from the
 | 
			
		||||
		 * kernel.  Since that space isn't going to be used again, we
 | 
			
		||||
		 * can take it for our purposes; rather than allocating a whole
 | 
			
		||||
		 * new structure and doing a memcpy.
 | 
			
		||||
		 *
 | 
			
		||||
		 * We should really make sure 'clog_request' doesn't grow
 | 
			
		||||
		 * beyond what is available to us, but we need only check it
 | 
			
		||||
		 * once... perhaps at compile time?
 | 
			
		||||
		 */
 | 
			
		||||
		foo = (char *)u_rq;
 | 
			
		||||
		foo -= (sizeof(struct clog_request) - sizeof(struct dm_ulog_request));
 | 
			
		||||
		*rq = (struct clog_request *) foo;
 | 
			
		||||
 | 
			
		||||
		/* Clear the wrapper container fields */
 | 
			
		||||
		memset(*rq, 0, (size_t)((char *)u_rq - (char *)(*rq)));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		LOG_ERROR("Unknown nlmsg_type");
 | 
			
		||||
		r = -EBADE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
	if (r)
 | 
			
		||||
		*rq = NULL;
 | 
			
		||||
 | 
			
		||||
	return (r == -EAGAIN) ? 0 : r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int kernel_send_helper(void *data, uint16_t out_size)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	struct nlmsghdr *nlh;
 | 
			
		||||
	struct cn_msg *msg;
 | 
			
		||||
 | 
			
		||||
	memset(send_buf, 0, sizeof(send_buf));
 | 
			
		||||
 | 
			
		||||
	nlh = (struct nlmsghdr *)send_buf;
 | 
			
		||||
	nlh->nlmsg_seq = 0;  /* FIXME: Is this used? */
 | 
			
		||||
	nlh->nlmsg_pid = getpid();
 | 
			
		||||
	nlh->nlmsg_type = NLMSG_DONE;
 | 
			
		||||
	nlh->nlmsg_len = NLMSG_LENGTH(out_size + sizeof(struct cn_msg));
 | 
			
		||||
	nlh->nlmsg_flags = 0;
 | 
			
		||||
 | 
			
		||||
	msg = NLMSG_DATA(nlh);
 | 
			
		||||
	memcpy(msg->data, data, out_size);
 | 
			
		||||
	msg->len = out_size;
 | 
			
		||||
	msg->id.idx = CN_IDX_DM;
 | 
			
		||||
	msg->id.val = CN_VAL_DM_USERSPACE_LOG;
 | 
			
		||||
	msg->seq = 0;
 | 
			
		||||
 | 
			
		||||
	r = send(cn_fd, nlh, NLMSG_LENGTH(out_size + sizeof(struct cn_msg)), 0);
 | 
			
		||||
	/* FIXME: do better error processing */
 | 
			
		||||
	if (r <= 0)
 | 
			
		||||
		return -EBADE;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * do_local_work
 | 
			
		||||
 *
 | 
			
		||||
 * Any processing errors are placed in the 'rq'
 | 
			
		||||
 * structure to be reported back to the kernel.
 | 
			
		||||
 * It may be pointless for this function to
 | 
			
		||||
 * return an int.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 0 on success, -EXXX on failure
 | 
			
		||||
 */
 | 
			
		||||
static int do_local_work(void *data __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	struct clog_request *rq;
 | 
			
		||||
	struct dm_ulog_request *u_rq = NULL;
 | 
			
		||||
 | 
			
		||||
	r = kernel_recv(&rq);
 | 
			
		||||
	if (r)
 | 
			
		||||
		return r;
 | 
			
		||||
 | 
			
		||||
	if (!rq)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	u_rq = &rq->u_rq;
 | 
			
		||||
	LOG_DBG("[%s]  Request from kernel received: [%s/%u]",
 | 
			
		||||
		SHORT_UUID(u_rq->uuid), RQ_TYPE(u_rq->request_type),
 | 
			
		||||
		u_rq->seq);
 | 
			
		||||
	switch (u_rq->request_type) {
 | 
			
		||||
	case DM_ULOG_CTR:
 | 
			
		||||
	case DM_ULOG_DTR:
 | 
			
		||||
	case DM_ULOG_GET_REGION_SIZE:
 | 
			
		||||
	case DM_ULOG_IN_SYNC:
 | 
			
		||||
	case DM_ULOG_GET_SYNC_COUNT:
 | 
			
		||||
	case DM_ULOG_STATUS_TABLE:
 | 
			
		||||
	case DM_ULOG_PRESUSPEND:
 | 
			
		||||
		/* We do not specify ourselves as server here */
 | 
			
		||||
		r = do_request(rq, 0);
 | 
			
		||||
		if (r)
 | 
			
		||||
			LOG_DBG("Returning failed request to kernel [%s]",
 | 
			
		||||
				RQ_TYPE(u_rq->request_type));
 | 
			
		||||
		r = kernel_send(u_rq);
 | 
			
		||||
		if (r)
 | 
			
		||||
			LOG_ERROR("Failed to respond to kernel [%s]",
 | 
			
		||||
				  RQ_TYPE(u_rq->request_type));
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
	case DM_ULOG_RESUME:
 | 
			
		||||
		/*
 | 
			
		||||
		 * Resume is a special case that requires a local
 | 
			
		||||
		 * component to join the CPG, and a cluster component
 | 
			
		||||
		 * to handle the request.
 | 
			
		||||
		 */
 | 
			
		||||
		r = local_resume(u_rq);
 | 
			
		||||
		if (r) {
 | 
			
		||||
			LOG_DBG("Returning failed request to kernel [%s]",
 | 
			
		||||
				RQ_TYPE(u_rq->request_type));
 | 
			
		||||
			r = kernel_send(u_rq);
 | 
			
		||||
			if (r)
 | 
			
		||||
				LOG_ERROR("Failed to respond to kernel [%s]",
 | 
			
		||||
					  RQ_TYPE(u_rq->request_type));
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		/* ELSE, fall through */
 | 
			
		||||
	case DM_ULOG_IS_CLEAN:
 | 
			
		||||
	case DM_ULOG_FLUSH:
 | 
			
		||||
	case DM_ULOG_MARK_REGION:
 | 
			
		||||
	case DM_ULOG_GET_RESYNC_WORK:
 | 
			
		||||
	case DM_ULOG_SET_REGION_SYNC:
 | 
			
		||||
	case DM_ULOG_STATUS_INFO:
 | 
			
		||||
	case DM_ULOG_IS_REMOTE_RECOVERING:
 | 
			
		||||
	case DM_ULOG_POSTSUSPEND:
 | 
			
		||||
		r = cluster_send(rq);
 | 
			
		||||
		if (r) {
 | 
			
		||||
			u_rq->data_size = 0;
 | 
			
		||||
			u_rq->error = r;
 | 
			
		||||
			if (kernel_send(u_rq))
 | 
			
		||||
				LOG_ERROR("Failed to respond to kernel [%s]",
 | 
			
		||||
					  RQ_TYPE(u_rq->request_type));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
	case DM_ULOG_CLEAR_REGION:
 | 
			
		||||
		r = kernel_ack(u_rq->seq, 0);
 | 
			
		||||
 | 
			
		||||
		r = cluster_send(rq);
 | 
			
		||||
		if (r) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * FIXME: store error for delivery on flush
 | 
			
		||||
			 *        This would allow us to optimize MARK_REGION
 | 
			
		||||
			 *        too.
 | 
			
		||||
			 */
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		LOG_ERROR("Invalid log request received (%u), ignoring.",
 | 
			
		||||
			  u_rq->request_type);
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (r && !u_rq->error)
 | 
			
		||||
		u_rq->error = r;
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * kernel_send
 | 
			
		||||
 * @u_rq: result to pass back to kernel
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns the u_rq structure
 | 
			
		||||
 * (containing the results) to the kernel.
 | 
			
		||||
 * It then frees the structure.
 | 
			
		||||
 *
 | 
			
		||||
 * WARNING: should the structure be freed if
 | 
			
		||||
 * there is an error?  I vote 'yes'.  If the
 | 
			
		||||
 * kernel doesn't get the response, it should
 | 
			
		||||
 * resend the request.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 0 on success, -EXXX on failure
 | 
			
		||||
 */
 | 
			
		||||
int kernel_send(struct dm_ulog_request *u_rq)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	uint16_t size;
 | 
			
		||||
 | 
			
		||||
	if (!u_rq)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	size = (uint16_t)(sizeof(struct dm_ulog_request) + u_rq->data_size);
 | 
			
		||||
 | 
			
		||||
	if (!u_rq->data_size && !u_rq->error) {
 | 
			
		||||
		/* An ACK is all that is needed */
 | 
			
		||||
 | 
			
		||||
		/* FIXME: add ACK code */
 | 
			
		||||
	} else if (size > DM_ULOG_REQUEST_SIZE) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * If we gotten here, we've already overrun
 | 
			
		||||
		 * our allotted space somewhere.
 | 
			
		||||
		 *
 | 
			
		||||
		 * We must do something, because the kernel
 | 
			
		||||
		 * is waiting for a response.
 | 
			
		||||
		 */
 | 
			
		||||
		LOG_ERROR("Not enough space to respond to server");
 | 
			
		||||
		u_rq->error = -ENOSPC;
 | 
			
		||||
		size = sizeof(struct dm_ulog_request);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = kernel_send_helper(u_rq, size);
 | 
			
		||||
	if (r)
 | 
			
		||||
		LOG_ERROR("Failed to send msg to kernel.");
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * init_local
 | 
			
		||||
 *
 | 
			
		||||
 * Initialize kernel communication socket (netlink)
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 0 on success, values from common.h on failure
 | 
			
		||||
 */
 | 
			
		||||
int init_local(void)
 | 
			
		||||
{
 | 
			
		||||
	int r = 0;
 | 
			
		||||
	unsigned opt;
 | 
			
		||||
	struct sockaddr_nl addr;
 | 
			
		||||
 | 
			
		||||
	cn_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
 | 
			
		||||
	if (cn_fd < 0)
 | 
			
		||||
		return EXIT_KERNEL_SOCKET;
 | 
			
		||||
 | 
			
		||||
	/* memset to fix valgrind complaint */
 | 
			
		||||
	memset(&addr, 0, sizeof(struct sockaddr_nl));
 | 
			
		||||
 | 
			
		||||
	addr.nl_family = AF_NETLINK;
 | 
			
		||||
	addr.nl_groups = CN_IDX_DM;
 | 
			
		||||
	addr.nl_pid = 0;
 | 
			
		||||
 | 
			
		||||
	r = bind(cn_fd, (struct sockaddr *) &addr, sizeof(addr));
 | 
			
		||||
	if (r < 0) {
 | 
			
		||||
		if (close(cn_fd))
 | 
			
		||||
			LOG_ERROR("Failed to close socket: %s",
 | 
			
		||||
				  strerror(errno));
 | 
			
		||||
		return EXIT_KERNEL_BIND;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opt = addr.nl_groups;
 | 
			
		||||
	r = setsockopt(cn_fd, 270, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt));
 | 
			
		||||
	if (r) {
 | 
			
		||||
		if (close(cn_fd))
 | 
			
		||||
			LOG_ERROR("Failed to close socket: %s",
 | 
			
		||||
				  strerror(errno));
 | 
			
		||||
		return EXIT_KERNEL_SETSOCKOPT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	r = fcntl(cn_fd, F_SETFL, FNDELAY);
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	links_register(cn_fd, "local", do_local_work, NULL);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * cleanup_local
 | 
			
		||||
 *
 | 
			
		||||
 * Clean up before exiting
 | 
			
		||||
 */
 | 
			
		||||
void cleanup_local(void)
 | 
			
		||||
{
 | 
			
		||||
	links_unregister(cn_fd);
 | 
			
		||||
	if (cn_fd >= 0 && close(cn_fd))
 | 
			
		||||
		LOG_ERROR("Failed to close socket: %s",
 | 
			
		||||
			  strerror(errno));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _LVM_CLOG_LOCAL_H
 | 
			
		||||
#define _LVM_CLOG_LOCAL_H
 | 
			
		||||
 | 
			
		||||
int init_local(void);
 | 
			
		||||
void cleanup_local(void);
 | 
			
		||||
 | 
			
		||||
int kernel_send(struct dm_ulog_request *rq);
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_LOCAL_H */
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
#include "logging.h"
 | 
			
		||||
 | 
			
		||||
const char *__rq_types_off_by_one[] = {
 | 
			
		||||
	"DM_ULOG_CTR",
 | 
			
		||||
	"DM_ULOG_DTR",
 | 
			
		||||
	"DM_ULOG_PRESUSPEND",
 | 
			
		||||
	"DM_ULOG_POSTSUSPEND",
 | 
			
		||||
	"DM_ULOG_RESUME",
 | 
			
		||||
	"DM_ULOG_GET_REGION_SIZE",
 | 
			
		||||
	"DM_ULOG_IS_CLEAN",
 | 
			
		||||
	"DM_ULOG_IN_SYNC",
 | 
			
		||||
	"DM_ULOG_FLUSH",
 | 
			
		||||
	"DM_ULOG_MARK_REGION",
 | 
			
		||||
	"DM_ULOG_CLEAR_REGION",
 | 
			
		||||
	"DM_ULOG_GET_RESYNC_WORK",
 | 
			
		||||
	"DM_ULOG_SET_REGION_SYNC",
 | 
			
		||||
	"DM_ULOG_GET_SYNC_COUNT",
 | 
			
		||||
	"DM_ULOG_STATUS_INFO",
 | 
			
		||||
	"DM_ULOG_STATUS_TABLE",
 | 
			
		||||
	"DM_ULOG_IS_REMOTE_RECOVERING",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int log_tabbing = 0;
 | 
			
		||||
int log_is_open = 0;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Variables for various conditional logging
 | 
			
		||||
 */
 | 
			
		||||
#ifdef MEMB
 | 
			
		||||
int log_membership_change = 1;
 | 
			
		||||
#else
 | 
			
		||||
int log_membership_change = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CKPT
 | 
			
		||||
int log_checkpoint = 1;
 | 
			
		||||
#else
 | 
			
		||||
int log_checkpoint = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RESEND
 | 
			
		||||
int log_resend_requests = 1;
 | 
			
		||||
#else
 | 
			
		||||
int log_resend_requests = 0;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_CLOG_LOGGING_H
 | 
			
		||||
#define _LVM_CLOG_LOGGING_H
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#define _FILE_OFFSET_BITS 64
 | 
			
		||||
 | 
			
		||||
#include "configure.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
/* SHORT_UUID - print last 8 chars of a string */
 | 
			
		||||
#define SHORT_UUID(x) (strlen(x) > 8) ? ((x) + (strlen(x) - 8)) : (x)
 | 
			
		||||
 | 
			
		||||
extern const char *__rq_types_off_by_one[];
 | 
			
		||||
#define RQ_TYPE(x) __rq_types_off_by_one[(x) - 1]
 | 
			
		||||
 | 
			
		||||
extern int log_tabbing;
 | 
			
		||||
extern int log_is_open;
 | 
			
		||||
extern int log_membership_change;
 | 
			
		||||
extern int log_checkpoint;
 | 
			
		||||
extern int log_resend_requests;
 | 
			
		||||
 | 
			
		||||
#define LOG_OPEN(ident, option, facility) do { \
 | 
			
		||||
		openlog(ident, option, facility); \
 | 
			
		||||
		log_is_open = 1;		  \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define LOG_CLOSE(void) do { \
 | 
			
		||||
		log_is_open = 0; \
 | 
			
		||||
		closelog();	 \
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define LOG_OUTPUT(level, f, arg...) do {				\
 | 
			
		||||
		int __i;						\
 | 
			
		||||
		char __buffer[16];					\
 | 
			
		||||
		FILE *fp = (level > LOG_NOTICE) ? stderr : stdout;	\
 | 
			
		||||
		if (log_is_open) {					\
 | 
			
		||||
			for (__i = 0; (__i < log_tabbing) && (__i < 15); __i++) \
 | 
			
		||||
				__buffer[__i] = '\t';			\
 | 
			
		||||
			__buffer[__i] = '\0';				\
 | 
			
		||||
			syslog(level, "%s" f "\n", __buffer, ## arg);	\
 | 
			
		||||
		} else {						\
 | 
			
		||||
			for (__i = 0; __i < log_tabbing; __i++)		\
 | 
			
		||||
				fprintf(fp, "\t");			\
 | 
			
		||||
			fprintf(fp, f "\n", ## arg);			\
 | 
			
		||||
		}							\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
#define LOG_DBG(f, arg...) LOG_OUTPUT(LOG_DEBUG, f, ## arg)
 | 
			
		||||
#else /* DEBUG */
 | 
			
		||||
#define LOG_DBG(f, arg...) do {} while (0)
 | 
			
		||||
#endif /* DEBUG */
 | 
			
		||||
 | 
			
		||||
#define LOG_COND(__X, f, arg...) do {\
 | 
			
		||||
		if (__X) { 	     \
 | 
			
		||||
			LOG_OUTPUT(LOG_NOTICE, f, ## arg); \
 | 
			
		||||
		} \
 | 
			
		||||
	} while (0)
 | 
			
		||||
#define LOG_PRINT(f, arg...) LOG_OUTPUT(LOG_NOTICE, f, ## arg)
 | 
			
		||||
#define LOG_ERROR(f, arg...) LOG_OUTPUT(LOG_ERR, f, ## arg)
 | 
			
		||||
 | 
			
		||||
#endif /* _LVM_CLOG_LOGGING_H */
 | 
			
		||||
@@ -1,4 +1,19 @@
 | 
			
		||||
init_fifos
 | 
			
		||||
fini_fifos
 | 
			
		||||
daemon_talk
 | 
			
		||||
dm_event_get_version
 | 
			
		||||
dm_event_handler_create
 | 
			
		||||
dm_event_handler_destroy
 | 
			
		||||
dm_event_handler_set_dso
 | 
			
		||||
dm_event_handler_set_dev_name
 | 
			
		||||
dm_event_handler_set_uuid
 | 
			
		||||
dm_event_handler_set_major
 | 
			
		||||
dm_event_handler_set_minor
 | 
			
		||||
dm_event_handler_set_event_mask
 | 
			
		||||
dm_event_handler_get_dso
 | 
			
		||||
dm_event_handler_get_devname
 | 
			
		||||
dm_event_handler_get_uuid
 | 
			
		||||
dm_event_handler_get_major
 | 
			
		||||
dm_event_handler_get_minor
 | 
			
		||||
dm_event_handler_get_event_mask
 | 
			
		||||
dm_event_register_handler
 | 
			
		||||
dm_event_unregister_handler
 | 
			
		||||
dm_event_get_registered_device
 | 
			
		||||
dm_event_handler_set_timeout
 | 
			
		||||
dm_event_handler_get_timeout
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of the device-mapper userspace tools.
 | 
			
		||||
#
 | 
			
		||||
@@ -13,98 +13,71 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
SOURCES = libdevmapper-event.c
 | 
			
		||||
SOURCES2 = dmeventd.c
 | 
			
		||||
 | 
			
		||||
LIB_STATIC = libdevmapper-event.a
 | 
			
		||||
 | 
			
		||||
ifeq ("@LIB_SUFFIX@","dylib")
 | 
			
		||||
  LIB_SHARED = libdevmapper-event.dylib
 | 
			
		||||
else
 | 
			
		||||
  LIB_SHARED = libdevmapper-event.so
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
TARGETS = dmeventd
 | 
			
		||||
CLEAN_TARGETS = dmeventd.o
 | 
			
		||||
 | 
			
		||||
.PHONY: install_lib_dynamic install_lib_static install_include \
 | 
			
		||||
	install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
 | 
			
		||||
	install_lib install_dmeventd
 | 
			
		||||
include ../make.tmpl
 | 
			
		||||
 | 
			
		||||
INSTALL_DMEVENTD_TARGETS = install_dmeventd_dynamic
 | 
			
		||||
INSTALL_LIB_TARGETS = install_lib_dynamic
 | 
			
		||||
 | 
			
		||||
LIB_NAME = libdevmapper-event
 | 
			
		||||
ifeq ("@STATIC_LINK@", "yes")
 | 
			
		||||
  LIB_STATIC = $(LIB_NAME).a
 | 
			
		||||
  TARGETS += $(LIB_STATIC) dmeventd.static
 | 
			
		||||
  INSTALL_DMEVENTD_TARGETS += install_dmeventd_static
 | 
			
		||||
  INSTALL_LIB_TARGETS += install_lib_static
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_DM)
 | 
			
		||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
 | 
			
		||||
 | 
			
		||||
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
 | 
			
		||||
 | 
			
		||||
ifneq ($(MAKECMDGOALS),device-mapper)
 | 
			
		||||
  SUBDIRS+=plugins
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
CFLOW_LIST = $(SOURCES)
 | 
			
		||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
 | 
			
		||||
CFLOW_TARGET = dmeventd
 | 
			
		||||
 | 
			
		||||
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
 | 
			
		||||
EXPORTED_FN_PREFIX = dm_event
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
all: device-mapper
 | 
			
		||||
device-mapper: $(TARGETS)
 | 
			
		||||
 | 
			
		||||
LIBS += -ldevmapper
 | 
			
		||||
LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
 | 
			
		||||
 | 
			
		||||
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
 | 
			
		||||
LDFLAGS += -ldl -ldevmapper -lpthread
 | 
			
		||||
CLDFLAGS += -ldl -ldevmapper -lpthread
 | 
			
		||||
 | 
			
		||||
dmeventd: $(LIB_SHARED) dmeventd.o
 | 
			
		||||
	$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
 | 
			
		||||
	$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
 | 
			
		||||
	$(CC) -o $@ dmeventd.o $(CFLAGS) $(LDFLAGS) \
 | 
			
		||||
	-L. -ldevmapper-event $(LIBS) -rdynamic
 | 
			
		||||
 | 
			
		||||
dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a
 | 
			
		||||
	$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
 | 
			
		||||
	dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
 | 
			
		||||
.PHONY: install_dynamic install_static install_include \
 | 
			
		||||
	install_pkgconfig install_dmeventd
 | 
			
		||||
 | 
			
		||||
INSTALL_TYPE = install_dynamic
 | 
			
		||||
 | 
			
		||||
ifeq ("@STATIC_LINK@", "yes")
 | 
			
		||||
  INSTALL_TYPE += install_static
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ("@PKGCONFIG@", "yes")
 | 
			
		||||
  INSTALL_LIB_TARGETS += install_pkgconfig
 | 
			
		||||
  INSTALL_TYPE += install_pkgconfig
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ("$(CFLOW_CMD)", "")
 | 
			
		||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
 | 
			
		||||
-include $(top_builddir)/libdm/libdevmapper.cflow
 | 
			
		||||
-include $(top_builddir)/lib/liblvm-internal.cflow
 | 
			
		||||
-include $(top_builddir)/lib/liblvm2cmd.cflow
 | 
			
		||||
-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
 | 
			
		||||
-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
 | 
			
		||||
endif
 | 
			
		||||
install: $(INSTALL_TYPE) install_include install_dmeventd
 | 
			
		||||
 | 
			
		||||
install_include: $(srcdir)/libdevmapper-event.h
 | 
			
		||||
	$(INSTALL_DATA) -D $< $(includedir)/$(<F)
 | 
			
		||||
install_include:
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
 | 
			
		||||
		$(includedir)/libdevmapper-event.h
 | 
			
		||||
 | 
			
		||||
install_pkgconfig: libdevmapper-event.pc
 | 
			
		||||
	$(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
 | 
			
		||||
install_dynamic: libdevmapper-event.$(LIB_SUFFIX)
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
 | 
			
		||||
		$(libdir)/libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION)
 | 
			
		||||
	$(LN_S) -f libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) \
 | 
			
		||||
		$(libdir)/libdevmapper-event.$(LIB_SUFFIX)
 | 
			
		||||
 | 
			
		||||
install_lib_dynamic: install_lib_shared
 | 
			
		||||
install_dmeventd: dmeventd
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$<
 | 
			
		||||
 | 
			
		||||
install_lib_static: $(LIB_STATIC)
 | 
			
		||||
	$(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
 | 
			
		||||
install_pkgconfig:
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.pc \
 | 
			
		||||
		$(usrlibdir)/pkgconfig/devmapper-event.pc
 | 
			
		||||
 | 
			
		||||
install_lib: $(INSTALL_LIB_TARGETS)
 | 
			
		||||
install_static: libdevmapper-event.a
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
 | 
			
		||||
		$(libdir)/libdevmapper-event.a.$(LIB_VERSION)
 | 
			
		||||
	$(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
 | 
			
		||||
 | 
			
		||||
install_dmeventd_dynamic: dmeventd
 | 
			
		||||
	$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
 | 
			
		||||
.PHONY: distclean_lib distclean
 | 
			
		||||
 | 
			
		||||
install_dmeventd_static: dmeventd.static
 | 
			
		||||
	$(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
 | 
			
		||||
distclean_lib: 
 | 
			
		||||
	$(RM) libdevmapper-event.pc
 | 
			
		||||
 | 
			
		||||
install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)
 | 
			
		||||
distclean: distclean_lib
 | 
			
		||||
 | 
			
		||||
install: install_include install_lib install_dmeventd
 | 
			
		||||
 | 
			
		||||
install_device-mapper: install_include install_lib install_dmeventd
 | 
			
		||||
 | 
			
		||||
DISTCLEAN_TARGETS += libdevmapper-event.pc
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,24 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of the device-mapper userspace tools.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __DMEVENTD_DOT_H__
 | 
			
		||||
#define __DMEVENTD_DOT_H__
 | 
			
		||||
 | 
			
		||||
/* FIXME This stuff must be configurable. */
 | 
			
		||||
 | 
			
		||||
#define	DM_EVENT_FIFO_CLIENT	DEFAULT_DM_RUN_DIR "/dmeventd-client"
 | 
			
		||||
#define	DM_EVENT_FIFO_SERVER	DEFAULT_DM_RUN_DIR "/dmeventd-server"
 | 
			
		||||
#define	DM_EVENT_DAEMON		"/sbin/dmeventd"
 | 
			
		||||
#define DM_EVENT_LOCKFILE	"/var/lock/dmeventd"
 | 
			
		||||
#define	DM_EVENT_FIFO_CLIENT	"/var/run/dmeventd-client"
 | 
			
		||||
#define	DM_EVENT_FIFO_SERVER	"/var/run/dmeventd-server"
 | 
			
		||||
#define DM_EVENT_PIDFILE	"/var/run/dmeventd.pid"
 | 
			
		||||
 | 
			
		||||
#define DM_EVENT_DEFAULT_TIMEOUT 10
 | 
			
		||||
 | 
			
		||||
@@ -32,9 +21,6 @@ enum dm_event_command {
 | 
			
		||||
	DM_EVENT_CMD_SET_TIMEOUT,
 | 
			
		||||
	DM_EVENT_CMD_GET_TIMEOUT,
 | 
			
		||||
	DM_EVENT_CMD_HELLO,
 | 
			
		||||
	DM_EVENT_CMD_DIE,
 | 
			
		||||
	DM_EVENT_CMD_GET_STATUS,
 | 
			
		||||
	DM_EVENT_CMD_GET_PARAMETERS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Message passed between client and daemon. */
 | 
			
		||||
@@ -56,21 +42,11 @@ struct dm_event_fifos {
 | 
			
		||||
 | 
			
		||||
/*      EXIT_SUCCESS             0 -- stdlib.h */
 | 
			
		||||
/*      EXIT_FAILURE             1 -- stdlib.h */
 | 
			
		||||
/*      EXIT_LOCKFILE_INUSE      2 -- obsoleted */
 | 
			
		||||
#define EXIT_LOCKFILE_INUSE      2
 | 
			
		||||
#define EXIT_DESC_CLOSE_FAILURE  3
 | 
			
		||||
#define EXIT_DESC_OPEN_FAILURE   4
 | 
			
		||||
/*      EXIT_OPEN_PID_FAILURE    5 -- obsoleted */
 | 
			
		||||
#define EXIT_OPEN_PID_FAILURE    5
 | 
			
		||||
#define EXIT_FIFO_FAILURE        6
 | 
			
		||||
#define EXIT_CHDIR_FAILURE       7
 | 
			
		||||
 | 
			
		||||
/* Implemented in libdevmapper-event.c, but not part of public API. */
 | 
			
		||||
// FIXME  misuse of bitmask as enum
 | 
			
		||||
int daemon_talk(struct dm_event_fifos *fifos,
 | 
			
		||||
		struct dm_event_daemon_message *msg, int cmd,
 | 
			
		||||
		const char *dso_name, const char *dev_name,
 | 
			
		||||
		enum dm_event_mask evmask, uint32_t timeout);
 | 
			
		||||
int init_fifos(struct dm_event_fifos *fifos);
 | 
			
		||||
void fini_fifos(struct dm_event_fifos *fifos);
 | 
			
		||||
int dm_event_get_version(struct dm_event_fifos *fifos, int *version);
 | 
			
		||||
 | 
			
		||||
#endif /* __DMEVENTD_DOT_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of the device-mapper userspace tools.
 | 
			
		||||
 *
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "dmlib.h"
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "libdevmapper-event.h"
 | 
			
		||||
//#include "libmultilog.h"
 | 
			
		||||
#include "dmeventd.h"
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
@@ -34,8 +35,6 @@ static int _sequence_nr = 0;
 | 
			
		||||
struct dm_event_handler {
 | 
			
		||||
	char *dso;
 | 
			
		||||
 | 
			
		||||
	char *dmeventd_path;
 | 
			
		||||
 | 
			
		||||
	char *dev_name;
 | 
			
		||||
 | 
			
		||||
	char *uuid;
 | 
			
		||||
@@ -48,20 +47,25 @@ struct dm_event_handler {
 | 
			
		||||
 | 
			
		||||
static void _dm_event_handler_clear_dev_info(struct dm_event_handler *dmevh)
 | 
			
		||||
{
 | 
			
		||||
	dm_free(dmevh->dev_name);
 | 
			
		||||
	dm_free(dmevh->uuid);
 | 
			
		||||
	if (dmevh->dev_name)
 | 
			
		||||
		dm_free(dmevh->dev_name);
 | 
			
		||||
	if (dmevh->uuid)
 | 
			
		||||
		dm_free(dmevh->uuid);
 | 
			
		||||
	dmevh->dev_name = dmevh->uuid = NULL;
 | 
			
		||||
	dmevh->major = dmevh->minor = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dm_event_handler *dm_event_handler_create(void)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_event_handler *dmevh;
 | 
			
		||||
	struct dm_event_handler *dmevh = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh = dm_zalloc(sizeof(*dmevh)))) {
 | 
			
		||||
		log_error("Failed to allocate event handler.");
 | 
			
		||||
	if (!(dmevh = dm_malloc(sizeof(*dmevh))))
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dmevh->dso = dmevh->dev_name = dmevh->uuid = NULL;
 | 
			
		||||
	dmevh->major = dmevh->minor = 0;
 | 
			
		||||
	dmevh->mask = 0;
 | 
			
		||||
	dmevh->timeout = 0;
 | 
			
		||||
 | 
			
		||||
	return dmevh;
 | 
			
		||||
}
 | 
			
		||||
@@ -69,32 +73,20 @@ struct dm_event_handler *dm_event_handler_create(void)
 | 
			
		||||
void dm_event_handler_destroy(struct dm_event_handler *dmevh)
 | 
			
		||||
{
 | 
			
		||||
	_dm_event_handler_clear_dev_info(dmevh);
 | 
			
		||||
	dm_free(dmevh->dso);
 | 
			
		||||
	dm_free(dmevh->dmeventd_path);
 | 
			
		||||
	if (dmevh->dso)
 | 
			
		||||
		dm_free(dmevh->dso);
 | 
			
		||||
	dm_free(dmevh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path)
 | 
			
		||||
{
 | 
			
		||||
	if (!dmeventd_path) /* noop */
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	dm_free(dmevh->dmeventd_path);
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh->dmeventd_path = dm_strdup(dmeventd_path)))
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
 | 
			
		||||
{
 | 
			
		||||
	if (!path) /* noop */
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (dmevh->dso)
 | 
			
		||||
		dm_free(dmevh->dso);
 | 
			
		||||
 | 
			
		||||
	dm_free(dmevh->dso);
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh->dso = dm_strdup(path)))
 | 
			
		||||
	dmevh->dso = dm_strdup(path);
 | 
			
		||||
	if (!dmevh->dso)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
@@ -107,9 +99,9 @@ int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *de
 | 
			
		||||
 | 
			
		||||
	_dm_event_handler_clear_dev_info(dmevh);
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh->dev_name = dm_strdup(dev_name)))
 | 
			
		||||
	dmevh->dev_name = dm_strdup(dev_name);
 | 
			
		||||
	if (!dmevh->dev_name)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -120,9 +112,9 @@ int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid)
 | 
			
		||||
 | 
			
		||||
	_dm_event_handler_clear_dev_info(dmevh);
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh->uuid = dm_strdup(uuid)))
 | 
			
		||||
	dmevh->uuid = dm_strdup(uuid);
 | 
			
		||||
	if (!dmevh->dev_name)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -222,25 +214,23 @@ static int _daemon_read(struct dm_event_fifos *fifos,
 | 
			
		||||
	unsigned bytes = 0;
 | 
			
		||||
	int ret, i;
 | 
			
		||||
	fd_set fds;
 | 
			
		||||
	struct timeval tval = { 0, 0 };
 | 
			
		||||
	size_t size = 2 * sizeof(uint32_t);	/* status + size */
 | 
			
		||||
	uint32_t *header = alloca(size);
 | 
			
		||||
	char *buf = (char *)header;
 | 
			
		||||
	char *buf = alloca(size);
 | 
			
		||||
	int header = 1;
 | 
			
		||||
 | 
			
		||||
	while (bytes < size) {
 | 
			
		||||
		for (i = 0, ret = 0; (i < 20) && (ret < 1); i++) {
 | 
			
		||||
			/* Watch daemon read FIFO for input. */
 | 
			
		||||
			struct timeval tval = { .tv_sec = 1 };
 | 
			
		||||
			FD_ZERO(&fds);
 | 
			
		||||
			FD_SET(fifos->server, &fds);
 | 
			
		||||
			ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
 | 
			
		||||
			tval.tv_sec = 1;
 | 
			
		||||
			ret = select(fifos->server + 1, &fds, NULL, NULL,
 | 
			
		||||
				     &tval);
 | 
			
		||||
			if (ret < 0 && errno != EINTR) {
 | 
			
		||||
				log_error("Unable to read from event server");
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			if ((ret == 0) && (i > 4) && !bytes) {
 | 
			
		||||
				log_error("No input from event server.");
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (ret < 1) {
 | 
			
		||||
			log_error("Unable to read from event server.");
 | 
			
		||||
@@ -258,9 +248,9 @@ static int _daemon_read(struct dm_event_fifos *fifos,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bytes += ret;
 | 
			
		||||
		if (header && (bytes == 2 * sizeof(uint32_t))) {
 | 
			
		||||
			msg->cmd = ntohl(header[0]);
 | 
			
		||||
			msg->size = ntohl(header[1]);
 | 
			
		||||
		if (bytes == 2 * sizeof(uint32_t) && header) {
 | 
			
		||||
			msg->cmd = ntohl(*((uint32_t *)buf));
 | 
			
		||||
			msg->size = ntohl(*((uint32_t *)buf + 1));
 | 
			
		||||
			buf = msg->data = dm_malloc(msg->size);
 | 
			
		||||
			size = msg->size;
 | 
			
		||||
			bytes = 0;
 | 
			
		||||
@@ -269,9 +259,11 @@ static int _daemon_read(struct dm_event_fifos *fifos,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (bytes != size) {
 | 
			
		||||
		dm_free(msg->data);
 | 
			
		||||
		if (msg->data)
 | 
			
		||||
			dm_free(msg->data);
 | 
			
		||||
		msg->data = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bytes == size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -279,39 +271,32 @@ static int _daemon_read(struct dm_event_fifos *fifos,
 | 
			
		||||
static int _daemon_write(struct dm_event_fifos *fifos,
 | 
			
		||||
			 struct dm_event_daemon_message *msg)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	unsigned bytes = 0;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	fd_set fds;
 | 
			
		||||
	size_t bytes = 0;
 | 
			
		||||
	size_t size = 2 * sizeof(uint32_t) + msg->size;
 | 
			
		||||
	uint32_t *header = alloca(size);
 | 
			
		||||
	char *buf = (char *)header;
 | 
			
		||||
	char drainbuf[128];
 | 
			
		||||
 | 
			
		||||
	header[0] = htonl(msg->cmd);
 | 
			
		||||
	header[1] = htonl(msg->size);
 | 
			
		||||
	size_t size = 2 * sizeof(uint32_t) + msg->size;
 | 
			
		||||
	char *buf = alloca(size);
 | 
			
		||||
	char drainbuf[128];
 | 
			
		||||
	struct timeval tval = { 0, 0 };
 | 
			
		||||
 | 
			
		||||
	*((uint32_t *)buf) = htonl(msg->cmd);
 | 
			
		||||
	*((uint32_t *)buf + 1) = htonl(msg->size);
 | 
			
		||||
	memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
 | 
			
		||||
 | 
			
		||||
	/* drain the answer fifo */
 | 
			
		||||
	while (1) {
 | 
			
		||||
		struct timeval tval = { .tv_usec = 100 };
 | 
			
		||||
		FD_ZERO(&fds);
 | 
			
		||||
		FD_SET(fifos->server, &fds);
 | 
			
		||||
		tval.tv_usec = 100;
 | 
			
		||||
		ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			if (errno == EINTR)
 | 
			
		||||
				continue;
 | 
			
		||||
		if ((ret < 0) && (errno != EINTR)) {
 | 
			
		||||
			log_error("Unable to talk to event daemon");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (ret == 0)
 | 
			
		||||
			break;
 | 
			
		||||
		ret = read(fifos->server, drainbuf, sizeof(drainbuf));
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			if ((errno == EINTR) || (errno == EAGAIN))
 | 
			
		||||
				continue;
 | 
			
		||||
			log_error("Unable to talk to event daemon");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		read(fifos->server, drainbuf, 127);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (bytes < size) {
 | 
			
		||||
@@ -326,7 +311,8 @@ static int _daemon_write(struct dm_event_fifos *fifos,
 | 
			
		||||
			}
 | 
			
		||||
		} while (ret < 1);
 | 
			
		||||
 | 
			
		||||
		ret = write(fifos->client, buf + bytes, size - bytes);
 | 
			
		||||
		ret = write(fifos->client, ((char *) buf) + bytes,
 | 
			
		||||
			    size - bytes);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			if ((errno == EINTR) || (errno == EAGAIN))
 | 
			
		||||
				continue;
 | 
			
		||||
@@ -342,11 +328,14 @@ static int _daemon_write(struct dm_event_fifos *fifos,
 | 
			
		||||
	return bytes == size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int daemon_talk(struct dm_event_fifos *fifos,
 | 
			
		||||
		struct dm_event_daemon_message *msg, int cmd,
 | 
			
		||||
		const char *dso_name, const char *dev_name,
 | 
			
		||||
		enum dm_event_mask evmask, uint32_t timeout)
 | 
			
		||||
static int _daemon_talk(struct dm_event_fifos *fifos,
 | 
			
		||||
			struct dm_event_daemon_message *msg, int cmd,
 | 
			
		||||
			const char *dso_name, const char *dev_name,
 | 
			
		||||
			enum dm_event_mask evmask, uint32_t timeout)
 | 
			
		||||
{
 | 
			
		||||
	const char *dso = dso_name ? dso_name : "";
 | 
			
		||||
	const char *dev = dev_name ? dev_name : "";
 | 
			
		||||
	const char *fmt = "%d:%d %s %s %u %" PRIu32;
 | 
			
		||||
	int msg_size;
 | 
			
		||||
	memset(msg, 0, sizeof(*msg));
 | 
			
		||||
 | 
			
		||||
@@ -354,17 +343,14 @@ int daemon_talk(struct dm_event_fifos *fifos,
 | 
			
		||||
	 * Set command and pack the arguments
 | 
			
		||||
	 * into ASCII message string.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((msg_size =
 | 
			
		||||
	     ((cmd == DM_EVENT_CMD_HELLO) ?
 | 
			
		||||
	      dm_asprintf(&(msg->data), "%d:%d HELLO", getpid(), _sequence_nr) :
 | 
			
		||||
	      dm_asprintf(&(msg->data), "%d:%d %s %s %u %" PRIu32,
 | 
			
		||||
			  getpid(), _sequence_nr,
 | 
			
		||||
			  dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
 | 
			
		||||
	    < 0) {
 | 
			
		||||
	msg->cmd = cmd;
 | 
			
		||||
	if (cmd == DM_EVENT_CMD_HELLO)
 | 
			
		||||
		fmt = "%d:%d HELLO";
 | 
			
		||||
	if ((msg_size = dm_asprintf(&(msg->data), fmt, getpid(), _sequence_nr,
 | 
			
		||||
				    dso, dev, evmask, timeout)) < 0) {
 | 
			
		||||
		log_error("_daemon_talk: message allocation failed");
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
	}
 | 
			
		||||
	msg->cmd = cmd;
 | 
			
		||||
	msg->size = msg_size;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
@@ -374,13 +360,15 @@ int daemon_talk(struct dm_event_fifos *fifos,
 | 
			
		||||
	if (!_daemon_write(fifos, msg)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		dm_free(msg->data);
 | 
			
		||||
		msg->data = NULL;
 | 
			
		||||
		msg->data = 0;
 | 
			
		||||
		return -EIO;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		dm_free(msg->data);
 | 
			
		||||
		msg->data = NULL;
 | 
			
		||||
 | 
			
		||||
		if (msg->data)
 | 
			
		||||
			dm_free(msg->data);
 | 
			
		||||
		msg->data = 0;
 | 
			
		||||
 | 
			
		||||
		if (!_daemon_read(fifos, msg)) {
 | 
			
		||||
			stack;
 | 
			
		||||
@@ -405,13 +393,11 @@ int daemon_talk(struct dm_event_fifos *fifos,
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 1 on success, 0 otherwise
 | 
			
		||||
 */
 | 
			
		||||
static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
 | 
			
		||||
static int _start_daemon(struct dm_event_fifos *fifos)
 | 
			
		||||
{
 | 
			
		||||
	int pid, ret = 0;
 | 
			
		||||
	int status;
 | 
			
		||||
	struct stat statbuf;
 | 
			
		||||
	char default_dmeventd_path[] = DMEVENTD_PATH;
 | 
			
		||||
	char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
 | 
			
		||||
 | 
			
		||||
	if (stat(fifos->client_path, &statbuf))
 | 
			
		||||
		goto start_server;
 | 
			
		||||
@@ -425,32 +411,28 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
 | 
			
		||||
	fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
 | 
			
		||||
	if (fifos->client >= 0) {
 | 
			
		||||
		/* server is running and listening */
 | 
			
		||||
		if (close(fifos->client))
 | 
			
		||||
			log_sys_debug("close", fifos->client_path);
 | 
			
		||||
 | 
			
		||||
		close(fifos->client);
 | 
			
		||||
		return 1;
 | 
			
		||||
	} else if (errno != ENXIO) {
 | 
			
		||||
		/* problem */
 | 
			
		||||
		log_sys_error("open", fifos->client_path);
 | 
			
		||||
 | 
			
		||||
		log_error("%s: Can't open client fifo %s: %s",
 | 
			
		||||
			  __func__, fifos->client_path, strerror(errno));
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      start_server:
 | 
			
		||||
	/* server is not running */
 | 
			
		||||
 | 
			
		||||
	if ((args[0][0] == '/') && stat(args[0], &statbuf)) {
 | 
			
		||||
		log_sys_error("stat", args[0]);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pid = fork();
 | 
			
		||||
 | 
			
		||||
	if (pid < 0)
 | 
			
		||||
		log_sys_error("fork", "");
 | 
			
		||||
		log_error("Unable to fork.");
 | 
			
		||||
 | 
			
		||||
	else if (!pid) {
 | 
			
		||||
		execvp(args[0], args);
 | 
			
		||||
		log_error("Unable to exec dmeventd: %s", strerror(errno));
 | 
			
		||||
		_exit(EXIT_FAILURE);
 | 
			
		||||
		execvp(DMEVENTD_PATH, NULL);
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (waitpid(pid, &status, 0) < 0)
 | 
			
		||||
			log_error("Unable to start dmeventd: %s",
 | 
			
		||||
@@ -464,59 +446,56 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int init_fifos(struct dm_event_fifos *fifos)
 | 
			
		||||
/* Initialize client. */
 | 
			
		||||
static int _init_client(struct dm_event_fifos *fifos)
 | 
			
		||||
{
 | 
			
		||||
	/* FIXME? Is fifo the most suitable method? Why not share
 | 
			
		||||
	   comms/daemon code with something else e.g. multipath? */
 | 
			
		||||
 | 
			
		||||
	/* init fifos */
 | 
			
		||||
	memset(fifos, 0, sizeof(*fifos));
 | 
			
		||||
	fifos->client_path = DM_EVENT_FIFO_CLIENT;
 | 
			
		||||
	fifos->server_path = DM_EVENT_FIFO_SERVER;
 | 
			
		||||
 | 
			
		||||
	if (!_start_daemon(fifos)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Open the fifo used to read from the daemon. */
 | 
			
		||||
	if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
 | 
			
		||||
		log_sys_error("open", fifos->server_path);
 | 
			
		||||
		log_error("%s: open server fifo %s",
 | 
			
		||||
			  __func__, fifos->server_path);
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Lock out anyone else trying to do communication with the daemon. */
 | 
			
		||||
	if (flock(fifos->server, LOCK_EX) < 0) {
 | 
			
		||||
		log_sys_error("flock", fifos->server_path);
 | 
			
		||||
		goto bad;
 | 
			
		||||
		log_error("%s: flock %s", __func__, fifos->server_path);
 | 
			
		||||
		close(fifos->server);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/*	if ((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0) {*/
 | 
			
		||||
	if ((fifos->client = open(fifos->client_path, O_RDWR | O_NONBLOCK)) < 0) {
 | 
			
		||||
		log_sys_error("open", fifos->client_path);
 | 
			
		||||
		goto bad;
 | 
			
		||||
		log_error("%s: Can't open client fifo %s: %s",
 | 
			
		||||
			  __func__, fifos->client_path, strerror(errno));
 | 
			
		||||
		close(fifos->server);
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
bad:
 | 
			
		||||
	if (close(fifos->server))
 | 
			
		||||
		log_sys_debug("close", fifos->server_path);
 | 
			
		||||
	fifos->server = -1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialize client. */
 | 
			
		||||
static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
 | 
			
		||||
static void _dtr_client(struct dm_event_fifos *fifos)
 | 
			
		||||
{
 | 
			
		||||
	if (!_start_daemon(dmeventd_path, fifos))
 | 
			
		||||
		return_0;
 | 
			
		||||
	if (flock(fifos->server, LOCK_UN))
 | 
			
		||||
		log_error("flock unlock %s", fifos->server_path);
 | 
			
		||||
 | 
			
		||||
	return init_fifos(fifos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fini_fifos(struct dm_event_fifos *fifos)
 | 
			
		||||
{
 | 
			
		||||
	if (fifos->client >= 0 && close(fifos->client))
 | 
			
		||||
		log_sys_debug("close", fifos->client_path);
 | 
			
		||||
 | 
			
		||||
	if (fifos->server >= 0) {
 | 
			
		||||
		if (flock(fifos->server, LOCK_UN))
 | 
			
		||||
			log_sys_debug("flock unlock", fifos->server_path);
 | 
			
		||||
 | 
			
		||||
		if (close(fifos->server))
 | 
			
		||||
			log_sys_debug("close", fifos->server_path);
 | 
			
		||||
	}
 | 
			
		||||
	close(fifos->client);
 | 
			
		||||
	close(fifos->server);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get uuid of a device */
 | 
			
		||||
@@ -530,78 +509,62 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (dmevh->uuid) {
 | 
			
		||||
		if (!dm_task_set_uuid(dmt, dmevh->uuid))
 | 
			
		||||
			goto_bad;
 | 
			
		||||
	} else if (dmevh->dev_name) {
 | 
			
		||||
		if (!dm_task_set_name(dmt, dmevh->dev_name))
 | 
			
		||||
			goto_bad;
 | 
			
		||||
	} else if (dmevh->major && dmevh->minor) {
 | 
			
		||||
		if (!dm_task_set_major(dmt, dmevh->major) ||
 | 
			
		||||
		    !dm_task_set_minor(dmt, dmevh->minor))
 | 
			
		||||
			goto_bad;
 | 
			
		||||
	}
 | 
			
		||||
	if (dmevh->uuid)
 | 
			
		||||
		dm_task_set_uuid(dmt, dmevh->uuid);
 | 
			
		||||
	else if (dmevh->dev_name)
 | 
			
		||||
		dm_task_set_name(dmt, dmevh->dev_name);
 | 
			
		||||
	else if (dmevh->major && dmevh->minor) {
 | 
			
		||||
		dm_task_set_major(dmt, dmevh->major);
 | 
			
		||||
		dm_task_set_minor(dmt, dmevh->minor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	/* FIXME Add name or uuid or devno to messages */
 | 
			
		||||
	if (!dm_task_run(dmt)) {
 | 
			
		||||
		log_error("_get_device_info: dm_task_run() failed");
 | 
			
		||||
		goto bad;
 | 
			
		||||
		goto failed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_get_info(dmt, &info)) {
 | 
			
		||||
		log_error("_get_device_info: failed to get info for device");
 | 
			
		||||
		goto bad;
 | 
			
		||||
		goto failed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!info.exists) {
 | 
			
		||||
		log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found",
 | 
			
		||||
			  dmevh->uuid ? : "",
 | 
			
		||||
			  (!dmevh->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
 | 
			
		||||
			  (!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
 | 
			
		||||
			  (!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? dmevh->major : 0,
 | 
			
		||||
			  (!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ":" : "",
 | 
			
		||||
			  (!dmevh->uuid && !dmevh->dev_name && dmevh->minor > 0) ? dmevh->minor : 0,
 | 
			
		||||
			  (!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) && dmevh->minor == 0 ? "0" : "",
 | 
			
		||||
			  (!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ") " : "");
 | 
			
		||||
		goto bad;
 | 
			
		||||
		log_error("_get_device_info: device not found");
 | 
			
		||||
		goto failed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dmt;
 | 
			
		||||
 | 
			
		||||
      bad:
 | 
			
		||||
failed:
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle the event (de)registration call and return negative error codes. */
 | 
			
		||||
static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_message *msg,
 | 
			
		||||
static int _do_event(int cmd, struct dm_event_daemon_message *msg,
 | 
			
		||||
		     const char *dso_name, const char *dev_name,
 | 
			
		||||
		     enum dm_event_mask evmask, uint32_t timeout)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct dm_event_fifos fifos = {
 | 
			
		||||
		.server = -1,
 | 
			
		||||
		.client = -1,
 | 
			
		||||
		/* FIXME Make these either configurable or depend directly on dmeventd_path */
 | 
			
		||||
		.client_path = DM_EVENT_FIFO_CLIENT,
 | 
			
		||||
		.server_path = DM_EVENT_FIFO_SERVER
 | 
			
		||||
	};
 | 
			
		||||
	struct dm_event_fifos fifos;
 | 
			
		||||
 | 
			
		||||
	if (!_init_client(dmeventd_path, &fifos)) {
 | 
			
		||||
	if (!_init_client(&fifos)) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return -ESRCH;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
 | 
			
		||||
	ret = _daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, 0, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
	dm_free(msg->data);
 | 
			
		||||
	if (msg->data)
 | 
			
		||||
		dm_free(msg->data);
 | 
			
		||||
	msg->data = 0;
 | 
			
		||||
 | 
			
		||||
	if (!ret)
 | 
			
		||||
		ret = daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
 | 
			
		||||
		ret = _daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
 | 
			
		||||
 | 
			
		||||
	/* what is the opposite of init? */
 | 
			
		||||
	fini_fifos(&fifos);
 | 
			
		||||
	_dtr_client(&fifos);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -612,21 +575,16 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
 | 
			
		||||
	int ret = 1, err;
 | 
			
		||||
	const char *uuid;
 | 
			
		||||
	struct dm_task *dmt;
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0 };
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0, 0, NULL };
 | 
			
		||||
 | 
			
		||||
	if (!(dmt = _get_device_info(dmevh)))
 | 
			
		||||
		return_0;
 | 
			
		||||
	if (!(dmt = _get_device_info(dmevh))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uuid = dm_task_get_uuid(dmt);
 | 
			
		||||
 | 
			
		||||
	if (!strstr(dmevh->dso, "libdevmapper-event-lvm2thin.so") &&
 | 
			
		||||
	    !strstr(dmevh->dso, "libdevmapper-event-lvm2snapshot.so") &&
 | 
			
		||||
	    !strstr(dmevh->dso, "libdevmapper-event-lvm2mirror.so") &&
 | 
			
		||||
	    !strstr(dmevh->dso, "libdevmapper-event-lvm2raid.so"))
 | 
			
		||||
		log_warn("WARNING: %s: dmeventd plugins are deprecated", dmevh->dso);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
 | 
			
		||||
	if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
 | 
			
		||||
			     dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
 | 
			
		||||
		log_error("%s: event registration failed: %s",
 | 
			
		||||
			  dm_task_get_name(dmt),
 | 
			
		||||
@@ -634,7 +592,8 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dm_free(msg.data);
 | 
			
		||||
	if (msg.data)
 | 
			
		||||
		dm_free(msg.data);
 | 
			
		||||
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
 | 
			
		||||
@@ -646,14 +605,16 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
 | 
			
		||||
	int ret = 1, err;
 | 
			
		||||
	const char *uuid;
 | 
			
		||||
	struct dm_task *dmt;
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0 };
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0, 0, NULL };
 | 
			
		||||
 | 
			
		||||
	if (!(dmt = _get_device_info(dmevh)))
 | 
			
		||||
		return_0;
 | 
			
		||||
	if (!(dmt = _get_device_info(dmevh))) {
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uuid = dm_task_get_uuid(dmt);
 | 
			
		||||
 | 
			
		||||
	if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
 | 
			
		||||
	if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
 | 
			
		||||
			    dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
 | 
			
		||||
		log_error("%s: event deregistration failed: %s",
 | 
			
		||||
			  dm_task_get_name(dmt),
 | 
			
		||||
@@ -661,7 +622,8 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dm_free(msg.data);
 | 
			
		||||
	if (msg.data)
 | 
			
		||||
		dm_free(msg.data);
 | 
			
		||||
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
 | 
			
		||||
@@ -690,23 +652,31 @@ static char *_fetch_string(char **src, const int delimiter)
 | 
			
		||||
static int _parse_message(struct dm_event_daemon_message *msg, char **dso_name,
 | 
			
		||||
			 char **uuid, enum dm_event_mask *evmask)
 | 
			
		||||
{
 | 
			
		||||
	char *id;
 | 
			
		||||
	char *id = NULL;
 | 
			
		||||
	char *p = msg->data;
 | 
			
		||||
 | 
			
		||||
	if ((id = _fetch_string(&p, ' ')) &&
 | 
			
		||||
	    (*dso_name = _fetch_string(&p, ' ')) &&
 | 
			
		||||
	    (*uuid = _fetch_string(&p, ' '))) {
 | 
			
		||||
		*evmask = atoi(p);
 | 
			
		||||
 | 
			
		||||
		dm_free(id);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dm_free(id);
 | 
			
		||||
	if (id)
 | 
			
		||||
		dm_free(id);
 | 
			
		||||
	return -ENOMEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns 0 if handler found; error (-ENOMEM, -ENOENT) otherwise.
 | 
			
		||||
 * dm_event_get_registered_device
 | 
			
		||||
 * @dso_name
 | 
			
		||||
 * @device_path
 | 
			
		||||
 * @mask
 | 
			
		||||
 * @next
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 0 if handler found, error (-ENOMEM, -ENOENT) otherwise
 | 
			
		||||
 */
 | 
			
		||||
int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
 | 
			
		||||
{
 | 
			
		||||
@@ -715,44 +685,36 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
 | 
			
		||||
	char *reply_dso = NULL, *reply_uuid = NULL;
 | 
			
		||||
	enum dm_event_mask reply_mask = 0;
 | 
			
		||||
	struct dm_task *dmt = NULL;
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0 };
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0, 0, NULL };
 | 
			
		||||
 | 
			
		||||
	if (!(dmt = _get_device_info(dmevh))) {
 | 
			
		||||
		log_debug("Device does not exists (uuid=%s, name=%s, %d:%d).",
 | 
			
		||||
			  dmevh->uuid, dmevh->dev_name,
 | 
			
		||||
			  dmevh->major, dmevh->minor);
 | 
			
		||||
		ret = -ENODEV;
 | 
			
		||||
		goto fail;
 | 
			
		||||
		stack;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uuid = dm_task_get_uuid(dmt);
 | 
			
		||||
 | 
			
		||||
	if (_do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
 | 
			
		||||
		      DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
 | 
			
		||||
		      &msg, dmevh->dso, uuid, dmevh->mask, 0)) {
 | 
			
		||||
		log_debug("%s: device not registered.", dm_task_get_name(dmt));
 | 
			
		||||
	if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
 | 
			
		||||
			     DM_EVENT_CMD_GET_REGISTERED_DEVICE,
 | 
			
		||||
			      &msg, dmevh->dso, uuid, dmevh->mask, 0))) {
 | 
			
		||||
		/* FIXME this will probably horribly break if we get
 | 
			
		||||
		   ill-formatted reply */
 | 
			
		||||
		ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
 | 
			
		||||
	} else {
 | 
			
		||||
		ret = -ENOENT;
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* FIXME this will probably horribly break if we get
 | 
			
		||||
	   ill-formatted reply */
 | 
			
		||||
	ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask);
 | 
			
		||||
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
	dmt = NULL;
 | 
			
		||||
 | 
			
		||||
	dm_free(msg.data);
 | 
			
		||||
	msg.data = NULL;
 | 
			
		||||
 | 
			
		||||
	_dm_event_handler_clear_dev_info(dmevh);
 | 
			
		||||
	if (!reply_uuid) {
 | 
			
		||||
		ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */
 | 
			
		||||
		goto fail;
 | 
			
		||||
	if (msg.data) {
 | 
			
		||||
		dm_free(msg.data);
 | 
			
		||||
		msg.data = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh->uuid = dm_strdup(reply_uuid))) {
 | 
			
		||||
	_dm_event_handler_clear_dev_info(dmevh);
 | 
			
		||||
	dmevh->uuid = dm_strdup(reply_uuid);
 | 
			
		||||
	if (!dmevh->uuid) {
 | 
			
		||||
		ret = -ENOMEM;
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
@@ -765,17 +727,18 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
 | 
			
		||||
	dm_event_handler_set_dso(dmevh, reply_dso);
 | 
			
		||||
	dm_event_handler_set_event_mask(dmevh, reply_mask);
 | 
			
		||||
 | 
			
		||||
	dm_free(reply_dso);
 | 
			
		||||
	reply_dso = NULL;
 | 
			
		||||
	if (reply_dso)
 | 
			
		||||
		dm_free(reply_dso);
 | 
			
		||||
	if (reply_uuid)
 | 
			
		||||
		dm_free(reply_uuid);
 | 
			
		||||
 | 
			
		||||
	dm_free(reply_uuid);
 | 
			
		||||
	reply_uuid = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!(dmevh->dev_name = dm_strdup(dm_task_get_name(dmt)))) {
 | 
			
		||||
	dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
 | 
			
		||||
	if (!dmevh->dev_name) {
 | 
			
		||||
		ret = -ENOMEM;
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	if (!dm_task_get_info(dmt, &info)) {
 | 
			
		||||
		ret = -1;
 | 
			
		||||
		goto fail;
 | 
			
		||||
@@ -789,45 +752,17 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
 | 
			
		||||
	return ret;
 | 
			
		||||
 | 
			
		||||
 fail:
 | 
			
		||||
	dm_free(msg.data);
 | 
			
		||||
	dm_free(reply_dso);
 | 
			
		||||
	dm_free(reply_uuid);
 | 
			
		||||
	if (msg.data)
 | 
			
		||||
		dm_free(msg.data);
 | 
			
		||||
	if (reply_dso)
 | 
			
		||||
		dm_free(reply_dso);
 | 
			
		||||
	if (reply_uuid)
 | 
			
		||||
		dm_free(reply_uuid);
 | 
			
		||||
	_dm_event_handler_clear_dev_info(dmevh);
 | 
			
		||||
	if (dmt)
 | 
			
		||||
		dm_task_destroy(dmt);
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * You can (and have to) call this at the stage of the protocol where
 | 
			
		||||
 *     daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0)
 | 
			
		||||
 *
 | 
			
		||||
 * would be normally sent. This call will parse the version reply from
 | 
			
		||||
 * dmeventd, in addition to above call. It is not safe to call this at any
 | 
			
		||||
 * other place in the protocol.
 | 
			
		||||
 *
 | 
			
		||||
 * This is an internal function, not exposed in the public API.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
 | 
			
		||||
	char *p;
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0 };
 | 
			
		||||
 | 
			
		||||
	if (daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0))
 | 
			
		||||
		return 0;
 | 
			
		||||
	p = msg.data;
 | 
			
		||||
	*version = 0;
 | 
			
		||||
 | 
			
		||||
	if (!p || !(p = strchr(p, ' '))) /* Message ID */
 | 
			
		||||
		return 0;
 | 
			
		||||
	if (!(p = strchr(p + 1, ' '))) /* HELLO */
 | 
			
		||||
		return 0;
 | 
			
		||||
	if ((p = strchr(p + 1, ' '))) /* HELLO, once more */
 | 
			
		||||
		*version = atoi(p);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0				/* left out for now */
 | 
			
		||||
 | 
			
		||||
static char *_skip_string(char *src, const int delimiter)
 | 
			
		||||
@@ -840,7 +775,7 @@ static char *_skip_string(char *src, const int delimiter)
 | 
			
		||||
 | 
			
		||||
int dm_event_set_timeout(const char *device_path, uint32_t timeout)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0 };
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0, 0, NULL };
 | 
			
		||||
 | 
			
		||||
	if (!device_exists(device_path))
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
@@ -852,24 +787,22 @@ int dm_event_set_timeout(const char *device_path, uint32_t timeout)
 | 
			
		||||
int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0 };
 | 
			
		||||
	struct dm_event_daemon_message msg = { 0, 0, NULL };
 | 
			
		||||
 | 
			
		||||
	if (!device_exists(device_path))
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	if (!(ret = _do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path,
 | 
			
		||||
			     0, 0))) {
 | 
			
		||||
		char *p = _skip_string(msg.data, ' ');
 | 
			
		||||
		if (!p) {
 | 
			
		||||
			log_error("malformed reply from dmeventd '%s'\n",
 | 
			
		||||
				  msg.data);
 | 
			
		||||
			dm_free(msg.data);
 | 
			
		||||
			return -EIO;
 | 
			
		||||
		}
 | 
			
		||||
		*timeout = atoi(p);
 | 
			
		||||
	}
 | 
			
		||||
	dm_free(msg.data);
 | 
			
		||||
 | 
			
		||||
	if (msg.data)
 | 
			
		||||
		dm_free(msg.data);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of the device-mapper userspace tools.
 | 
			
		||||
 *
 | 
			
		||||
@@ -46,9 +46,7 @@ enum dm_event_mask {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DM_EVENT_ALL_ERRORS DM_EVENT_ERROR_MASK
 | 
			
		||||
#define DM_EVENT_PROTOCOL_VERSION 2
 | 
			
		||||
 | 
			
		||||
struct dm_task;
 | 
			
		||||
struct dm_event_handler;
 | 
			
		||||
 | 
			
		||||
struct dm_event_handler *dm_event_handler_create(void);
 | 
			
		||||
@@ -57,17 +55,12 @@ void dm_event_handler_destroy(struct dm_event_handler *dmevh);
 | 
			
		||||
/*
 | 
			
		||||
 * Path of shared library to handle events.
 | 
			
		||||
 *
 | 
			
		||||
 * All of dmeventd, dso, device_name and uuid strings are duplicated so
 | 
			
		||||
 * you do not need to keep the pointers valid after the call succeeds.
 | 
			
		||||
 * They may return -ENOMEM though.
 | 
			
		||||
 * All of dso, device_name and uuid strings are duplicated, you do not
 | 
			
		||||
 * need to keep the pointers valid after the call succeeds. Thes may
 | 
			
		||||
 * return -ENOMEM though.
 | 
			
		||||
 */
 | 
			
		||||
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Path of dmeventd binary.
 | 
			
		||||
 */
 | 
			
		||||
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Identify the device to monitor by exactly one of device_name, uuid or
 | 
			
		||||
 * device number. String arguments are duplicated, see above.
 | 
			
		||||
@@ -83,7 +76,6 @@ void dm_event_handler_set_timeout(struct dm_event_handler *dmevh, int timeout);
 | 
			
		||||
/*
 | 
			
		||||
 * Specify mask for events to monitor.
 | 
			
		||||
 */
 | 
			
		||||
// FIXME  misuse of bitmask as enum
 | 
			
		||||
void dm_event_handler_set_event_mask(struct dm_event_handler *dmevh,
 | 
			
		||||
				     enum dm_event_mask evmask);
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +85,6 @@ const char *dm_event_handler_get_uuid(const struct dm_event_handler *dmevh);
 | 
			
		||||
int dm_event_handler_get_major(const struct dm_event_handler *dmevh);
 | 
			
		||||
int dm_event_handler_get_minor(const struct dm_event_handler *dmevh);
 | 
			
		||||
int dm_event_handler_get_timeout(const struct dm_event_handler *dmevh);
 | 
			
		||||
// FIXME  misuse of bitmask as enum
 | 
			
		||||
enum dm_event_mask dm_event_handler_get_event_mask(const struct dm_event_handler *dmevh);
 | 
			
		||||
 | 
			
		||||
/* FIXME Review interface (what about this next thing?) */
 | 
			
		||||
@@ -107,7 +98,6 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
 | 
			
		||||
 | 
			
		||||
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
 | 
			
		||||
   detailed descriptions. */
 | 
			
		||||
// FIXME  misuse of bitmask as enum
 | 
			
		||||
void process_event(struct dm_task *dmt, enum dm_event_mask evmask, void **user);
 | 
			
		||||
int register_device(const char *device_name, const char *uuid, int major, int minor, void **user);
 | 
			
		||||
int unregister_device(const char *device_name, const char *uuid, int major,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,8 @@ includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: devmapper-event
 | 
			
		||||
Description: device-mapper event library
 | 
			
		||||
Version: @DM_LIB_PATCHLEVEL@
 | 
			
		||||
Version: @DM_LIB_VERSION@
 | 
			
		||||
Requires: devmapper
 | 
			
		||||
Cflags: -I${includedir}
 | 
			
		||||
Libs: -L${libdir} -ldevmapper-event
 | 
			
		||||
Requires.private: devmapper
 | 
			
		||||
Libs.private: -lpthread -ldl
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2005, 2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
@@ -14,33 +14,9 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
SUBDIRS += lvm2
 | 
			
		||||
SUBDIRS += mirror
 | 
			
		||||
 | 
			
		||||
ifneq ("@MIRRORS@", "none")
 | 
			
		||||
  SUBDIRS += mirror
 | 
			
		||||
endif
 | 
			
		||||
include $(top_srcdir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
ifneq ("@SNAPSHOTS@", "none")
 | 
			
		||||
  SUBDIRS += snapshot
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ("@RAID@", "none")
 | 
			
		||||
  SUBDIRS += raid
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ("@THIN@", "none")
 | 
			
		||||
  SUBDIRS += thin
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),distclean)
 | 
			
		||||
  SUBDIRS = lvm2 mirror snapshot raid thin
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
snapshot: lvm2
 | 
			
		||||
mirror: lvm2
 | 
			
		||||
raid: lvm2
 | 
			
		||||
thin: lvm2
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
dmeventd_lvm2_init
 | 
			
		||||
dmeventd_lvm2_exit
 | 
			
		||||
dmeventd_lvm2_lock
 | 
			
		||||
dmeventd_lvm2_unlock
 | 
			
		||||
dmeventd_lvm2_pool
 | 
			
		||||
dmeventd_lvm2_run
 | 
			
		||||
dmeventd_lvm2_command
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2010-2014 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU General Public License v.2.
 | 
			
		||||
#
 | 
			
		||||
# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
CLDFLAGS += -L$(top_builddir)/tools
 | 
			
		||||
 | 
			
		||||
SOURCES = dmeventd_lvm.c
 | 
			
		||||
 | 
			
		||||
LIB_SHARED = libdevmapper-event-lvm2.$(LIB_SUFFIX)
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_LVM)
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
LIBS += @LVM2CMD_LIB@ -ldevmapper $(PTHREAD_LIBS)
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_lib_shared
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
@@ -1,177 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "lvm2cmd.h"
 | 
			
		||||
#include "dmeventd_lvm.h"
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
extern int dmeventd_debug;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * register_device() is called first and performs initialisation.
 | 
			
		||||
 * Only one device may be registered or unregistered at a time.
 | 
			
		||||
 */
 | 
			
		||||
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Number of active registrations.
 | 
			
		||||
 */
 | 
			
		||||
static int _register_count = 0;
 | 
			
		||||
static struct dm_pool *_mem_pool = NULL;
 | 
			
		||||
static void *_lvm_handle = NULL;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Currently only one event can be processed at a time.
 | 
			
		||||
 */
 | 
			
		||||
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * FIXME Do not pass things directly to syslog, rather use the existing logging
 | 
			
		||||
 * facilities to sort logging ... however that mechanism needs to be somehow
 | 
			
		||||
 * configurable and we don't have that option yet
 | 
			
		||||
 */
 | 
			
		||||
static void _temporary_log_fn(int level,
 | 
			
		||||
			      const char *file __attribute__((unused)),
 | 
			
		||||
			      int line __attribute__((unused)),
 | 
			
		||||
			      int dm_errno __attribute__((unused)),
 | 
			
		||||
			      const char *message)
 | 
			
		||||
{
 | 
			
		||||
	level &= ~(_LOG_STDERR | _LOG_ONCE);
 | 
			
		||||
 | 
			
		||||
	switch (level) {
 | 
			
		||||
	case _LOG_DEBUG:
 | 
			
		||||
		if (dmeventd_debug >= 3)
 | 
			
		||||
			syslog(LOG_DEBUG, "%s", message);
 | 
			
		||||
		break;
 | 
			
		||||
	case _LOG_INFO:
 | 
			
		||||
		if (dmeventd_debug >= 2)
 | 
			
		||||
			syslog(LOG_INFO, "%s", message);
 | 
			
		||||
		break;
 | 
			
		||||
	case _LOG_NOTICE:
 | 
			
		||||
		if (dmeventd_debug >= 1)
 | 
			
		||||
			syslog(LOG_NOTICE, "%s", message);
 | 
			
		||||
		break;
 | 
			
		||||
	case _LOG_WARN:
 | 
			
		||||
		syslog(LOG_WARNING, "%s", message);
 | 
			
		||||
		break;
 | 
			
		||||
	case _LOG_ERR:
 | 
			
		||||
		syslog(LOG_ERR, "%s", message);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		syslog(LOG_CRIT, "%s", message);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmeventd_lvm2_lock(void)
 | 
			
		||||
{
 | 
			
		||||
	pthread_mutex_lock(&_event_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmeventd_lvm2_unlock(void)
 | 
			
		||||
{
 | 
			
		||||
	pthread_mutex_unlock(&_event_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmeventd_lvm2_init(void)
 | 
			
		||||
{
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	pthread_mutex_lock(&_register_mutex);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Need some space for allocations.  1024 should be more
 | 
			
		||||
	 * than enough for what we need (device mapper name splitting)
 | 
			
		||||
	 */
 | 
			
		||||
	if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!_lvm_handle) {
 | 
			
		||||
		if (!getenv("LVM_LOG_FILE_EPOCH"))
 | 
			
		||||
			lvm2_log_fn(_temporary_log_fn);
 | 
			
		||||
		if (!(_lvm_handle = lvm2_init())) {
 | 
			
		||||
			dm_pool_destroy(_mem_pool);
 | 
			
		||||
			_mem_pool = NULL;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		lvm2_disable_dmeventd_monitoring(_lvm_handle);
 | 
			
		||||
		/* FIXME Temporary: move to dmeventd core */
 | 
			
		||||
		lvm2_run(_lvm_handle, "_memlock_inc");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_register_count++;
 | 
			
		||||
	r = 1;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	pthread_mutex_unlock(&_register_mutex);
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dmeventd_lvm2_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	pthread_mutex_lock(&_register_mutex);
 | 
			
		||||
 | 
			
		||||
	if (!--_register_count) {
 | 
			
		||||
		lvm2_run(_lvm_handle, "_memlock_dec");
 | 
			
		||||
		dm_pool_destroy(_mem_pool);
 | 
			
		||||
		_mem_pool = NULL;
 | 
			
		||||
		lvm2_exit(_lvm_handle);
 | 
			
		||||
		_lvm_handle = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pthread_mutex_unlock(&_register_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dm_pool *dmeventd_lvm2_pool(void)
 | 
			
		||||
{
 | 
			
		||||
	return _mem_pool;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmeventd_lvm2_run(const char *cmdline)
 | 
			
		||||
{
 | 
			
		||||
	return (lvm2_run(_lvm_handle, cmdline) == LVM2_COMMAND_SUCCEEDED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
 | 
			
		||||
			  const char *cmd, const char *device)
 | 
			
		||||
{
 | 
			
		||||
	char *vg = NULL, *lv = NULL, *layer;
 | 
			
		||||
	int r;
 | 
			
		||||
 | 
			
		||||
	if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
 | 
			
		||||
		syslog(LOG_ERR, "Unable to determine VG name from %s.\n",
 | 
			
		||||
		       device);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* strip off the mirror component designations */
 | 
			
		||||
	if ((layer = strstr(lv, "_mimagetmp")) ||
 | 
			
		||||
	    (layer = strstr(lv, "_mlog")))
 | 
			
		||||
		*layer = '\0';
 | 
			
		||||
 | 
			
		||||
	r = dm_snprintf(buffer, size, "%s %s/%s", cmd, vg, lv);
 | 
			
		||||
 | 
			
		||||
	dm_pool_free(mem, vg);
 | 
			
		||||
 | 
			
		||||
	if (r < 0) {
 | 
			
		||||
		syslog(LOG_ERR, "Unable to form LVM command. (too long).\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Wrappers around liblvm2cmd functions for dmeventd plug-ins.
 | 
			
		||||
 *
 | 
			
		||||
 * liblvm2cmd is not thread-safe so the locking in this library helps dmeventd
 | 
			
		||||
 * threads to co-operate in sharing a single instance.
 | 
			
		||||
 *
 | 
			
		||||
 * FIXME Either support this properly as a generic liblvm2cmd wrapper or make
 | 
			
		||||
 * liblvm2cmd thread-safe so this can go away.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DMEVENTD_LVMWRAP_H
 | 
			
		||||
#define _DMEVENTD_LVMWRAP_H
 | 
			
		||||
 | 
			
		||||
struct dm_pool;
 | 
			
		||||
 | 
			
		||||
int dmeventd_lvm2_init(void);
 | 
			
		||||
void dmeventd_lvm2_exit(void);
 | 
			
		||||
int dmeventd_lvm2_run(const char *cmdline);
 | 
			
		||||
 | 
			
		||||
void dmeventd_lvm2_lock(void);
 | 
			
		||||
void dmeventd_lvm2_unlock(void);
 | 
			
		||||
 | 
			
		||||
struct dm_pool *dmeventd_lvm2_pool(void);
 | 
			
		||||
 | 
			
		||||
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
 | 
			
		||||
			  const char *cmd, const char *device);
 | 
			
		||||
 | 
			
		||||
#endif /* _DMEVENTD_LVMWRAP_H */
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2005, 2008-2014 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
@@ -14,24 +14,23 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
INCLUDES += -I${top_srcdir}/tools
 | 
			
		||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
 | 
			
		||||
 | 
			
		||||
SOURCES = dmeventd_mirror.c
 | 
			
		||||
 | 
			
		||||
LIB_NAME = libdevmapper-event-lvm2mirror
 | 
			
		||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_LVM)
 | 
			
		||||
ifeq ("@LIB_SUFFIX@","dylib")
 | 
			
		||||
  LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
 | 
			
		||||
else
 | 
			
		||||
  LIB_SHARED = libdevmapper-event-lvm2mirror.so
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
CFLOW_LIST = $(SOURCES)
 | 
			
		||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
 | 
			
		||||
include $(top_srcdir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
 | 
			
		||||
		$(libdir)/$<.$(LIB_VERSION)
 | 
			
		||||
	$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
 | 
			
		||||
 | 
			
		||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_dm_plugin
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2005-2012 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
@@ -12,50 +12,43 @@
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
#include "lvm2cmd.h"
 | 
			
		||||
 | 
			
		||||
#include "libdevmapper-event.h"
 | 
			
		||||
#include "dmeventd_lvm.h"
 | 
			
		||||
#include "defaults.h"
 | 
			
		||||
#include <libdevmapper.h>
 | 
			
		||||
#include <libdevmapper-event.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
 | 
			
		||||
/* FIXME Missing openlog? */
 | 
			
		||||
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
 | 
			
		||||
/* FIXME Reformat to 80 char lines. */
 | 
			
		||||
 | 
			
		||||
#define ME_IGNORE    0
 | 
			
		||||
#define ME_INSYNC    1
 | 
			
		||||
#define ME_FAILURE   2
 | 
			
		||||
 | 
			
		||||
static int _process_status_code(const char status_code, const char *dev_name,
 | 
			
		||||
				const char *dev_type, int r)
 | 
			
		||||
{
 | 
			
		||||
	/*
 | 
			
		||||
	 *    A => Alive - No failures
 | 
			
		||||
	 *    D => Dead - A write failure occurred leaving mirror out-of-sync
 | 
			
		||||
	 *    F => Flush failed.
 | 
			
		||||
	 *    S => Sync - A sychronization failure occurred, mirror out-of-sync
 | 
			
		||||
	 *    R => Read - A read failure occurred, mirror data unaffected
 | 
			
		||||
	 *    U => Unclassified failure (bug)
 | 
			
		||||
	 */ 
 | 
			
		||||
	if (status_code == 'F') {
 | 
			
		||||
		syslog(LOG_ERR, "%s device %s flush failed.",
 | 
			
		||||
		       dev_type, dev_name);
 | 
			
		||||
		r = ME_FAILURE;
 | 
			
		||||
	} else if (status_code == 'S')
 | 
			
		||||
		syslog(LOG_ERR, "%s device %s sync failed.",
 | 
			
		||||
		       dev_type, dev_name);
 | 
			
		||||
	else if (status_code == 'R')
 | 
			
		||||
		syslog(LOG_ERR, "%s device %s read failed.",
 | 
			
		||||
		       dev_type, dev_name);
 | 
			
		||||
	else if (status_code != 'A') {
 | 
			
		||||
		syslog(LOG_ERR, "%s device %s has failed (%c).",
 | 
			
		||||
		       dev_type, dev_name, status_code);
 | 
			
		||||
		r = ME_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
/*
 | 
			
		||||
 * register_device() is called first and performs initialisation.
 | 
			
		||||
 * Only one device may be registered or unregistered at a time.
 | 
			
		||||
 */
 | 
			
		||||
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * Number of active registrations.
 | 
			
		||||
 */
 | 
			
		||||
static int _register_count = 0;
 | 
			
		||||
 | 
			
		||||
static struct dm_pool *_mem_pool = NULL;
 | 
			
		||||
static void *_lvm_handle = NULL;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Currently only one event can be processed at a time.
 | 
			
		||||
 */
 | 
			
		||||
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
static int _get_mirror_event(char *params)
 | 
			
		||||
{
 | 
			
		||||
@@ -80,8 +73,7 @@ static int _get_mirror_event(char *params)
 | 
			
		||||
	if (!dm_split_words(params, 1, 0, &p))
 | 
			
		||||
		goto out_parse;
 | 
			
		||||
 | 
			
		||||
	if (!(num_devs = atoi(p)) ||
 | 
			
		||||
	    (num_devs > DEFAULT_MIRROR_MAX_IMAGES) || (num_devs < 0))
 | 
			
		||||
	if (!(num_devs = atoi(p)))
 | 
			
		||||
		goto out_parse;
 | 
			
		||||
	p += strlen(p) + 1;
 | 
			
		||||
 | 
			
		||||
@@ -90,7 +82,6 @@ static int _get_mirror_event(char *params)
 | 
			
		||||
	if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
 | 
			
		||||
		goto out_parse;
 | 
			
		||||
 | 
			
		||||
	/* FIXME: Code differs from lib/mirror/mirrored.c */
 | 
			
		||||
	dev_status_str = args[2 + num_devs];
 | 
			
		||||
	log_argc = atoi(args[3 + num_devs]);
 | 
			
		||||
	log_status_str = args[3 + num_devs + log_argc];
 | 
			
		||||
@@ -98,14 +89,17 @@ static int _get_mirror_event(char *params)
 | 
			
		||||
 | 
			
		||||
	/* Check for bad mirror devices */
 | 
			
		||||
	for (i = 0; i < num_devs; i++)
 | 
			
		||||
		r = _process_status_code(dev_status_str[i], args[i],
 | 
			
		||||
			i ? "Secondary mirror" : "Primary mirror", r);
 | 
			
		||||
		if (dev_status_str[i] == 'D') {
 | 
			
		||||
			syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i]);
 | 
			
		||||
			r = ME_FAILURE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	/* Check for bad disk log device */
 | 
			
		||||
	if (log_argc > 1)
 | 
			
		||||
		r = _process_status_code(log_status_str[0],
 | 
			
		||||
					 args[2 + num_devs + log_argc],
 | 
			
		||||
					 "Log", r);
 | 
			
		||||
	if (log_argc > 1 && log_status_str[0] == 'D') {
 | 
			
		||||
		syslog(LOG_ERR, "Log device, %s, has failed.\n",
 | 
			
		||||
		       args[2 + num_devs + log_argc]);
 | 
			
		||||
		r = ME_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (r == ME_FAILURE)
 | 
			
		||||
		goto out;
 | 
			
		||||
@@ -120,47 +114,58 @@ static int _get_mirror_event(char *params)
 | 
			
		||||
		goto out_parse;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	dm_free(args);
 | 
			
		||||
	if (args)
 | 
			
		||||
		dm_free(args);
 | 
			
		||||
	return r;
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
out_parse:
 | 
			
		||||
	dm_free(args);
 | 
			
		||||
	if (args)
 | 
			
		||||
		dm_free(args);
 | 
			
		||||
	syslog(LOG_ERR, "Unable to parse mirror status string.");
 | 
			
		||||
	return ME_IGNORE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _temporary_log_fn(int level, const char *file,
 | 
			
		||||
			      int line, const char *format)
 | 
			
		||||
{
 | 
			
		||||
	if (!strncmp(format, "WARNING: ", 9) && (level < 5))
 | 
			
		||||
		syslog(LOG_CRIT, "%s", format);
 | 
			
		||||
	else
 | 
			
		||||
		syslog(LOG_DEBUG, "%s", format);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _remove_failed_devices(const char *device)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
#define CMD_SIZE 256	/* FIXME Use system restriction */
 | 
			
		||||
	char cmd_str[CMD_SIZE];
 | 
			
		||||
	char *vg = NULL, *lv = NULL, *layer = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
 | 
			
		||||
				   "lvscan --cache", device))
 | 
			
		||||
		return -1;
 | 
			
		||||
	if (strlen(device) > 200)  /* FIXME Use real restriction */
 | 
			
		||||
		return -ENAMETOOLONG;	/* FIXME These return code distinctions are not used so remove them! */
 | 
			
		||||
 | 
			
		||||
	r = dmeventd_lvm2_run(cmd_str);
 | 
			
		||||
	if (!dm_split_lvm_name(_mem_pool, device, &vg, &lv, &layer)) {
 | 
			
		||||
		syslog(LOG_ERR, "Unable to determine VG name from %s",
 | 
			
		||||
		       device);
 | 
			
		||||
		return -ENOMEM;	/* FIXME Replace with generic error return - reason for failure has already got logged */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!r)
 | 
			
		||||
		syslog(LOG_INFO, "Re-scan of mirror device %s failed.", device);
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
 | 
			
		||||
				  "lvconvert --config devices{ignore_suspended_devices=1} "
 | 
			
		||||
				  "--repair --use-policies", device))
 | 
			
		||||
	/* FIXME Is any sanity-checking required on %s? */
 | 
			
		||||
	if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing %s", vg)) {
 | 
			
		||||
		/* this error should be caught above, but doesn't hurt to check again */
 | 
			
		||||
		syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
 | 
			
		||||
		dm_pool_empty(_mem_pool);  /* FIXME: not safe with multiple threads */
 | 
			
		||||
		return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* if repair goes OK, report success even if lvscan has failed */
 | 
			
		||||
	r = dmeventd_lvm2_run(cmd_str);
 | 
			
		||||
	r = lvm2_run(_lvm_handle, cmd_str);
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "Repair of mirrored device %s %s.", device,
 | 
			
		||||
	       (r) ? "finished successfully" : "failed");
 | 
			
		||||
 | 
			
		||||
	return (r) ? 0 : -1;
 | 
			
		||||
	dm_pool_empty(_mem_pool);  /* FIXME: not safe with multiple threads */
 | 
			
		||||
	return (r == 1) ? 0 : -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void process_event(struct dm_task *dmt,
 | 
			
		||||
		   enum dm_event_mask event __attribute__((unused)),
 | 
			
		||||
		   void **unused __attribute__((unused)))
 | 
			
		||||
void process_event(struct dm_task *dmt, enum dm_event_mask event,
 | 
			
		||||
		   void **unused __attribute((unused)))
 | 
			
		||||
{
 | 
			
		||||
	void *next = NULL;
 | 
			
		||||
	uint64_t start, length;
 | 
			
		||||
@@ -168,19 +173,21 @@ void process_event(struct dm_task *dmt,
 | 
			
		||||
	char *params;
 | 
			
		||||
	const char *device = dm_task_get_name(dmt);
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_lock();
 | 
			
		||||
 | 
			
		||||
	if (pthread_mutex_trylock(&_event_mutex)) {
 | 
			
		||||
		syslog(LOG_NOTICE, "Another thread is handling an event.  Waiting...");
 | 
			
		||||
		pthread_mutex_lock(&_event_mutex);
 | 
			
		||||
	}
 | 
			
		||||
	do {
 | 
			
		||||
		next = dm_get_next_target(dmt, next, &start, &length,
 | 
			
		||||
					  &target_type, ¶ms);
 | 
			
		||||
 | 
			
		||||
		if (!target_type) {
 | 
			
		||||
			syslog(LOG_INFO, "%s mapping lost.", device);
 | 
			
		||||
			syslog(LOG_INFO, "%s mapping lost.\n", device);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (strcmp(target_type, "mirror")) {
 | 
			
		||||
			syslog(LOG_INFO, "%s has unmirrored portion.", device);
 | 
			
		||||
			syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -190,13 +197,13 @@ void process_event(struct dm_task *dmt,
 | 
			
		||||
			   _part_ of the device is in sync
 | 
			
		||||
			   Also, this is not an error
 | 
			
		||||
			*/
 | 
			
		||||
			syslog(LOG_NOTICE, "%s is now in-sync.", device);
 | 
			
		||||
			syslog(LOG_NOTICE, "%s is now in-sync\n", device);
 | 
			
		||||
			break;
 | 
			
		||||
		case ME_FAILURE:
 | 
			
		||||
			syslog(LOG_ERR, "Device failure in %s.", device);
 | 
			
		||||
			syslog(LOG_ERR, "Device failure in %s\n", device);
 | 
			
		||||
			if (_remove_failed_devices(device))
 | 
			
		||||
				/* FIXME Why are all the error return codes unused? Get rid of them? */
 | 
			
		||||
				syslog(LOG_ERR, "Failed to remove faulty devices in %s.",
 | 
			
		||||
				syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
 | 
			
		||||
				       device);
 | 
			
		||||
			/* Should check before warning user that device is now linear
 | 
			
		||||
			else
 | 
			
		||||
@@ -208,36 +215,67 @@ void process_event(struct dm_task *dmt,
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* FIXME Provide value then! */
 | 
			
		||||
			syslog(LOG_INFO, "Unknown event received.");
 | 
			
		||||
			syslog(LOG_INFO, "Unknown event received.\n");
 | 
			
		||||
		}
 | 
			
		||||
	} while (next);
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_unlock();
 | 
			
		||||
	pthread_mutex_unlock(&_event_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int register_device(const char *device,
 | 
			
		||||
		    const char *uuid __attribute__((unused)),
 | 
			
		||||
		    int major __attribute__((unused)),
 | 
			
		||||
		    int minor __attribute__((unused)),
 | 
			
		||||
		    void **unused __attribute__((unused)))
 | 
			
		||||
int register_device(const char *device, const char *uuid, int major, int minor,
 | 
			
		||||
		   void **unused __attribute((unused)))
 | 
			
		||||
{
 | 
			
		||||
	if (!dmeventd_lvm2_init())
 | 
			
		||||
		return 0;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "Monitoring mirror device %s for events.", device);
 | 
			
		||||
	pthread_mutex_lock(&_register_mutex);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
	syslog(LOG_INFO, "Monitoring mirror device %s for events\n", device);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Need some space for allocations.  1024 should be more
 | 
			
		||||
	 * than enough for what we need (device mapper name splitting)
 | 
			
		||||
	 */
 | 
			
		||||
	if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!_lvm_handle) {
 | 
			
		||||
		lvm2_log_fn(_temporary_log_fn);
 | 
			
		||||
		if (!(_lvm_handle = lvm2_init())) {
 | 
			
		||||
			dm_pool_destroy(_mem_pool);
 | 
			
		||||
			_mem_pool = NULL;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
 | 
			
		||||
		/* FIXME Temporary: move to dmeventd core */
 | 
			
		||||
		lvm2_run(_lvm_handle, "_memlock_inc");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_register_count++;
 | 
			
		||||
	r = 1;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	pthread_mutex_unlock(&_register_mutex);
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int unregister_device(const char *device,
 | 
			
		||||
		      const char *uuid __attribute__((unused)),
 | 
			
		||||
		      int major __attribute__((unused)),
 | 
			
		||||
		      int minor __attribute__((unused)),
 | 
			
		||||
		      void **unused __attribute__((unused)))
 | 
			
		||||
int unregister_device(const char *device, const char *uuid, int major, int minor,
 | 
			
		||||
		   void **unused __attribute((unused)))
 | 
			
		||||
{
 | 
			
		||||
	syslog(LOG_INFO, "No longer monitoring mirror device %s for events.",
 | 
			
		||||
	pthread_mutex_lock(&_register_mutex);
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "No longer monitoring mirror device %s for events\n",
 | 
			
		||||
	       device);
 | 
			
		||||
	dmeventd_lvm2_exit();
 | 
			
		||||
 | 
			
		||||
	if (!--_register_count) {
 | 
			
		||||
		dm_pool_destroy(_mem_pool);
 | 
			
		||||
		_mem_pool = NULL;
 | 
			
		||||
		lvm2_run(_lvm_handle, "_memlock_dec");
 | 
			
		||||
		lvm2_exit(_lvm_handle);
 | 
			
		||||
		_lvm_handle = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pthread_mutex_unlock(&_register_mutex);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU General Public License v.2.
 | 
			
		||||
#
 | 
			
		||||
# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
 | 
			
		||||
SOURCES = dmeventd_raid.c
 | 
			
		||||
 | 
			
		||||
LIB_NAME = libdevmapper-event-lvm2raid
 | 
			
		||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_LVM)
 | 
			
		||||
 | 
			
		||||
CFLOW_LIST = $(SOURCES)
 | 
			
		||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_dm_plugin
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
@@ -1,180 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
 | 
			
		||||
#include "libdevmapper-event.h"
 | 
			
		||||
#include "dmeventd_lvm.h"
 | 
			
		||||
 | 
			
		||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
 | 
			
		||||
/* FIXME Missing openlog? */
 | 
			
		||||
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
 | 
			
		||||
/* FIXME Reformat to 80 char lines. */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * run_repair is a close copy to
 | 
			
		||||
 * plugins/mirror/dmeventd_mirror.c:_remove_failed_devices()
 | 
			
		||||
 */
 | 
			
		||||
static int run_repair(const char *device)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
#define CMD_SIZE 256	/* FIXME Use system restriction */
 | 
			
		||||
	char cmd_str[CMD_SIZE];
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
 | 
			
		||||
				  "lvscan --cache", device))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	r = dmeventd_lvm2_run(cmd_str);
 | 
			
		||||
 | 
			
		||||
	if (!r)
 | 
			
		||||
		syslog(LOG_INFO, "Re-scan of RAID device %s failed.", device);
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
 | 
			
		||||
				  "lvconvert --config devices{ignore_suspended_devices=1} "
 | 
			
		||||
				  "--repair --use-policies", device))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	/* if repair goes OK, report success even if lvscan has failed */
 | 
			
		||||
	r = dmeventd_lvm2_run(cmd_str);
 | 
			
		||||
 | 
			
		||||
	if (!r)
 | 
			
		||||
		syslog(LOG_INFO, "Repair of RAID device %s failed.", device);
 | 
			
		||||
 | 
			
		||||
	return (r) ? 0 : -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _process_raid_event(char *params, const char *device)
 | 
			
		||||
{
 | 
			
		||||
	int i, n, failure = 0;
 | 
			
		||||
	char *p, *a[4];
 | 
			
		||||
	char *raid_type;
 | 
			
		||||
	char *num_devices;
 | 
			
		||||
	char *health_chars;
 | 
			
		||||
	char *resync_ratio;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * RAID parms:     <raid_type> <#raid_disks> \
 | 
			
		||||
	 *                 <health chars> <resync ratio>
 | 
			
		||||
	 */
 | 
			
		||||
	if (!dm_split_words(params, 4, 0, a)) {
 | 
			
		||||
		syslog(LOG_ERR, "Failed to process status line for %s\n",
 | 
			
		||||
		       device);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	raid_type = a[0];
 | 
			
		||||
	num_devices = a[1];
 | 
			
		||||
	health_chars = a[2];
 | 
			
		||||
	resync_ratio = a[3];
 | 
			
		||||
 | 
			
		||||
	if (!(n = atoi(num_devices))) {
 | 
			
		||||
		syslog(LOG_ERR, "Failed to parse number of devices for %s: %s",
 | 
			
		||||
		       device, num_devices);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < n; i++) {
 | 
			
		||||
		switch (health_chars[i]) {
 | 
			
		||||
		case 'A':
 | 
			
		||||
			/* Device is 'A'live and well */
 | 
			
		||||
		case 'a':
 | 
			
		||||
			/* Device is 'a'live, but not yet in-sync */
 | 
			
		||||
			break;
 | 
			
		||||
		case 'D':
 | 
			
		||||
			syslog(LOG_ERR,
 | 
			
		||||
			       "Device #%d of %s array, %s, has failed.",
 | 
			
		||||
			       i, raid_type, device);
 | 
			
		||||
			failure++;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* Unhandled character returned from kernel */
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if (failure)
 | 
			
		||||
			return run_repair(device);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p = strstr(resync_ratio, "/");
 | 
			
		||||
	if (!p) {
 | 
			
		||||
		syslog(LOG_ERR, "Failed to parse resync_ratio for %s: %s",
 | 
			
		||||
		       device, resync_ratio);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	p[0] = '\0';
 | 
			
		||||
	syslog(LOG_INFO, "%s array, %s, is %s in-sync.",
 | 
			
		||||
	       raid_type, device, strcmp(resync_ratio, p+1) ? "not" : "now");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void process_event(struct dm_task *dmt,
 | 
			
		||||
		   enum dm_event_mask event __attribute__((unused)),
 | 
			
		||||
		   void **unused __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	void *next = NULL;
 | 
			
		||||
	uint64_t start, length;
 | 
			
		||||
	char *target_type = NULL;
 | 
			
		||||
	char *params;
 | 
			
		||||
	const char *device = dm_task_get_name(dmt);
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_lock();
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		next = dm_get_next_target(dmt, next, &start, &length,
 | 
			
		||||
					  &target_type, ¶ms);
 | 
			
		||||
 | 
			
		||||
		if (!target_type) {
 | 
			
		||||
			syslog(LOG_INFO, "%s mapping lost.", device);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (strcmp(target_type, "raid")) {
 | 
			
		||||
			syslog(LOG_INFO, "%s has non-raid portion.", device);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (_process_raid_event(params, device))
 | 
			
		||||
			syslog(LOG_ERR, "Failed to process event for %s",
 | 
			
		||||
			       device);
 | 
			
		||||
	} while (next);
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int register_device(const char *device,
 | 
			
		||||
		    const char *uuid __attribute__((unused)),
 | 
			
		||||
		    int major __attribute__((unused)),
 | 
			
		||||
		    int minor __attribute__((unused)),
 | 
			
		||||
		    void **unused __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	if (!dmeventd_lvm2_init())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "Monitoring RAID device %s for events.", device);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int unregister_device(const char *device,
 | 
			
		||||
		      const char *uuid __attribute__((unused)),
 | 
			
		||||
		      int major __attribute__((unused)),
 | 
			
		||||
		      int minor __attribute__((unused)),
 | 
			
		||||
		      void **unused __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
	syslog(LOG_INFO, "No longer monitoring RAID device %s for events.",
 | 
			
		||||
	       device);
 | 
			
		||||
	dmeventd_lvm2_exit();
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
process_event
 | 
			
		||||
register_device
 | 
			
		||||
unregister_device
 | 
			
		||||
@@ -1,247 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007-2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
 | 
			
		||||
#include "libdevmapper-event.h"
 | 
			
		||||
#include "dmeventd_lvm.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
/* FIXME Missing openlog? */
 | 
			
		||||
 | 
			
		||||
/* First warning when snapshot is 80% full. */
 | 
			
		||||
#define WARNING_THRESH 80
 | 
			
		||||
/* Run a check every 5%. */
 | 
			
		||||
#define CHECK_STEP 5
 | 
			
		||||
/* Do not bother checking snapshots less than 50% full. */
 | 
			
		||||
#define CHECK_MINIMUM 50
 | 
			
		||||
 | 
			
		||||
#define UMOUNT_COMMAND "/bin/umount"
 | 
			
		||||
 | 
			
		||||
struct dso_state {
 | 
			
		||||
	struct dm_pool *mem;
 | 
			
		||||
	int percent_check;
 | 
			
		||||
	uint64_t known_size;
 | 
			
		||||
	char cmd_str[1024];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int _run(const char *cmd, ...)
 | 
			
		||||
{
 | 
			
		||||
        va_list ap;
 | 
			
		||||
        int argc = 1; /* for argv[0], i.e. cmd */
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        const char **argv;
 | 
			
		||||
        pid_t pid = fork();
 | 
			
		||||
        int status;
 | 
			
		||||
 | 
			
		||||
        if (pid == 0) { /* child */
 | 
			
		||||
                va_start(ap, cmd);
 | 
			
		||||
                while (va_arg(ap, const char *))
 | 
			
		||||
                        ++ argc;
 | 
			
		||||
                va_end(ap);
 | 
			
		||||
 | 
			
		||||
                /* + 1 for the terminating NULL */
 | 
			
		||||
                argv = alloca(sizeof(const char *) * (argc + 1));
 | 
			
		||||
 | 
			
		||||
                argv[0] = cmd;
 | 
			
		||||
                va_start(ap, cmd);
 | 
			
		||||
                while ((argv[++i] = va_arg(ap, const char *)));
 | 
			
		||||
                va_end(ap);
 | 
			
		||||
 | 
			
		||||
                execvp(cmd, (char **)argv);
 | 
			
		||||
                syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
 | 
			
		||||
                exit(127);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pid > 0) { /* parent */
 | 
			
		||||
                if (waitpid(pid, &status, 0) != pid)
 | 
			
		||||
                        return 0; /* waitpid failed */
 | 
			
		||||
                if (!WIFEXITED(status) || WEXITSTATUS(status))
 | 
			
		||||
                        return 0; /* the child failed */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pid < 0)
 | 
			
		||||
                return 0; /* fork failed */
 | 
			
		||||
 | 
			
		||||
        return 1; /* all good */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _extend(const char *cmd)
 | 
			
		||||
{
 | 
			
		||||
	return dmeventd_lvm2_run(cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _umount(const char *device, int major, int minor)
 | 
			
		||||
{
 | 
			
		||||
	FILE *mounts;
 | 
			
		||||
	char buffer[4096];
 | 
			
		||||
	char *words[3];
 | 
			
		||||
	struct stat st;
 | 
			
		||||
 | 
			
		||||
	if (!(mounts = fopen("/proc/mounts", "r"))) {
 | 
			
		||||
		syslog(LOG_ERR, "Could not read /proc/mounts. Not umounting %s.\n", device);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (!feof(mounts)) {
 | 
			
		||||
		/* read a line of /proc/mounts */
 | 
			
		||||
		if (!fgets(buffer, sizeof(buffer), mounts))
 | 
			
		||||
			break; /* eof, likely */
 | 
			
		||||
 | 
			
		||||
		/* words[0] is the mount point and words[1] is the device path */
 | 
			
		||||
		if (dm_split_words(buffer, 3, 0, words) < 2)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* find the major/minor of the device */
 | 
			
		||||
		if (stat(words[0], &st))
 | 
			
		||||
			continue; /* can't stat, skip this one */
 | 
			
		||||
 | 
			
		||||
		if (S_ISBLK(st.st_mode) &&
 | 
			
		||||
		    major(st.st_rdev) == major &&
 | 
			
		||||
		    minor(st.st_rdev) == minor) {
 | 
			
		||||
			syslog(LOG_ERR, "Unmounting invalid snapshot %s from %s.\n", device, words[1]);
 | 
			
		||||
                        if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
 | 
			
		||||
                                syslog(LOG_ERR, "Failed to umount snapshot %s from %s: %s.\n",
 | 
			
		||||
                                       device, words[1], strerror(errno));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (fclose(mounts))
 | 
			
		||||
		syslog(LOG_ERR, "Failed to close /proc/mounts.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void process_event(struct dm_task *dmt,
 | 
			
		||||
		   enum dm_event_mask event __attribute__((unused)),
 | 
			
		||||
		   void **private)
 | 
			
		||||
{
 | 
			
		||||
	void *next = NULL;
 | 
			
		||||
	uint64_t start, length;
 | 
			
		||||
	char *target_type = NULL;
 | 
			
		||||
	char *params;
 | 
			
		||||
	struct dm_status_snapshot *status = NULL;
 | 
			
		||||
	const char *device = dm_task_get_name(dmt);
 | 
			
		||||
	int percent;
 | 
			
		||||
	struct dso_state *state = *private;
 | 
			
		||||
 | 
			
		||||
	/* No longer monitoring, waiting for remove */
 | 
			
		||||
	if (!state->percent_check)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_lock();
 | 
			
		||||
 | 
			
		||||
	dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
 | 
			
		||||
	if (!target_type)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!dm_get_status_snapshot(state->mem, params, &status))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (status->invalid) {
 | 
			
		||||
		struct dm_info info;
 | 
			
		||||
		if (dm_task_get_info(dmt, &info)) {
 | 
			
		||||
			dmeventd_lvm2_unlock();
 | 
			
		||||
			_umount(device, info.major, info.minor);
 | 
			
		||||
			return;
 | 
			
		||||
		} /* else; too bad, but this is best-effort thing... */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Snapshot size had changed. Clear the threshold. */
 | 
			
		||||
	if (state->known_size != status->total_sectors) {
 | 
			
		||||
		state->percent_check = CHECK_MINIMUM;
 | 
			
		||||
		state->known_size = status->total_sectors;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If the snapshot has been invalidated or we failed to parse
 | 
			
		||||
	 * the status string. Report the full status string to syslog.
 | 
			
		||||
	 */
 | 
			
		||||
	if (status->invalid || !status->total_sectors) {
 | 
			
		||||
		syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
 | 
			
		||||
		state->percent_check = 0;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	percent = (int) (100 * status->used_sectors / status->total_sectors);
 | 
			
		||||
	if (percent >= state->percent_check) {
 | 
			
		||||
		/* Usage has raised more than CHECK_STEP since the last
 | 
			
		||||
		   time. Run actions. */
 | 
			
		||||
		state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
 | 
			
		||||
 | 
			
		||||
		if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
 | 
			
		||||
			syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
 | 
			
		||||
		/* Try to extend the snapshot, in accord with user-set policies */
 | 
			
		||||
		if (!_extend(state->cmd_str))
 | 
			
		||||
			syslog(LOG_ERR, "Failed to extend snapshot %s.\n", device);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	if (status)
 | 
			
		||||
		dm_pool_free(state->mem, status);
 | 
			
		||||
	dmeventd_lvm2_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int register_device(const char *device,
 | 
			
		||||
		    const char *uuid __attribute__((unused)),
 | 
			
		||||
		    int major __attribute__((unused)),
 | 
			
		||||
		    int minor __attribute__((unused)),
 | 
			
		||||
		    void **private)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_pool *statemem = NULL;
 | 
			
		||||
	struct dso_state *state;
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_init())
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!(statemem = dm_pool_create("snapshot_state", 512)) ||
 | 
			
		||||
	    !(state = dm_pool_zalloc(statemem, sizeof(*state))))
 | 
			
		||||
		goto bad;
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_command(statemem, state->cmd_str,
 | 
			
		||||
				   sizeof(state->cmd_str),
 | 
			
		||||
				   "lvextend --use-policies", device))
 | 
			
		||||
		goto bad;
 | 
			
		||||
 | 
			
		||||
	state->mem = statemem;
 | 
			
		||||
	state->percent_check = CHECK_MINIMUM;
 | 
			
		||||
	*private = state;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
bad:
 | 
			
		||||
	if (statemem)
 | 
			
		||||
		dm_pool_destroy(statemem);
 | 
			
		||||
	dmeventd_lvm2_exit();
 | 
			
		||||
out:
 | 
			
		||||
	syslog(LOG_ERR, "Failed to monitor snapshot %s.\n", device);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int unregister_device(const char *device,
 | 
			
		||||
		      const char *uuid __attribute__((unused)),
 | 
			
		||||
		      int major __attribute__((unused)),
 | 
			
		||||
		      int minor __attribute__((unused)),
 | 
			
		||||
		      void **private)
 | 
			
		||||
{
 | 
			
		||||
	struct dso_state *state = *private;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "No longer monitoring snapshot %s\n", device);
 | 
			
		||||
	dm_pool_destroy(state->mem);
 | 
			
		||||
	dmeventd_lvm2_exit();
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
process_event
 | 
			
		||||
register_device
 | 
			
		||||
unregister_device
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU General Public License v.2.
 | 
			
		||||
#
 | 
			
		||||
# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
 | 
			
		||||
SOURCES = dmeventd_thin.c
 | 
			
		||||
 | 
			
		||||
LIB_NAME = libdevmapper-event-lvm2thin
 | 
			
		||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_LVM)
 | 
			
		||||
 | 
			
		||||
CFLOW_LIST = $(SOURCES)
 | 
			
		||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_dm_plugin
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
@@ -1,401 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib.h"
 | 
			
		||||
 | 
			
		||||
#include "libdevmapper-event.h"
 | 
			
		||||
#include "dmeventd_lvm.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <syslog.h> /* FIXME Replace syslog with multilog */
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
/* FIXME Missing openlog? */
 | 
			
		||||
 | 
			
		||||
/* First warning when thin is 80% full. */
 | 
			
		||||
#define WARNING_THRESH 80
 | 
			
		||||
/* Run a check every 5%. */
 | 
			
		||||
#define CHECK_STEP 5
 | 
			
		||||
/* Do not bother checking thins less than 50% full. */
 | 
			
		||||
#define CHECK_MINIMUM 50
 | 
			
		||||
 | 
			
		||||
#define UMOUNT_COMMAND "/bin/umount"
 | 
			
		||||
 | 
			
		||||
#define THIN_DEBUG 0
 | 
			
		||||
 | 
			
		||||
struct dso_state {
 | 
			
		||||
	struct dm_pool *mem;
 | 
			
		||||
	int metadata_percent_check;
 | 
			
		||||
	int data_percent_check;
 | 
			
		||||
	uint64_t known_metadata_size;
 | 
			
		||||
	uint64_t known_data_size;
 | 
			
		||||
	char cmd_str[1024];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* TODO - move this mountinfo code into library to be reusable */
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#  include "kdev_t.h"
 | 
			
		||||
#else
 | 
			
		||||
#  define MAJOR(x) major((x))
 | 
			
		||||
#  define MINOR(x) minor((x))
 | 
			
		||||
#  define MKDEV(x,y) makedev((x),(y))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Get dependencies for device, and try to find matching device */
 | 
			
		||||
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_task *dmt;
 | 
			
		||||
	const struct dm_deps *deps;
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	int major, minor;
 | 
			
		||||
	int r = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_set_name(dmt, name))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_no_open_count(dmt))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_run(dmt))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_get_info(dmt, &info))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!(deps = dm_task_get_deps(dmt)))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (!info.exists || deps->count != 1)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	major = (int) MAJOR(deps->device[0]);
 | 
			
		||||
	minor = (int) MINOR(deps->device[0]);
 | 
			
		||||
	if ((major != tp_major) || (minor != tp_minor))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	*dev_minor = info.minor;
 | 
			
		||||
 | 
			
		||||
#if THIN_DEBUG
 | 
			
		||||
	{
 | 
			
		||||
		char dev_name[PATH_MAX];
 | 
			
		||||
		if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
 | 
			
		||||
			syslog(LOG_DEBUG, "Found %s (%u:%u) depends on %s",
 | 
			
		||||
			       name, major, *dev_minor, dev_name);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	r = 1;
 | 
			
		||||
out:
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get all active devices */
 | 
			
		||||
static int _find_all_devs(dm_bitset_t bs, int tp_major, int tp_minor)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_task *dmt;
 | 
			
		||||
	struct dm_names *names;
 | 
			
		||||
	unsigned next = 0;
 | 
			
		||||
	int minor, r = 1;
 | 
			
		||||
 | 
			
		||||
	if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_run(dmt)) {
 | 
			
		||||
		r = 0;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(names = dm_task_get_names(dmt))) {
 | 
			
		||||
		r = 0;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!names->dev)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		names = (struct dm_names *)((char *) names + next);
 | 
			
		||||
		if (_has_deps(names->name, tp_major, tp_minor, &minor))
 | 
			
		||||
			dm_bit_set(bs, minor);
 | 
			
		||||
		next = names->next;
 | 
			
		||||
	} while (next);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	dm_task_destroy(dmt);
 | 
			
		||||
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _extend(struct dso_state *state)
 | 
			
		||||
{
 | 
			
		||||
#if THIN_DEBUG
 | 
			
		||||
	syslog(LOG_INFO, "dmeventd executes: %s.\n", state->cmd_str);
 | 
			
		||||
#endif
 | 
			
		||||
	return dmeventd_lvm2_run(state->cmd_str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _run(const char *cmd, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	int argc = 1; /* for argv[0], i.e. cmd */
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	const char **argv;
 | 
			
		||||
	pid_t pid = fork();
 | 
			
		||||
	int status;
 | 
			
		||||
 | 
			
		||||
	if (pid == 0) { /* child */
 | 
			
		||||
		va_start(ap, cmd);
 | 
			
		||||
		while (va_arg(ap, const char *))
 | 
			
		||||
			++argc;
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
 | 
			
		||||
		/* + 1 for the terminating NULL */
 | 
			
		||||
		argv = alloca(sizeof(const char *) * (argc + 1));
 | 
			
		||||
 | 
			
		||||
		argv[0] = cmd;
 | 
			
		||||
                va_start(ap, cmd);
 | 
			
		||||
		while ((argv[++i] = va_arg(ap, const char *)));
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
 | 
			
		||||
		execvp(cmd, (char **)argv);
 | 
			
		||||
		syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
 | 
			
		||||
		exit(127);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pid > 0) { /* parent */
 | 
			
		||||
		if (waitpid(pid, &status, 0) != pid)
 | 
			
		||||
			return 0; /* waitpid failed */
 | 
			
		||||
		if (!WIFEXITED(status) || WEXITSTATUS(status))
 | 
			
		||||
			return 0; /* the child failed */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pid < 0)
 | 
			
		||||
		return 0; /* fork failed */
 | 
			
		||||
 | 
			
		||||
	return 1; /* all good */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct mountinfo_s {
 | 
			
		||||
	struct dm_info info;
 | 
			
		||||
	dm_bitset_t minors; /* Bitset for active thin pool minors */
 | 
			
		||||
	const char *device;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int _umount_device(char *buffer, unsigned major, unsigned minor,
 | 
			
		||||
			  char *target, void *cb_data)
 | 
			
		||||
{
 | 
			
		||||
	struct mountinfo_s *data = cb_data;
 | 
			
		||||
 | 
			
		||||
	if ((major == data->info.major) && dm_bit(data->minors, minor)) {
 | 
			
		||||
		syslog(LOG_INFO, "Unmounting thin volume %s from %s.\n",
 | 
			
		||||
		       data->device, target);
 | 
			
		||||
		if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
 | 
			
		||||
			syslog(LOG_ERR, "Failed to umount thin %s from %s: %s.\n",
 | 
			
		||||
			       data->device, target, strerror(errno));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Find all thin pool users and try to umount them.
 | 
			
		||||
 * TODO: work with read-only thin pool support
 | 
			
		||||
 */
 | 
			
		||||
static void _umount(struct dm_task *dmt, const char *device)
 | 
			
		||||
{
 | 
			
		||||
	/* TODO: Convert to use hash to reduce memory usage */
 | 
			
		||||
	static const size_t MINORS = (1U << 20); /* 20 bit */
 | 
			
		||||
	struct mountinfo_s data = {
 | 
			
		||||
		.device = device,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	if (!dm_task_get_info(dmt, &data.info))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_unlock();
 | 
			
		||||
 | 
			
		||||
	if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
 | 
			
		||||
		syslog(LOG_ERR, "Failed to allocate bitset. Not unmounting %s.\n", device);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
 | 
			
		||||
		syslog(LOG_ERR, "Failed to detect mounted volumes for %s.\n", device);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dm_mountinfo_read(_umount_device, &data)) {
 | 
			
		||||
		syslog(LOG_ERR, "Could not parse mountinfo file.\n");
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	if (data.minors)
 | 
			
		||||
		dm_bitset_destroy(data.minors);
 | 
			
		||||
	dmeventd_lvm2_lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void process_event(struct dm_task *dmt,
 | 
			
		||||
		   enum dm_event_mask event __attribute__((unused)),
 | 
			
		||||
		   void **private)
 | 
			
		||||
{
 | 
			
		||||
	const char *device = dm_task_get_name(dmt);
 | 
			
		||||
	int percent;
 | 
			
		||||
	struct dso_state *state = *private;
 | 
			
		||||
	struct dm_status_thin_pool *tps = NULL;
 | 
			
		||||
	void *next = NULL;
 | 
			
		||||
	uint64_t start, length;
 | 
			
		||||
	char *target_type = NULL;
 | 
			
		||||
	char *params;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	/* No longer monitoring, waiting for remove */
 | 
			
		||||
	if (!state->meta_percent_check && !state->data_percent_check)
 | 
			
		||||
		return;
 | 
			
		||||
#endif
 | 
			
		||||
	dmeventd_lvm2_lock();
 | 
			
		||||
 | 
			
		||||
	dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
 | 
			
		||||
 | 
			
		||||
	if (!target_type || (strcmp(target_type, "thin-pool") != 0)) {
 | 
			
		||||
		syslog(LOG_ERR, "Invalid target type.\n");
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
 | 
			
		||||
		syslog(LOG_ERR, "Failed to parse status.\n");
 | 
			
		||||
		_umount(dmt, device);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if THIN_DEBUG
 | 
			
		||||
	syslog(LOG_INFO, "%p: Got status %" PRIu64 " / %" PRIu64
 | 
			
		||||
	       " %" PRIu64  " / %" PRIu64 ".\n", state,
 | 
			
		||||
	       tps->used_metadata_blocks, tps->total_metadata_blocks,
 | 
			
		||||
	       tps->used_data_blocks, tps->total_data_blocks);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Thin pool size had changed. Clear the threshold. */
 | 
			
		||||
	if (state->known_metadata_size != tps->total_metadata_blocks) {
 | 
			
		||||
		state->metadata_percent_check = CHECK_MINIMUM;
 | 
			
		||||
		state->known_metadata_size = tps->total_metadata_blocks;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (state->known_data_size != tps->total_data_blocks) {
 | 
			
		||||
		state->data_percent_check = CHECK_MINIMUM;
 | 
			
		||||
		state->known_data_size = tps->total_data_blocks;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	percent = 100 * tps->used_metadata_blocks / tps->total_metadata_blocks;
 | 
			
		||||
	if (percent >= state->metadata_percent_check) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Usage has raised more than CHECK_STEP since the last
 | 
			
		||||
		 * time. Run actions.
 | 
			
		||||
		 */
 | 
			
		||||
		state->metadata_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
 | 
			
		||||
 | 
			
		||||
		/* FIXME: extension of metadata needs to be written! */
 | 
			
		||||
		if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
 | 
			
		||||
			syslog(LOG_WARNING, "Thin metadata %s is now %i%% full.\n",
 | 
			
		||||
			       device, percent);
 | 
			
		||||
		 /* Try to extend the metadata, in accord with user-set policies */
 | 
			
		||||
		if (!_extend(state)) {
 | 
			
		||||
			syslog(LOG_ERR, "Failed to extend thin metadata %s.\n",
 | 
			
		||||
			       device);
 | 
			
		||||
			_umount(dmt, device);
 | 
			
		||||
		}
 | 
			
		||||
		/* FIXME: hmm READ-ONLY switch should happen in error path */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	percent = 100 * tps->used_data_blocks / tps->total_data_blocks;
 | 
			
		||||
	if (percent >= state->data_percent_check) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Usage has raised more than CHECK_STEP since
 | 
			
		||||
		 * the last time. Run actions.
 | 
			
		||||
		 */
 | 
			
		||||
		state->data_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
 | 
			
		||||
 | 
			
		||||
		if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
 | 
			
		||||
			syslog(LOG_WARNING, "Thin %s is now %i%% full.\n", device, percent);
 | 
			
		||||
		/* Try to extend the thin data, in accord with user-set policies */
 | 
			
		||||
		if (!_extend(state)) {
 | 
			
		||||
			syslog(LOG_ERR, "Failed to extend thin %s.\n", device);
 | 
			
		||||
			state->data_percent_check = 0;
 | 
			
		||||
			_umount(dmt, device);
 | 
			
		||||
		}
 | 
			
		||||
		/* FIXME: hmm READ-ONLY switch should happen in error path */
 | 
			
		||||
	}
 | 
			
		||||
out:
 | 
			
		||||
	if (tps)
 | 
			
		||||
		dm_pool_free(state->mem, tps);
 | 
			
		||||
 | 
			
		||||
	dmeventd_lvm2_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int register_device(const char *device,
 | 
			
		||||
		    const char *uuid __attribute__((unused)),
 | 
			
		||||
		    int major __attribute__((unused)),
 | 
			
		||||
		    int minor __attribute__((unused)),
 | 
			
		||||
		    void **private)
 | 
			
		||||
{
 | 
			
		||||
	struct dm_pool *statemem = NULL;
 | 
			
		||||
	struct dso_state *state;
 | 
			
		||||
 | 
			
		||||
	if (!dmeventd_lvm2_init())
 | 
			
		||||
		goto bad;
 | 
			
		||||
 | 
			
		||||
	if (!(statemem = dm_pool_create("thin_pool_state", 2048)) ||
 | 
			
		||||
	    !(state = dm_pool_zalloc(statemem, sizeof(*state))) ||
 | 
			
		||||
	    !dmeventd_lvm2_command(statemem, state->cmd_str,
 | 
			
		||||
				   sizeof(state->cmd_str),
 | 
			
		||||
				   "lvextend --use-policies",
 | 
			
		||||
				   device)) {
 | 
			
		||||
		if (statemem)
 | 
			
		||||
			dm_pool_destroy(statemem);
 | 
			
		||||
		dmeventd_lvm2_exit();
 | 
			
		||||
		goto bad;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	state->mem = statemem;
 | 
			
		||||
	state->metadata_percent_check = CHECK_MINIMUM;
 | 
			
		||||
	state->data_percent_check = CHECK_MINIMUM;
 | 
			
		||||
	*private = state;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "Monitoring thin %s.\n", device);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
bad:
 | 
			
		||||
	syslog(LOG_ERR, "Failed to monitor thin %s.\n", device);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int unregister_device(const char *device,
 | 
			
		||||
		      const char *uuid __attribute__((unused)),
 | 
			
		||||
		      int major __attribute__((unused)),
 | 
			
		||||
		      int minor __attribute__((unused)),
 | 
			
		||||
		      void **private)
 | 
			
		||||
{
 | 
			
		||||
	struct dso_state *state = *private;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_INFO, "No longer monitoring thin %s.\n", device);
 | 
			
		||||
	dm_pool_destroy(state->mem);
 | 
			
		||||
	dmeventd_lvm2_exit();
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2011-2012 Red Hat, Inc.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
# of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
 | 
			
		||||
SOURCES = lvmetad-core.c
 | 
			
		||||
SOURCES2 = testclient.c
 | 
			
		||||
 | 
			
		||||
TARGETS = lvmetad lvmetad-testclient
 | 
			
		||||
 | 
			
		||||
.PHONY: install_lvmetad
 | 
			
		||||
 | 
			
		||||
CFLOW_LIST = $(SOURCES)
 | 
			
		||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
 | 
			
		||||
CFLOW_TARGET = lvmetad
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
INCLUDES += -I$(top_srcdir)/libdaemon/server
 | 
			
		||||
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
 | 
			
		||||
 | 
			
		||||
LIBS += $(PTHREAD_LIBS)
 | 
			
		||||
 | 
			
		||||
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS)
 | 
			
		||||
CLDFLAGS += -L$(top_builddir)/libdaemon/server
 | 
			
		||||
CFLAGS += $(EXTRA_EXEC_CFLAGS)
 | 
			
		||||
 | 
			
		||||
lvmetad: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
 | 
			
		||||
		    $(top_builddir)/libdaemon/server/libdaemonserver.a
 | 
			
		||||
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
 | 
			
		||||
	$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
 | 
			
		||||
 | 
			
		||||
# TODO: No idea. No idea how to test either.
 | 
			
		||||
#ifneq ("$(CFLOW_CMD)", "")
 | 
			
		||||
#CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
 | 
			
		||||
#-include $(top_builddir)/libdm/libdevmapper.cflow
 | 
			
		||||
#-include $(top_builddir)/lib/liblvm-internal.cflow
 | 
			
		||||
#-include $(top_builddir)/lib/liblvm2cmd.cflow
 | 
			
		||||
#-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
 | 
			
		||||
#-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
install_lvmetad: lvmetad
 | 
			
		||||
	$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_lvmetad
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
@@ -1,83 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011-2012 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This file is part of LVM2.
 | 
			
		||||
 *
 | 
			
		||||
 * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
 * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
 * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LVM_LVMETAD_CLIENT_H
 | 
			
		||||
#define _LVM_LVMETAD_CLIENT_H
 | 
			
		||||
 | 
			
		||||
#include "daemon-client.h"
 | 
			
		||||
 | 
			
		||||
#define LVMETAD_SOCKET DEFAULT_RUN_DIR "/lvmetad.socket"
 | 
			
		||||
 | 
			
		||||
struct volume_group;
 | 
			
		||||
 | 
			
		||||
/* Different types of replies we may get from lvmetad. */
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	daemon_reply r;
 | 
			
		||||
	const char **uuids; /* NULL terminated array */
 | 
			
		||||
} lvmetad_uuidlist;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	daemon_reply r;
 | 
			
		||||
	struct dm_config_tree *cft;
 | 
			
		||||
} lvmetad_vg;
 | 
			
		||||
 | 
			
		||||
/* Get a list of VG UUIDs that match a given VG name. */
 | 
			
		||||
lvmetad_uuidlist lvmetad_lookup_vgname(daemon_handle h, const char *name);
 | 
			
		||||
 | 
			
		||||
/* Get the metadata of a single VG, identified by UUID. */
 | 
			
		||||
lvmetad_vg lvmetad_get_vg(daemon_handle h, const char *uuid);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Add and remove PVs on demand. Udev-driven systems will use this interface
 | 
			
		||||
 * instead of scanning.
 | 
			
		||||
 */
 | 
			
		||||
daemon_reply lvmetad_add_pv(daemon_handle h, const char *pv_uuid, const char *mda_content);
 | 
			
		||||
daemon_reply lvmetad_remove_pv(daemon_handle h, const char *pv_uuid);
 | 
			
		||||
 | 
			
		||||
/* Trigger a full disk scan, throwing away all caches. XXX do we eventually want
 | 
			
		||||
 * this? Probably not yet, anyway.
 | 
			
		||||
 *     daemon_reply lvmetad_rescan(daemon_handle h);
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Update the version of metadata of a volume group. The VG has to be locked for
 | 
			
		||||
 * writing for this, and the VG metadata here has to match whatever has been
 | 
			
		||||
 * written to the disk (under this lock). This initially avoids the requirement
 | 
			
		||||
 * for lvmetad to write to disk (in later revisions, lvmetad_supersede_vg may
 | 
			
		||||
 * also do the writing, or we probably add another function to do that).
 | 
			
		||||
 */
 | 
			
		||||
daemon_reply lvmetad_supersede_vg(daemon_handle h, struct volume_group *vg);
 | 
			
		||||
 | 
			
		||||
/* Wrappers to open/close connection */
 | 
			
		||||
 | 
			
		||||
static inline daemon_handle lvmetad_open(const char *socket)
 | 
			
		||||
{
 | 
			
		||||
	daemon_info lvmetad_info = {
 | 
			
		||||
		.path = "lvmetad",
 | 
			
		||||
		.socket = socket ?: LVMETAD_SOCKET,
 | 
			
		||||
		.protocol = "lvmetad",
 | 
			
		||||
		.protocol_version = 1,
 | 
			
		||||
		.autostart = 0
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return daemon_open(lvmetad_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void lvmetad_close(daemon_handle h)
 | 
			
		||||
{
 | 
			
		||||
	return daemon_close(h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,16 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
export LD_LIBRARY_PATH="$1"
 | 
			
		||||
 | 
			
		||||
test -n "$2" && {
 | 
			
		||||
    rm -f /var/run/lvmetad.{socket,pid}
 | 
			
		||||
    chmod +rx lvmetad
 | 
			
		||||
    valgrind ./lvmetad -f &
 | 
			
		||||
    PID=$!
 | 
			
		||||
    sleep 1
 | 
			
		||||
    ./testclient
 | 
			
		||||
    kill $PID
 | 
			
		||||
    exit 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sudo ./test.sh "$1" .
 | 
			
		||||
@@ -1,129 +0,0 @@
 | 
			
		||||
#include "lvmetad-client.h"
 | 
			
		||||
#include "label.h"
 | 
			
		||||
#include "lvmcache.h"
 | 
			
		||||
#include "metadata.h"
 | 
			
		||||
 | 
			
		||||
const char *uuid1 = "abcd-efgh";
 | 
			
		||||
const char *uuid2 = "bbcd-efgh";
 | 
			
		||||
const char *vgid = "yada-yada";
 | 
			
		||||
const char *uuid3 = "cbcd-efgh";
 | 
			
		||||
 | 
			
		||||
const char *metadata2 = "{\n"
 | 
			
		||||
	"id = \"yada-yada\"\n"
 | 
			
		||||
	"seqno = 15\n"
 | 
			
		||||
	"status = [\"READ\", \"WRITE\"]\n"
 | 
			
		||||
	"flags = []\n"
 | 
			
		||||
	"extent_size = 8192\n"
 | 
			
		||||
	"physical_volumes {\n"
 | 
			
		||||
	"    pv0 {\n"
 | 
			
		||||
	"        id = \"abcd-efgh\"\n"
 | 
			
		||||
	"    }\n"
 | 
			
		||||
	"    pv1 {\n"
 | 
			
		||||
	"        id = \"bbcd-efgh\"\n"
 | 
			
		||||
	"    }\n"
 | 
			
		||||
	"    pv2 {\n"
 | 
			
		||||
	"        id = \"cbcd-efgh\"\n"
 | 
			
		||||
	"    }\n"
 | 
			
		||||
	"}\n"
 | 
			
		||||
	"}\n";
 | 
			
		||||
 | 
			
		||||
void _handle_reply(daemon_reply reply) {
 | 
			
		||||
	const char *repl = daemon_reply_str(reply, "response", NULL);
 | 
			
		||||
	const char *status = daemon_reply_str(reply, "status", NULL);
 | 
			
		||||
	const char *vgid = daemon_reply_str(reply, "vgid", NULL);
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr, "[C] REPLY: %s\n", repl);
 | 
			
		||||
	if (!strcmp(repl, "failed"))
 | 
			
		||||
		fprintf(stderr, "[C] REASON: %s\n", daemon_reply_str(reply, "reason", "unknown"));
 | 
			
		||||
	if (vgid)
 | 
			
		||||
		fprintf(stderr, "[C] VGID: %s\n", vgid);
 | 
			
		||||
	if (status)
 | 
			
		||||
		fprintf(stderr, "[C] STATUS: %s\n", status);
 | 
			
		||||
	daemon_reply_destroy(reply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _pv_add(daemon_handle h, const char *uuid, const char *metadata)
 | 
			
		||||
{
 | 
			
		||||
	daemon_reply reply = daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
 | 
			
		||||
						             "metadata = %b", metadata,
 | 
			
		||||
						             NULL);
 | 
			
		||||
	_handle_reply(reply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int scan(daemon_handle h, char *fn) {
 | 
			
		||||
	struct device *dev = dev_cache_get(fn, NULL);
 | 
			
		||||
 | 
			
		||||
	struct label *label;
 | 
			
		||||
	if (!label_read(dev, &label, 0)) {
 | 
			
		||||
		fprintf(stderr, "[C] no label found on %s\n", fn);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char uuid[64];
 | 
			
		||||
	id_write_format(dev->pvid, uuid, 64);
 | 
			
		||||
	fprintf(stderr, "[C] found PV: %s\n", uuid);
 | 
			
		||||
	struct lvmcache_info *info = (struct lvmcache_info *) label->info;
 | 
			
		||||
	struct physical_volume pv = { 0, };
 | 
			
		||||
 | 
			
		||||
	if (!(info->fmt->ops->pv_read(info->fmt, dev_name(dev), &pv, 0))) {
 | 
			
		||||
		fprintf(stderr, "[C] Failed to read PV %s", dev_name(dev));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct format_instance_ctx fic;
 | 
			
		||||
	struct format_instance *fid = info->fmt->ops->create_instance(info->fmt, &fic);
 | 
			
		||||
	struct metadata_area *mda;
 | 
			
		||||
	struct volume_group *vg = NULL;
 | 
			
		||||
	dm_list_iterate_items(mda, &info->mdas) {
 | 
			
		||||
		struct volume_group *this = mda->ops->vg_read(fid, "", mda);
 | 
			
		||||
		if (this && !vg || this->seqno > vg->seqno)
 | 
			
		||||
			vg = this;
 | 
			
		||||
	}
 | 
			
		||||
	if (vg) {
 | 
			
		||||
		char *buf = NULL;
 | 
			
		||||
		/* TODO. This is not entirely correct, since export_vg_to_buffer
 | 
			
		||||
		 * adds trailing garbage to the buffer. We may need to use
 | 
			
		||||
		 * export_vg_to_config_tree and format the buffer ourselves. It
 | 
			
		||||
		 * does, however, work for now, since the garbage is well
 | 
			
		||||
		 * formatted and has no conflicting keys with the rest of the
 | 
			
		||||
		 * request.  */
 | 
			
		||||
		export_vg_to_buffer(vg, &buf);
 | 
			
		||||
		daemon_reply reply =
 | 
			
		||||
			daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
 | 
			
		||||
					      "metadata = %b", strchr(buf, '{'),
 | 
			
		||||
					      NULL);
 | 
			
		||||
		_handle_reply(reply);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _dump_vg(daemon_handle h, const char *uuid)
 | 
			
		||||
{
 | 
			
		||||
	daemon_reply reply = daemon_send_simple(h, "vg_by_uuid", "uuid = %s", uuid, NULL);
 | 
			
		||||
	fprintf(stderr, "[C] reply buffer: %s\n", reply.buffer);
 | 
			
		||||
	daemon_reply_destroy(reply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv) {
 | 
			
		||||
	daemon_handle h = lvmetad_open();
 | 
			
		||||
	/* FIXME Missing error path */
 | 
			
		||||
 | 
			
		||||
	if (argc > 1) {
 | 
			
		||||
		int i;
 | 
			
		||||
		struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0);
 | 
			
		||||
		for (i = 1; i < argc; ++i) {
 | 
			
		||||
			const char *uuid = NULL;
 | 
			
		||||
			scan(h, argv[i]);
 | 
			
		||||
		}
 | 
			
		||||
		destroy_toolcontext(cmd);
 | 
			
		||||
		/* FIXME Missing lvmetad_close() */
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_pv_add(h, uuid1, NULL);
 | 
			
		||||
	_pv_add(h, uuid2, metadata2);
 | 
			
		||||
	_dump_vg(h, vgid);
 | 
			
		||||
	_pv_add(h, uuid3, NULL);
 | 
			
		||||
 | 
			
		||||
	daemon_close(h);	/* FIXME lvmetad_close? */
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/README.Debian
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/README.Debian
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
LVM2 requires the device-mapper kernel module (dm-mod).  This is
 | 
			
		||||
available as a kernel patch for 2.4 (in kernel-patch-device-mapper), and
 | 
			
		||||
is distributed with linux 2.5 and above.  The LVM1 kernel module (lvm-mod)
 | 
			
		||||
will not work with lvm2 packages.  dm-mod and lvm-mod may both be loaded
 | 
			
		||||
in the kernel at the same time with no problems.  Without dm-mod, this
 | 
			
		||||
package is pretty useless.
 | 
			
		||||
							
								
								
									
										82
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
lvm2 (1.95.15-1) unstable; urgency=low
 | 
			
		||||
  
 | 
			
		||||
  * New upstream release.
 | 
			
		||||
  * Remove undocumented manpage symlinks.
 | 
			
		||||
  * Update description to be more informative.  (Closes: #173499)
 | 
			
		||||
  * Add kernel-patch-device-mapper suggestion.
 | 
			
		||||
  * Update standards version.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Sun, 16 Feb 2002 04:21:26 -0400
 | 
			
		||||
 | 
			
		||||
lvm2 (1.95.11-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream release.  (Closes: #171436)
 | 
			
		||||
  * Removed TODO and INTRO from debian/docs; added WHATS_NEW.
 | 
			
		||||
  * Remove vgcfgrestore.8 undocumented symlink.
 | 
			
		||||
  * Added a README.Debian, mentioning the device-mapper kernel module
 | 
			
		||||
    requirement that lvm2 has.  (Closes: #171674, #163020)
 | 
			
		||||
  * Get rid of debian/conffiles (debhelper's smart enough to figure that out).
 | 
			
		||||
  * debian/copyright fix to appease lintian.
 | 
			
		||||
  * Fix typo in tools/commands.h that caused /usr/sbin/; to be created.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Mon,  9 Dec 2002 02:51:02 -0400
 | 
			
		||||
 | 
			
		||||
lvm2 (1.95.10-2) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fix software raid problems by ensuring lvm init script runs after
 | 
			
		||||
    raidtools init script.  (Closes: #152569)
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Tue,  3 Sep 2002 04:05:43 -0400
 | 
			
		||||
 | 
			
		||||
lvm2 (1.95.10-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream release (Beta 3.2).
 | 
			
		||||
  * Change all references to /dev/device-mapper/control to
 | 
			
		||||
    /dev/mapper/control.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Sun,  1 Sep 2002 18:55:12 -0400
 | 
			
		||||
 | 
			
		||||
lvm2 (0.95.05-3) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Get rid of awk dependency in init script.  (Closes: #146257)
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Sun, 12 May 2002 04:39:06 -0500
 | 
			
		||||
 | 
			
		||||
lvm2 (0.95.05-2) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Use ${shlibs:Depends} in Depends.
 | 
			
		||||
  * Get rid of postinst/postrm scripts, use debhelper's init script instead.
 | 
			
		||||
  * Add Conflicts against lvm10, lvm-common.
 | 
			
		||||
  * Fix endian issues on big-endian machines.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Thu,  2 May 2002 23:53:53 -0500
 | 
			
		||||
 | 
			
		||||
lvm2 (0.95.05-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New release (Beta2).
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Thu, 25 Apr 2002 00:37:41 -0500
 | 
			
		||||
 | 
			
		||||
lvm2 (0.95.04cvs20020306-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * CVS updated.
 | 
			
		||||
  * Convert from debian native package.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Wed,  6 Mar 2002 00:43:21 -0500
 | 
			
		||||
 | 
			
		||||
lvm2 (0.95.04cvs20020304) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * CVS updated.
 | 
			
		||||
  * Enhance init script; create devmapper control device, etc.
 | 
			
		||||
  * Add dmsetup as a suggestion.
 | 
			
		||||
  * Add /etc/lvm/lvm.conf conffile.
 | 
			
		||||
  * Add undocumented(7) for the commands missing manpages.
 | 
			
		||||
  
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Mon,  4 Mar 2002 04:51:26 -0500
 | 
			
		||||
 | 
			
		||||
lvm2 (0.95.02cvs20020220) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Initial Release.
 | 
			
		||||
 | 
			
		||||
 -- Andres Salomon <dilinger@mp3revolution.net>  Wed, 20 Feb 2002 03:17:25 -0500
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
Source: lvm2
 | 
			
		||||
Section: admin
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
 | 
			
		||||
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
 | 
			
		||||
Standards-Version: 3.5.8.0
 | 
			
		||||
 | 
			
		||||
Package: lvm2
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends}
 | 
			
		||||
Conflicts: lvm10, lvm-common
 | 
			
		||||
Replaces: lvm10, lvm-common
 | 
			
		||||
Provides: lvm-binaries
 | 
			
		||||
Suggests: dmsetup, kernel-patch-device-mapper
 | 
			
		||||
Description: The Linux Logical Volume Manager
 | 
			
		||||
 This is LVM2, the rewrite of The Linux Logical Volume Manager.  LVM
 | 
			
		||||
 supports enterprise level volume management of disk and disk subsystems
 | 
			
		||||
 by grouping arbitrary disks into volume groups. The total capacity of
 | 
			
		||||
 volume groups can be allocated to logical volumes, which are accessed as
 | 
			
		||||
 regular block devices.
 | 
			
		||||
 .
 | 
			
		||||
 LVM2 is currently stable, but has some unimplemented features (most notably,
 | 
			
		||||
 pvmove and e2fsadm).  It is not yet recommended for production use.  It is
 | 
			
		||||
 backwards-compatible with LVM1 (lvm10), and requires Linux kernel 2.4.
 | 
			
		||||
							
								
								
									
										25
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
This package was debianized by Andres Salomon <dilinger@mp3revolution.net> on
 | 
			
		||||
Wed, 20 Feb 2002 03:17:25 -0500.
 | 
			
		||||
 | 
			
		||||
It was downloaded from http://www.sistina.com/products_lvm.htm
 | 
			
		||||
 | 
			
		||||
Upstream Author: LVM Development Team
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2001-2002 LVM Development Team
 | 
			
		||||
 | 
			
		||||
LVM2 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.
 | 
			
		||||
 | 
			
		||||
LVM2 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 | 
			
		||||
 | 
			
		||||
On Debian systems, the full text of the GPL can be found in
 | 
			
		||||
/usr/share/common-licenses/GPL
 | 
			
		||||
							
								
								
									
										4
									
								
								debian/dirs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								debian/dirs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
etc/lvm
 | 
			
		||||
usr/share/man/man5
 | 
			
		||||
usr/share/man/man8
 | 
			
		||||
sbin
 | 
			
		||||
							
								
								
									
										5
									
								
								debian/docs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								debian/docs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
BUGS
 | 
			
		||||
README
 | 
			
		||||
VERSION
 | 
			
		||||
WHATS_NEW
 | 
			
		||||
doc/*
 | 
			
		||||
							
								
								
									
										64
									
								
								debian/init.d
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								debian/init.d
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# lvm2		This script handles LVM2 initialization/shutdown.
 | 
			
		||||
#
 | 
			
		||||
#		Written by Andres Salomon <dilinger@mp3revolution.net>.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
 | 
			
		||||
NAME=lvm2
 | 
			
		||||
DESC=LVM
 | 
			
		||||
 | 
			
		||||
test -x /sbin/vgchange || exit 0
 | 
			
		||||
modprobe dm-mod >/dev/null 2>&1
 | 
			
		||||
 | 
			
		||||
# Create necessary files in /dev for device-mapper
 | 
			
		||||
create_devfiles() {
 | 
			
		||||
	DIR="/dev/mapper"
 | 
			
		||||
	FILE="$DIR/control"
 | 
			
		||||
	major=$(grep "[0-9] misc$" /proc/devices | sed 's/[ ]\+misc//')
 | 
			
		||||
	minor=$(grep "[0-9] device-mapper$" /proc/misc | sed 's/[ ]\+device-mapper//')
 | 
			
		||||
 | 
			
		||||
	if test ! -d $DIR; then
 | 
			
		||||
		mkdir --mode=755 $DIR >/dev/null 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if test ! -c $FILE -a ! -z "$minor"; then
 | 
			
		||||
		mknod --mode=600 $FILE c $major $minor >/dev/null 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
	echo -n "Initializing $DESC: "
 | 
			
		||||
	create_devfiles
 | 
			
		||||
	vgchange -a y
 | 
			
		||||
 | 
			
		||||
#	# Mount all LVM devices
 | 
			
		||||
#	for vg in $( vgchange -a y 2>/dev/null | grep active | awk -F\" '{print $2}' ); do
 | 
			
		||||
#		MTPT=$( grep $vg /etc/fstab | awk '{print $2}' )
 | 
			
		||||
#		mount $MTPT
 | 
			
		||||
#	done
 | 
			
		||||
	echo "$NAME."
 | 
			
		||||
	;;
 | 
			
		||||
  stop)
 | 
			
		||||
	echo -n "Shutting down $DESC: "
 | 
			
		||||
	# We don't really try all that hard to shut it down; far too many
 | 
			
		||||
	# things that can keep it from successfully shutting down.
 | 
			
		||||
	vgchange -a n
 | 
			
		||||
	echo "$NAME."
 | 
			
		||||
	;;
 | 
			
		||||
  restart|force-reload)
 | 
			
		||||
	echo -n "Restarting $DESC: "
 | 
			
		||||
	vgchange -a n
 | 
			
		||||
	sleep 1
 | 
			
		||||
	vgchange -a y
 | 
			
		||||
	echo "$NAME."
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload}" >&2
 | 
			
		||||
	exit 1
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
							
								
								
									
										26
									
								
								debian/manpages
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								debian/manpages
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
debian/lvm2/usr/share/man/man5/lvm.conf.5
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvchange.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvcreate.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvdisplay.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvextend.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvm.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvmchange.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvreduce.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvremove.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvrename.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/lvscan.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/pvchange.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/pvcreate.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/pvdisplay.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/pvscan.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgcfgbackup.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgchange.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgck.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgcreate.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgdisplay.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgextend.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgmerge.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgreduce.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgremove.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgrename.8
 | 
			
		||||
debian/lvm2/usr/share/man/man8/vgscan.8
 | 
			
		||||
							
								
								
									
										119
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										119
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
# Sample debian/rules that uses debhelper. 
 | 
			
		||||
# GNU copyright 1997 by Joey Hess.
 | 
			
		||||
#
 | 
			
		||||
# This version is for a hypothetical package that builds an
 | 
			
		||||
# architecture-dependant package, as well as an architecture-independent
 | 
			
		||||
# package.
 | 
			
		||||
 | 
			
		||||
# Uncomment this to turn on verbose mode. 
 | 
			
		||||
#export DH_VERBOSE=1
 | 
			
		||||
 | 
			
		||||
# This is the debhelper compatibility version to use.
 | 
			
		||||
export DH_COMPAT=3
 | 
			
		||||
 | 
			
		||||
# These are used for cross-compiling and for saving the configure script
 | 
			
		||||
# from having to guess our platform (since we know it already)
 | 
			
		||||
DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
 | 
			
		||||
DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
 | 
			
		||||
 | 
			
		||||
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
 | 
			
		||||
	CFLAGS += -g
 | 
			
		||||
endif
 | 
			
		||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
 | 
			
		||||
	INSTALL_PROGRAM += -s
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
configure: configure-stamp
 | 
			
		||||
configure-stamp:
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	# Add here commands to configure the package.
 | 
			
		||||
	./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/ --mandir=\$${prefix}/usr/share/man --infodir=\$${prefix}/usr/share/info
 | 
			
		||||
 | 
			
		||||
	touch configure-stamp
 | 
			
		||||
 | 
			
		||||
build-arch: configure-stamp build-arch-stamp
 | 
			
		||||
build-arch-stamp:
 | 
			
		||||
	dh_testdir
 | 
			
		||||
 | 
			
		||||
	# Add here command to compile/build the package.
 | 
			
		||||
	$(MAKE)
 | 
			
		||||
 | 
			
		||||
	touch build-arch-stamp
 | 
			
		||||
 | 
			
		||||
build-indep: configure-stamp build-indep-stamp
 | 
			
		||||
build-indep-stamp:
 | 
			
		||||
	dh_testdir
 | 
			
		||||
 | 
			
		||||
	# Add here command to compile/build the arch indep package.
 | 
			
		||||
	# It's ok not to do anything here, if you don't need to build
 | 
			
		||||
	#  anything for this package.
 | 
			
		||||
	#/usr/bin/docbook-to-man debian/lvm2.sgml > lvm2.1
 | 
			
		||||
 | 
			
		||||
	touch build-indep-stamp
 | 
			
		||||
 | 
			
		||||
build: build-arch build-indep
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	dh_testroot
 | 
			
		||||
	rm -f build-stamp configure-stamp
 | 
			
		||||
 | 
			
		||||
	# Add here commands to clean up after the build process.
 | 
			
		||||
	-$(MAKE) distclean
 | 
			
		||||
	-test -r /usr/share/misc/config.sub && \
 | 
			
		||||
	  cp -f /usr/share/misc/config.sub config.sub
 | 
			
		||||
	-test -r /usr/share/misc/config.guess && \
 | 
			
		||||
	  cp -f /usr/share/misc/config.guess config.guess
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	dh_clean
 | 
			
		||||
 | 
			
		||||
install: DH_OPTIONS=
 | 
			
		||||
install: build
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	dh_testroot
 | 
			
		||||
	dh_clean -k
 | 
			
		||||
	dh_installdirs
 | 
			
		||||
 | 
			
		||||
	# Add here commands to install the package into debian/lvm2.
 | 
			
		||||
	$(MAKE) install prefix=$(CURDIR)/debian/lvm2
 | 
			
		||||
	install -m 0644 doc/example.conf debian/lvm2/etc/lvm/lvm.conf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Build architecture-independent files here.
 | 
			
		||||
# Pass -i to all debhelper commands in this target to reduce clutter.
 | 
			
		||||
binary-indep: build install
 | 
			
		||||
# nada.
 | 
			
		||||
 | 
			
		||||
# Build architecture-dependent files here.
 | 
			
		||||
binary-arch: build install
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	dh_testroot
 | 
			
		||||
 | 
			
		||||
#	dh_installdebconf
 | 
			
		||||
	dh_installdocs
 | 
			
		||||
	dh_installexamples
 | 
			
		||||
#	dh_installlogrotate -a
 | 
			
		||||
#	dh_installemacsen -a
 | 
			
		||||
#	dh_installpam -a
 | 
			
		||||
#	dh_installmime -a
 | 
			
		||||
	dh_installinit --update-rcd-params="start 26 S . start 50 0 6 ."
 | 
			
		||||
	dh_installcron
 | 
			
		||||
	dh_installman
 | 
			
		||||
	dh_installinfo 
 | 
			
		||||
	dh_installchangelogs
 | 
			
		||||
	dh_strip
 | 
			
		||||
	dh_link
 | 
			
		||||
	dh_compress
 | 
			
		||||
	dh_fixperms
 | 
			
		||||
	dh_makeshlibs
 | 
			
		||||
	dh_installdeb
 | 
			
		||||
#	dh_perl -a
 | 
			
		||||
	dh_shlibdeps
 | 
			
		||||
	dh_gencontrol
 | 
			
		||||
	dh_md5sums
 | 
			
		||||
	dh_builddeb
 | 
			
		||||
 | 
			
		||||
binary: binary-indep binary-arch
 | 
			
		||||
.PHONY: build clean binary-indep binary-arch binary install configure
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2011 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of LVM2.
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
# This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
# modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
@@ -13,13 +14,9 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
SOURCES = thin.c
 | 
			
		||||
SUBDIRS += mirror
 | 
			
		||||
 | 
			
		||||
LIB_SHARED = liblvm2thin.$(LIB_SUFFIX)
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_LVM)
 | 
			
		||||
include $(top_srcdir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
install: install_lib_shared_plugin
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
 | 
			
		||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
 | 
			
		||||
#
 | 
			
		||||
# This file is part of the LVM2.
 | 
			
		||||
#
 | 
			
		||||
@@ -14,20 +14,23 @@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
top_builddir = @top_builddir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
 | 
			
		||||
INCLUDES += -I${top_srcdir}/tools
 | 
			
		||||
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper -llvm2cmd
 | 
			
		||||
 | 
			
		||||
SOURCES = dmeventd_snapshot.c
 | 
			
		||||
SOURCES = dmeventd_mirror.c
 | 
			
		||||
 | 
			
		||||
LIB_SHARED = libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
 | 
			
		||||
LIB_VERSION = $(LIB_VERSION_LVM)
 | 
			
		||||
ifeq ("@LIB_SUFFIX@","dylib")
 | 
			
		||||
  LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
 | 
			
		||||
else
 | 
			
		||||
  LIB_SHARED = libdevmapper-event-lvm2mirror.so
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
include $(top_builddir)/make.tmpl
 | 
			
		||||
include $(top_srcdir)/make.tmpl
 | 
			
		||||
 | 
			
		||||
LIBS += -ldevmapper-event-lvm2 -ldevmapper
 | 
			
		||||
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
 | 
			
		||||
	$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
 | 
			
		||||
		$(libdir)/$<.$(LIB_VERSION)
 | 
			
		||||
	$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
 | 
			
		||||
 | 
			
		||||
install_lvm2: install_dm_plugin
 | 
			
		||||
 | 
			
		||||
install: install_lvm2
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user