mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-08-22 01:50:06 +03:00
Compare commits
1572 Commits
v0.9.3-rc2
...
v0.9.9
Author | SHA1 | Date | |
---|---|---|---|
2f667b5697 | |||
cf6d36257b | |||
03ea567327 | |||
74ff57506c | |||
b41d440e61 | |||
307f363509 | |||
6b780f744b | |||
820a2159e9 | |||
302fe95ffa | |||
db371a217d | |||
49d8c8bc0c | |||
beeea90a37 | |||
88ed9ec001 | |||
06b9c5b923 | |||
524ba58bb9 | |||
66ca7ce573 | |||
851fc8139f | |||
269ce467fc | |||
d82c6bcf30 | |||
f4384b8439 | |||
973af2362c | |||
baade4cd2b | |||
8267aea5a6 | |||
bc1b27e07e | |||
c4ac050fcb | |||
904e05a292 | |||
b43432931a | |||
6cb4acce8b | |||
e83837945c | |||
336df7966b | |||
116d6af979 | |||
cbc7025942 | |||
b2310b2913 | |||
e8d6b293d8 | |||
ee3de186b3 | |||
e7dfe00d06 | |||
51fded0be9 | |||
85f3493f34 | |||
f0293edc3f | |||
ae3315aa4a | |||
1a3f6608aa | |||
96b3716c2a | |||
e957b67061 | |||
1f24ddf6bf | |||
b2c545bf80 | |||
8a34f822e6 | |||
d145fe3bb3 | |||
c8b9fa7434 | |||
dc099b8338 | |||
d8db0f9690 | |||
74ad69b708 | |||
6e4c540d28 | |||
5ccc7f6488 | |||
8e7829f754 | |||
6da91758d7 | |||
a1a83c5874 | |||
1c8f0cbb83 | |||
33eca17f6a | |||
6fdbce1232 | |||
bbae92f8b8 | |||
d64955a91a | |||
4ba56a9410 | |||
7e4d896b5e | |||
fbdfda14a1 | |||
ea964658af | |||
2b603dcb6c | |||
5abbe04d68 | |||
9da9a3b047 | |||
6758a01b18 | |||
1b051d8652 | |||
c57ca57034 | |||
9d3a721ad5 | |||
059425ae45 | |||
4e394dea1f | |||
f8616336a3 | |||
60f99824d4 | |||
78496224f7 | |||
6f75a28d9b | |||
6e4750e057 | |||
707781fe12 | |||
34ad13536e | |||
2c2d533768 | |||
06eb22df01 | |||
7b87a30f15 | |||
4f5326c315 | |||
d09f6ba5fe | |||
a86bbc6003 | |||
b4d579de1e | |||
f9d60b1946 | |||
8fb2aeb662 | |||
d99fe011a2 | |||
13d5a6b83d | |||
3bb6bcfc79 | |||
daa8c96233 | |||
d8916dc8e2 | |||
d758e0cb64 | |||
6948b725e7 | |||
3f29d6c91f | |||
a0aec362e8 | |||
6e53293812 | |||
65aefae1a8 | |||
972f7e6e49 | |||
fbd8d6fc87 | |||
ae52342754 | |||
b72c774b88 | |||
98b942c6f5 | |||
380f326955 | |||
fe7fc1617c | |||
104046712f | |||
5547d2b81c | |||
0fe2b40d5a | |||
dcaeb74a31 | |||
95ab415417 | |||
20e1233c31 | |||
4d9e51f633 | |||
7204a9fd31 | |||
ae1232b298 | |||
9f406c5838 | |||
2a994a3b1e | |||
e1636f47ae | |||
dad3c2090d | |||
a7adac3730 | |||
6c811ed486 | |||
9707c2a8bc | |||
84f5633312 | |||
b1d6d56ceb | |||
3b0bb65dd4 | |||
2d5046d31f | |||
b2cb24f48b | |||
6235629648 | |||
33eb3567dd | |||
95ff5899b9 | |||
f582199e60 | |||
ecf75f83dc | |||
f48ab7d888 | |||
f21d49144f | |||
3b95f284f1 | |||
9c417636c4 | |||
4d82fa688e | |||
478a4d07ac | |||
011a3350be | |||
608786fc52 | |||
5e6ce1c936 | |||
9bb8064dff | |||
82ff25e108 | |||
f99b3b4b50 | |||
dbe5eb2d3a | |||
7c6b0653f3 | |||
fea83dde7b | |||
f59a941757 | |||
e970863746 | |||
50a4f49c19 | |||
284230199a | |||
8d16201fe0 | |||
9fdfd8b6af | |||
97652044af | |||
cc17f09246 | |||
9ec14bcabb | |||
13c881dcbf | |||
d336dbdb33 | |||
e7dfa468f9 | |||
f17e0e2182 | |||
9bfa132c70 | |||
b265beda55 | |||
38527c9ae0 | |||
8fcee135e8 | |||
dd8e895606 | |||
17c7795561 | |||
49556023f2 | |||
3a9ce767f1 | |||
2b094d56b5 | |||
2b045d39df | |||
c74a2a03f0 | |||
75da320087 | |||
4cfdbfc46f | |||
fd06692544 | |||
8c309caff8 | |||
77e62f132c | |||
a699793449 | |||
059d746ddb | |||
da8061eefe | |||
24d9792821 | |||
949e10911a | |||
55d76a7270 | |||
ac6b368d8a | |||
b0ed12276e | |||
7a79648532 | |||
0763a26dfe | |||
764574f7c7 | |||
cb1e7b61c8 | |||
4c8327994c | |||
5483e5736d | |||
d7cc2520f2 | |||
773a4ea5e1 | |||
ad8fa356a6 | |||
7b811a74c6 | |||
f9bb67ec6a | |||
25a5f07c69 | |||
22cf6d46f4 | |||
9b524ff040 | |||
7e976db4ea | |||
55ecc49bbc | |||
62a19475d2 | |||
e9bd9a0809 | |||
eca96694a7 | |||
6df7ccb10e | |||
115a2a3fbb | |||
87e8ff1be1 | |||
a8bb75a3e6 | |||
32d3ec7466 | |||
3ec1289896 | |||
380110cf08 | |||
a82ed6a0c3 | |||
9ae0b8349c | |||
8c60bc169f | |||
2fc056c1ba | |||
f1f28611f1 | |||
f5272027c3 | |||
c92653f4dd | |||
53c2aad88b | |||
33386276a9 | |||
6ea25cd975 | |||
ae5e55289d | |||
6fb5400fc6 | |||
866b0a7069 | |||
a001a5e28b | |||
d082e1b966 | |||
1f8a339dee | |||
93ab58595d | |||
6ac81c8ec8 | |||
659ded58ed | |||
51727c1dc0 | |||
4199f3de2e | |||
80eaa56561 | |||
2524c8434b | |||
72908c7403 | |||
d1a6c77aca | |||
4fa36f1392 | |||
7c80d07414 | |||
caef87d557 | |||
dee901c1ff | |||
6b84ee3370 | |||
54bf875aa6 | |||
4b7de948f9 | |||
34401a8b42 | |||
4ddb37c395 | |||
76da40a820 | |||
979676e3db | |||
302743f177 | |||
4e511fcc18 | |||
2d0fc93fdd | |||
d360795d60 | |||
8078a90a24 | |||
a6916977bb | |||
508aef9b0e | |||
a04699fc12 | |||
d9724a81b3 | |||
9175347828 | |||
3e1b6d7575 | |||
3ba949e8f4 | |||
a1b62f983b | |||
f88de3eb51 | |||
c3a6a1e149 | |||
2c4cdb736c | |||
04a469338d | |||
8455705959 | |||
3a6a262428 | |||
1e62643719 | |||
6e945da567 | |||
e401b0cd02 | |||
afdf014f4f | |||
2fb1362883 | |||
673adba594 | |||
f4324e3292 | |||
fd7e85ac6a | |||
8d6e3edd0e | |||
71b779a1ad | |||
4acd358a76 | |||
2afc5a7bbf | |||
78965a33e8 | |||
3e1b2fab0c | |||
ebee52f52b | |||
dc62c22532 | |||
c4b32641f1 | |||
db2f680775 | |||
3ac26e2645 | |||
c725e2dc5a | |||
489e14f258 | |||
aad764e107 | |||
3fb94eeeb2 | |||
ea7182c29f | |||
ad6c67cf85 | |||
5c5e07b84c | |||
7ca82ecbea | |||
aa1cb7e706 | |||
970b417abb | |||
fa69eb5f52 | |||
d64208888d | |||
1d5654b266 | |||
ba3bf00acf | |||
af37ce3dc7 | |||
aa69441cba | |||
720442e245 | |||
c6ba523961 | |||
3c5405149b | |||
e352b16400 | |||
693d22d417 | |||
334c539ba0 | |||
2e37bf42d2 | |||
b745817650 | |||
66d5d3f186 | |||
d26b73ca2b | |||
83ac18937e | |||
1355bdf940 | |||
8047c4bffa | |||
a495365d09 | |||
531d7dddf1 | |||
f14b4cb5a0 | |||
41a2636aa3 | |||
cda8bd1a63 | |||
4af58342ed | |||
d02ef4b84c | |||
8951328619 | |||
c80296e21a | |||
581d1cea34 | |||
1d8a00cd22 | |||
f086b8164a | |||
6aa99120fa | |||
f6e80a713f | |||
ea7c73a76f | |||
2657822e87 | |||
19028ad6dc | |||
4a410218a0 | |||
be39b3e4a5 | |||
4df34ec394 | |||
e9640b99ef | |||
4789fb2e4e | |||
bfe952c9b2 | |||
6ec8288a96 | |||
f3b1b9b184 | |||
914d1b7403 | |||
0c1587e10b | |||
91904106a2 | |||
74b32b6297 | |||
8f688c85af | |||
5373cb74bd | |||
6e0c4dce0b | |||
8e6cd41418 | |||
50f190856d | |||
00bba08d24 | |||
ebbb6bd11f | |||
255917f516 | |||
10462d5c78 | |||
d2fed854c0 | |||
57f0de4c26 | |||
191090ae27 | |||
896104c9f0 | |||
43925db7ca | |||
a7c6ce0d52 | |||
9b6bb0fef6 | |||
5f7b71b413 | |||
c74b97156f | |||
d47ab3fe61 | |||
e86417e90c | |||
1ae8eed1b4 | |||
f153501e68 | |||
a38710bd65 | |||
1d46b2e900 | |||
ff465ad203 | |||
b196220337 | |||
5990f227e9 | |||
9f28ad0026 | |||
fa9595003d | |||
2501d27e18 | |||
d776170012 | |||
5745dc123a | |||
0f590c62b2 | |||
39d91e9f88 | |||
c2cc02ea98 | |||
5240ad6580 | |||
268085c3bd | |||
428cffb1e7 | |||
29b242ad80 | |||
d3406045fd | |||
df64f4807e | |||
767e01ceb1 | |||
b1451b6c07 | |||
be622a63cd | |||
afa1029ada | |||
342c09578a | |||
40624d32fb | |||
a218c81da2 | |||
329b2b2819 | |||
61f2b6ba5f | |||
d3da21d656 | |||
e55ec69de6 | |||
787b0a2238 | |||
613f9ea8f7 | |||
fde59b4059 | |||
c31d23a787 | |||
a132fb0925 | |||
091fa6a89c | |||
3b7122c0b2 | |||
bd6083c9ba | |||
0eee075dc7 | |||
4c544e6c61 | |||
e49c9bf25c | |||
c1df2c14b5 | |||
ccc243470d | |||
dfb454cebc | |||
d8a62d9552 | |||
dced27c89e | |||
4f4fd8f7ad | |||
6cfeb9a766 | |||
85cf8d3899 | |||
676fdf8cb5 | |||
0dbc10a89e | |||
b9338ac828 | |||
5ab243b64f | |||
2d764cb472 | |||
ab4823a062 | |||
f7bd00c12c | |||
07bf96ee3f | |||
b2c6231647 | |||
4d970fd293 | |||
9d86cbcf5f | |||
53c91e999c | |||
04d2a7f253 | |||
26ff8996b1 | |||
15fd90b641 | |||
5d4b0c4c80 | |||
2d9931d20c | |||
8aee48bdaa | |||
209c2880b9 | |||
8866eed097 | |||
876c8b3bd3 | |||
0f31f7b794 | |||
86b53e59d8 | |||
5990d92192 | |||
0873b688c6 | |||
b0a510ad2a | |||
745c3e7981 | |||
6bab30d071 | |||
fbae3d6f9e | |||
6d897fc671 | |||
f4e584decf | |||
1367954702 | |||
6b98a4b2e6 | |||
319992d4b6 | |||
26b7430773 | |||
f4786c1885 | |||
7ab1c25cc5 | |||
97656536e7 | |||
5465bc0c87 | |||
9d201a5c22 | |||
26798492e3 | |||
6828535669 | |||
878cc33a6a | |||
a02f57faa9 | |||
065ecf5162 | |||
f33b5792f7 | |||
23247a1efd | |||
5759a5ccb5 | |||
8bec4ff2f1 | |||
20e4e9872d | |||
b7b5e0c833 | |||
c85013b90d | |||
243f185742 | |||
381de90375 | |||
d3505ba895 | |||
457d46ca8c | |||
d84b36263c | |||
73ce5050e0 | |||
96f28f7f10 | |||
484460ec46 | |||
228a9ec312 | |||
7e02076624 | |||
5fb0de2e4d | |||
44477c57be | |||
5bd6271f59 | |||
536d1f8746 | |||
87b7e148e9 | |||
a4ca6e5d0f | |||
884b98add5 | |||
d442599a80 | |||
3ae0ab67e6 | |||
36a9c83de4 | |||
b0f996a6b1 | |||
018044c89f | |||
f877fed36f | |||
6aa27da287 | |||
9d96f1ce90 | |||
5eb3df8bdb | |||
a784784438 | |||
6b5c9936ec | |||
279084537f | |||
c0d9dfe2a1 | |||
fef8127c5f | |||
559644ddd2 | |||
9b76b08ae4 | |||
95d3b4de71 | |||
838d8c1b6b | |||
3fd2b1e9d0 | |||
d2dff42598 | |||
6889f33e8b | |||
cfa61a950a | |||
4d8e20f6c2 | |||
46e1a426f9 | |||
c04beb5d3a | |||
2dee896593 | |||
9cf70dad0f | |||
806d4d8140 | |||
552fe4cce6 | |||
a877575a88 | |||
baf2ff7e90 | |||
12ba43222d | |||
b8fbe5d5ba | |||
458b7099b2 | |||
e5a84d74a2 | |||
b1836a254e | |||
79052a76b5 | |||
69d044c034 | |||
2c27dfaeb1 | |||
9981fc5828 | |||
390645b346 | |||
a61e9ff60d | |||
e36da1bd8a | |||
4eedfd075e | |||
9a220665e7 | |||
27b3b303d9 | |||
9cba392768 | |||
fd9c052e6d | |||
818a966510 | |||
ef696300e6 | |||
5c09b81be7 | |||
52e3b3d1bb | |||
755a09b579 | |||
10d3272ec3 | |||
646b300773 | |||
7b2723c5c1 | |||
80710c69fe | |||
99e2505210 | |||
aa84f96666 | |||
d1249910b8 | |||
8f3d1669da | |||
c005e523b2 | |||
58d26a8ee9 | |||
777ffbd0e2 | |||
02e92dc470 | |||
07862822f3 | |||
46a1168129 | |||
04323fbcb4 | |||
dad15a2e02 | |||
94f776e716 | |||
de12bee7eb | |||
7fb50e300c | |||
c1bc3d892c | |||
e570d7c4d6 | |||
9f4b49cdfc | |||
ecbca76739 | |||
b767de4bdf | |||
0a71c79a34 | |||
1afcfbdda0 | |||
7c23c34d38 | |||
d09354786a | |||
80b077ee5e | |||
4040ff6638 | |||
5d784bd6d7 | |||
24b8be890d | |||
435b9d99cc | |||
618758c9b4 | |||
1518042bf3 | |||
57d91fca64 | |||
aaa937c0b6 | |||
0472f39f8b | |||
16e7b5fa24 | |||
5fa3d775a9 | |||
6ac6238de3 | |||
920487b36d | |||
a2b5c57db8 | |||
8f8258e1df | |||
f1409fa7c6 | |||
bf7676af30 | |||
dddbfcf6d6 | |||
f043ff6308 | |||
60be9e8c0e | |||
ce521f242a | |||
430156cf32 | |||
72851bb9ef | |||
219600c94e | |||
d60299c3ec | |||
df92bab4a8 | |||
f65eda365a | |||
9bc9999b6e | |||
d81eee40c2 | |||
2050b61dec | |||
4dadfe59d5 | |||
f319b553c1 | |||
78adf5099f | |||
08d56e24b0 | |||
5cf56c4b23 | |||
8b6d1a2068 | |||
c490b469ce | |||
c2969ec7ae | |||
c58d778d73 | |||
da8127e6b3 | |||
7f197559f2 | |||
33b55fd85a | |||
ebec21eee0 | |||
35abced2a8 | |||
9279bdf757 | |||
7ec6f7bd33 | |||
59f179ce64 | |||
b77b203cac | |||
83ad88b7bd | |||
bbbdc14854 | |||
c654ba8893 | |||
e648aee0f5 | |||
099dc93b7c | |||
b794d2a572 | |||
15d52307f9 | |||
ad2bb65c4a | |||
1223910ba8 | |||
ddf3bd32ce | |||
bc7b8c7e06 | |||
5bcbb3902f | |||
6aebc1943f | |||
bc61aa1211 | |||
22af84dc52 | |||
1c3e0eabce | |||
5907403716 | |||
db536236f4 | |||
521cc44700 | |||
16d7b3908e | |||
510823018e | |||
fe383bb541 | |||
f2013c9dd1 | |||
de6431a3d6 | |||
dca1a6b46f | |||
c5d2984c42 | |||
dbbe16c26e | |||
bab4f31c78 | |||
40baa1c899 | |||
82c1740ab9 | |||
cd016a46c7 | |||
0654d274e6 | |||
2e593ba518 | |||
d5c4067d7b | |||
696becb658 | |||
f399612c56 | |||
fd52b968b5 | |||
731f9a5e56 | |||
203b361f09 | |||
811886672d | |||
2d45ae5a01 | |||
6dd8532d96 | |||
4bb4109f7b | |||
91195b4321 | |||
8644a379d7 | |||
3addd15195 | |||
b59bb93129 | |||
5298551e07 | |||
892719f657 | |||
29879b550b | |||
70e015e12f | |||
3c797404a5 | |||
869b69ea3d | |||
fcd2bd55d7 | |||
f045583372 | |||
827a992a13 | |||
12062abb89 | |||
64703c03fc | |||
ae37001d78 | |||
cdd5ef7b07 | |||
652f887144 | |||
6cc9ee9b18 | |||
6c9e2eb23b | |||
92888c803b | |||
be5ec76630 | |||
8bdd603920 | |||
0664d41b55 | |||
c329db7180 | |||
be7bc4d5cc | |||
41bf4e721e | |||
30f555c6a8 | |||
a111b9e24f | |||
086608de34 | |||
0ec9a8c2f2 | |||
df1a00559c | |||
c0e4d4329c | |||
541ff63615 | |||
11c6e094e4 | |||
2a449549c1 | |||
9b706b2703 | |||
3d308f75c1 | |||
c7d1f5980b | |||
dd09da70f2 | |||
0c92e1428f | |||
b1b5b51ae8 | |||
b6dd366ad2 | |||
4ee8092dde | |||
1cf0e3db8b | |||
d1be48f976 | |||
3ca4296f80 | |||
a2f706de93 | |||
b1746239f2 | |||
beeab55908 | |||
46e8dc710a | |||
bd83b2a371 | |||
cc0e4e8ddb | |||
c20b7c9826 | |||
1cb031a2bb | |||
03d89991f2 | |||
b0889eae6a | |||
882e768ef0 | |||
63b2edc81c | |||
dc79852af8 | |||
ba6cbb182b | |||
75e3149264 | |||
2c1a3dd878 | |||
d82ce38415 | |||
62cb8ad7ff | |||
831977df56 | |||
45ad3d6962 | |||
05e2fc51d1 | |||
196acebbce | |||
f887334dcf | |||
cb61009236 | |||
1888363d8b | |||
c4111bd0d9 | |||
f858bcb2d6 | |||
c42e1c3947 | |||
508de7eedb | |||
61dbee0efd | |||
e485dcc9cb | |||
bcf974b94b | |||
e6966fa79a | |||
a55f18929b | |||
466f902446 | |||
2f0595244b | |||
bc4e5b43c2 | |||
d93a08eb47 | |||
42b23434b0 | |||
3abadf82d7 | |||
f84aedad09 | |||
e531f9a9d8 | |||
2b0803c64f | |||
7d7a7e291b | |||
08c4de5984 | |||
ad4036c34a | |||
a362f1f7aa | |||
675464b183 | |||
19ff0ddfbb | |||
b4c3be5943 | |||
891c6fd74f | |||
232392b1c6 | |||
21b5daa13d | |||
6d1c11e51c | |||
2ad83bf448 | |||
d6fb294346 | |||
619077b9eb | |||
6196fd1c28 | |||
d02c4a1877 | |||
809999b5a3 | |||
db3b32c4e1 | |||
2fdd441a4a | |||
ecd8725c1a | |||
43c2641c18 | |||
2895905a0b | |||
1726a736fb | |||
8e44e5593e | |||
14c22b3b64 | |||
d2d6776342 | |||
96fc478417 | |||
c2e9fab273 | |||
3acb664c56 | |||
018f2e5c9f | |||
e9f55e4688 | |||
4a075f7e7f | |||
3f2cb3ab59 | |||
b996110285 | |||
bc35f12a45 | |||
1ce3b61fa5 | |||
79cf07af7c | |||
4d4430e125 | |||
85d2810823 | |||
9ed46a3ed7 | |||
69d8c75333 | |||
b4a01cecd6 | |||
e99f01ecb6 | |||
a73e92ba08 | |||
1c90642f85 | |||
0257ba8f9f | |||
ef1065cf5a | |||
8fc40c511c | |||
829bce174c | |||
6f84e110d6 | |||
dd428d4798 | |||
247726bf38 | |||
f2fc1eee4c | |||
72f865dd23 | |||
b998f1f77c | |||
9d0ae85088 | |||
49ce282a6d | |||
8918fc8edf | |||
477d240778 | |||
9eba0d2591 | |||
2a0d75e5ee | |||
4e53546911 | |||
60290c84ad | |||
c5edc92071 | |||
799912fa05 | |||
011eeb4130 | |||
7f2498efe4 | |||
afc984af2e | |||
c9b37fee25 | |||
b14e7d2a16 | |||
498d783387 | |||
2acd4a1640 | |||
ae2bee4c5c | |||
a00c37f2f9 | |||
6c14439e51 | |||
9c7283166f | |||
9acaca7c24 | |||
07331bba6d | |||
db8ffc2dfb | |||
3a89819de8 | |||
4b4e4a69a8 | |||
6977fd95bf | |||
4d3d3e475f | |||
d1a366be05 | |||
a6e2ef732d | |||
dc675f3789 | |||
e0a07bb1f2 | |||
8277c15151 | |||
edd1295e1d | |||
c246b02586 | |||
9fd3bb7a88 | |||
2e0dbaad9b | |||
59e22b7258 | |||
ffe28ab74b | |||
f4c331a744 | |||
ee0d8c3b5c | |||
2f58ba8996 | |||
efa7fc9f75 | |||
1f80c3eb86 | |||
1c622a3d53 | |||
c843478ec8 | |||
d38897a5d4 | |||
3005cacb69 | |||
597fe3cee6 | |||
6337989089 | |||
9c21b44131 | |||
e702b5bab1 | |||
c111517a88 | |||
7807e05d43 | |||
35d52b56bb | |||
e03a62b456 | |||
88a993b129 | |||
89b6284fd9 | |||
d6f6b2d194 | |||
5b30b08d66 | |||
a891ffa446 | |||
6f66423e17 | |||
ddc882733a | |||
3d77d0a644 | |||
e91d27ee45 | |||
471235307f | |||
5a1f272875 | |||
ddc9036281 | |||
360aaafc63 | |||
07901bf235 | |||
8be115ff80 | |||
973fcd8fd3 | |||
2a95a3e976 | |||
8352e04d7e | |||
f609cb85ca | |||
0ce68c66c7 | |||
e2fb96d92b | |||
19f8c980ef | |||
3881a47088 | |||
8055e5af82 | |||
e88872e9a9 | |||
282fe1f08c | |||
bd18b9670f | |||
ece197e9d4 | |||
2b4d8deb6b | |||
90ec08ed73 | |||
af65695af0 | |||
6b3801b042 | |||
22a833e789 | |||
9f5e53e211 | |||
7afa6b4129 | |||
795fe9b2fa | |||
67555b2434 | |||
90ea06b88a | |||
cb231b4bee | |||
a31d65695d | |||
d4a965c6a8 | |||
7dc44eb059 | |||
25fb3ef1e1 | |||
88fe7a4ba5 | |||
7381aaff33 | |||
42c52d53c3 | |||
3cff66f487 | |||
c1ff5dc63d | |||
4813b3f094 | |||
162efa1a7c | |||
fdd14a9d05 | |||
f35bbf7be7 | |||
31710a5389 | |||
fdabeb3c5f | |||
f3ce59621f | |||
22c0d433ab | |||
33d11150b7 | |||
d6d54cd19e | |||
2e4b5243b2 | |||
8631bdc0c8 | |||
329f907b99 | |||
c554f6e18b | |||
e86789a5f2 | |||
6ee52c1b76 | |||
ddcd5674aa | |||
27758859c7 | |||
660cb2530f | |||
50c82157e1 | |||
55d88def95 | |||
449ae9c2f1 | |||
deff02a365 | |||
bf71201865 | |||
f0fe28cb8d | |||
c1665ba872 | |||
d4b9e06256 | |||
78d9325d1e | |||
57c95175e2 | |||
32620dabb1 | |||
cd592a91de | |||
c2d4b4f704 | |||
691ec08bac | |||
59d4b170fc | |||
7bc1c5cefe | |||
1282bd80f7 | |||
b12354befe | |||
d1535e668a | |||
b3fb288e52 | |||
1b72ad2eaa | |||
b6263c1801 | |||
6f2581edd7 | |||
9f3e724339 | |||
ffafede112 | |||
fd038a337b | |||
03388b6424 | |||
6af0c3e82b | |||
c2c713dd00 | |||
6ff9fc26d3 | |||
d07aa6a96f | |||
a91d3115b5 | |||
c32536e7da | |||
cab55fa0a8 | |||
0e5c4ab79c | |||
183383889a | |||
64bdec3841 | |||
2223b1f71f | |||
173015bec6 | |||
4521ffabeb | |||
27c8526053 | |||
71a0beaf3a | |||
e6b8bc812a | |||
bae460fc56 | |||
a71f8fc70f | |||
7e5f6a516c | |||
2137cb1911 | |||
5e3b0f8b57 | |||
e224b6f8fb | |||
4d6e6f4aa9 | |||
f2e7064373 | |||
5f57c48528 | |||
709b4c500d | |||
22d744d0c7 | |||
c4f91b144c | |||
6c7299d47d | |||
6b434da6bf | |||
ce93f64b1e | |||
7ac78e3237 | |||
855f768996 | |||
520d91f8bd | |||
4c85d96f27 | |||
b136266d57 | |||
3398eeda75 | |||
6766ff10dd | |||
5e47785b85 | |||
861dc84bb5 | |||
5495e45e70 | |||
d69d321086 | |||
2d533a465a | |||
eaddec976e | |||
b1643dc15c | |||
7ae740fcb1 | |||
3468bdafaf | |||
c0f025b8ba | |||
ba0c219902 | |||
131540277e | |||
6aa57af3e4 | |||
10b100240f | |||
678cd0f04b | |||
3a52b864dd | |||
fb6d616523 | |||
241cbc13ac | |||
0756e5ad92 | |||
172214bd30 | |||
0376f4a69b | |||
d4b53ef6cf | |||
4340b3ba40 | |||
5e495c8bd8 | |||
6ac47762bb | |||
49218c59b2 | |||
825d91cd31 | |||
dba7086fc3 | |||
9f5afc732c | |||
6611d9ebcc | |||
baac9c37d7 | |||
d89dd42d51 | |||
751304e367 | |||
e472fe25c7 | |||
5f98c43707 | |||
04682e694c | |||
ecc2735480 | |||
49186deda6 | |||
b9736d5b21 | |||
b3b4aba5d4 | |||
7d3390f802 | |||
aaa93ab6fa | |||
ea92a34d1d | |||
b375fc01e2 | |||
0f407570b4 | |||
4ffa7530a4 | |||
b14df8bec0 | |||
b32f8b1989 | |||
74c7567133 | |||
4dec4d414f | |||
322d1cfc78 | |||
310b09ec27 | |||
c811de8fb7 | |||
984840a2c2 | |||
dbf04dac3e | |||
108ca33357 | |||
531c858131 | |||
2ce90ea296 | |||
cfbccb3821 | |||
d48a0597e3 | |||
b4633113fc | |||
f682c25308 | |||
3cf37700cd | |||
57c7b40b76 | |||
f4765b691d | |||
6452b1eb5c | |||
34a01fc431 | |||
5abbf7b958 | |||
cd5544d412 | |||
17d64cab16 | |||
03172265d3 | |||
8231539830 | |||
73c0a148af | |||
d17101e011 | |||
3261761794 | |||
e8989ae4e2 | |||
52e2918ae1 | |||
5d30db09a6 | |||
70e4295bc4 | |||
f4287c7676 | |||
841a403f94 | |||
9e093f0b4c | |||
2a48b59dec | |||
24d3738f2d | |||
be427e8b0b | |||
c8a3a26513 | |||
e1da464d88 | |||
b7e5ca48f8 | |||
f80a4ed77a | |||
e48427051d | |||
e08adab31d | |||
2cc1ad61c7 | |||
cfe35a88f0 | |||
9a0ec36346 | |||
ce7244a014 | |||
977ba05973 | |||
447e4c466e | |||
594f564c75 | |||
6c55124f37 | |||
98369d314b | |||
398ce48d5c | |||
4a6ffae3b6 | |||
762101c7af | |||
d30d572650 | |||
e6d5d6105c | |||
23b4a3f95b | |||
6927887829 | |||
0de75e855b | |||
073ef15c87 | |||
ed009313b1 | |||
cdbb27e3bb | |||
839a5295ef | |||
e6cdb431bd | |||
5f5c6fde00 | |||
8c7477c481 | |||
77791dc0e1 | |||
b6bd2d3466 | |||
63e4af45f2 | |||
5ef1b6c54a | |||
3aa84653d1 | |||
2c4d7b5fa4 | |||
2280447962 | |||
8329c56e3a | |||
ae0dcbc413 | |||
02eab9cefd | |||
099d30a825 | |||
14c2ca3db9 | |||
f768b4c3e9 | |||
c86827a243 | |||
d69b79ab72 | |||
0634b62336 | |||
8d0be8fd57 | |||
44ebb18ec2 | |||
2ea9409a88 | |||
0c1813f4c9 | |||
9a87657a31 | |||
57ec8cedfc | |||
ed246fbb79 | |||
9160573d32 | |||
94b5dae479 | |||
e4047f0a10 | |||
00ef048f62 | |||
440d6b6a0b | |||
6915439794 | |||
3157d78f52 | |||
50ae1de27c | |||
d68b97c8a6 | |||
de5494d8a4 | |||
4e006b844f | |||
22da8c941c | |||
df97107787 | |||
082bcf1c5e | |||
193cd0f3c8 | |||
c03f7f1358 | |||
868453db1e | |||
c9ee3d2675 | |||
2f6239d068 | |||
f362a99a53 | |||
49b8d51edc | |||
a8be259d0c | |||
dd20328fbb | |||
513122ae93 | |||
c5b6537b1f | |||
343ab98229 | |||
f2ac5807b9 | |||
ef765169dd | |||
b590866bdb | |||
c0e5994aef | |||
cffba7ea3e | |||
f0a5eaf35f | |||
0ea479f8f6 | |||
ff81956ac6 | |||
1b3765fd34 | |||
a1e641a550 | |||
03e5f8bbbf | |||
f859919fed | |||
eb1e3143da | |||
99e4b30b39 | |||
ef79fb5b5f | |||
3f39a0bf27 | |||
b240f966d9 | |||
d9fcd17ec2 | |||
09d7eba99d | |||
c6a4c375fb | |||
867e751982 | |||
26fdb4173b | |||
9b382394d1 | |||
3f08212c3c | |||
9d5cef1872 | |||
1768bf63ed | |||
01e1ea1219 | |||
9a34ebd357 | |||
0d0bf8507c | |||
8d2319cb90 | |||
4ab0260956 | |||
f9a837da73 | |||
ad6cc26c8d | |||
63d15036cc | |||
d1bd3f57bc | |||
90feb02dd0 | |||
fb3cada0a0 | |||
9cfd2197e4 | |||
d58e91a812 | |||
eeb008dbfc | |||
9271367067 | |||
1c93fbbbe7 | |||
fe957f0a6f | |||
5c77d18b1b | |||
d5f969e130 | |||
831c81fcd4 | |||
f63930a7cc | |||
93fb3acc8d | |||
0302391ee6 | |||
652e55b7a5 | |||
4d349ef7be | |||
a4b4b6aa30 | |||
8fb9fdc3d9 | |||
7df6945d7f | |||
5622830c53 | |||
a44585972a | |||
4bfd0cf700 | |||
268cc6e9d1 | |||
7e853d6c1a | |||
4b7a8e9c0d | |||
59d042871c | |||
6f1bfd6de5 | |||
d6354c1696 | |||
85a954cebb | |||
677258ab02 | |||
567b8d69b9 | |||
2a667c34cb | |||
d0e83bd84f | |||
da4009ec40 | |||
18a68f7dce | |||
9e4de11807 | |||
c5cf6e14ab | |||
d1f144d6fe | |||
2fdf2173f3 | |||
2b9efcb3df | |||
e5f1f9de77 | |||
90074ecfa7 | |||
aaa98b08ff | |||
e2ed67a8b6 | |||
7373188219 | |||
a8923162c9 | |||
239322cbd4 | |||
c5d1592e20 | |||
5283ea9b1d | |||
c198d91667 | |||
b3ad9b9b80 | |||
6d37888e6a | |||
66a00e61a4 | |||
ed12c9ca7c | |||
bd789dff80 | |||
07f9b6f019 | |||
1a80a4e0d4 | |||
379efa109f | |||
6b01c83a63 | |||
f7e18208e1 | |||
637711cbdf | |||
3b8061c759 | |||
92509413e2 | |||
d489b04628 | |||
f50750b2d0 | |||
b31abc6f03 | |||
b976165ca4 | |||
4daeefac60 | |||
72082a054b | |||
152e810388 | |||
bfb485ced2 | |||
0696becacf | |||
d2a929d4b3 | |||
28d182506a | |||
a9f9545e12 | |||
58e668d2ea | |||
519a1c4379 | |||
12291656b1 | |||
1eb6647979 | |||
38149ec145 | |||
a779d2ff2d | |||
b1083a4c53 | |||
1700345708 | |||
934fdcb3c5 | |||
a9135359b4 | |||
04711a0f32 | |||
e9949a586a | |||
03caa988a6 | |||
b48e81bf94 | |||
40fd7073be | |||
07f4136993 | |||
524655eea2 | |||
a3d95b550b | |||
6fe5fde292 | |||
7b5fc59733 | |||
1edf5cc5b4 | |||
73838d331f | |||
6ec7195c01 | |||
64ce43f82c | |||
e4e69b4bb2 | |||
ab5eb92bbd | |||
2dd3f025a0 | |||
ba0219a752 | |||
3959fe300e | |||
427eaf13e2 | |||
ca79a4fb51 | |||
080bc4ea02 | |||
b6fe647b60 | |||
ad0b912384 | |||
360e5ea144 | |||
8e22e08935 | |||
5d804ffae4 | |||
4289114518 | |||
fbd5465a5b | |||
979b784be2 | |||
1468359f16 | |||
5e7d638ca0 | |||
d6fa4967bc | |||
fbdea7cb92 | |||
67a173c54f | |||
c4441fee10 | |||
f27f62ca69 | |||
fd7c172340 | |||
8e64f87306 | |||
e40725779c | |||
7818b7ef85 | |||
0bbf87e91e | |||
1151f0eee8 | |||
a71434054c | |||
e0a21dfef4 | |||
670c9f770b | |||
b14800af14 | |||
14800d49cb | |||
f53cc36fe8 | |||
3ea043254c | |||
4f550a129e | |||
574953309f | |||
83e849c197 | |||
39babffb73 | |||
67d33735ec | |||
ae8e08aa28 | |||
0f8552a2fb | |||
b26a9fa9c2 | |||
f81f63cd04 | |||
79591d4fbf | |||
543c266d2d | |||
789fc4ae90 | |||
e06c8ede42 | |||
7ea2ef4ce8 | |||
6198f3a1d7 | |||
06c0d1841c | |||
97ee0953c6 | |||
463e8c2ff0 | |||
74594c57f1 | |||
07b39a9418 | |||
8665f85523 | |||
fff9d71a65 | |||
73d4625a04 | |||
dde5681356 | |||
40143fb697 | |||
33ba6e6881 | |||
6f669d4ea5 | |||
08d3b0a2f8 | |||
40798fb0d2 | |||
80cafba310 | |||
2c32898c39 | |||
92f0a7f5af | |||
fab4f0c699 | |||
703d4ed594 | |||
aea883abc9 | |||
761bbb17c7 | |||
6a713b310a | |||
ca122578b3 | |||
ca92c85756 | |||
20135c704a | |||
e5adda7e6b | |||
8d733f4ef1 | |||
461e0f1a2d | |||
37754a74bb | |||
e962a57994 | |||
c8771867b8 | |||
f2845177e2 | |||
618b55220a | |||
3807d552c7 | |||
c147b93739 | |||
ceb0ed5d97 | |||
cf81318cb7 | |||
71d3026077 | |||
a59a99f218 | |||
3cbf5d5f76 | |||
e208c38b49 | |||
3d7320403b | |||
2682731d24 | |||
b8f36e74ad | |||
3fbc761552 | |||
f209333996 | |||
85aa40e26d | |||
c3fd09f7b7 | |||
5169e5ea38 | |||
088473b29f | |||
3349f2bb65 | |||
553115d3ca | |||
c444721b9d | |||
f580a33ffd | |||
c1710ca6a0 | |||
2de8aa8fd0 | |||
3e75c5ec85 | |||
ff98359d51 | |||
e17d3e7fe7 | |||
07d5d07383 | |||
52a12382b6 | |||
0983905c5a | |||
4ba3faac2c | |||
8cf1b7fc86 | |||
8d173c47b7 | |||
2bcad36889 | |||
e8f03b8fb6 | |||
f548480b7f | |||
76f40fa55f | |||
8ef4fe1425 | |||
5037cea55e | |||
9110941cfd | |||
23cbf1e0d4 | |||
36caaddde6 | |||
64bd1b9dd5 | |||
ba78d2cf89 | |||
833fe8abec | |||
01ed9b56d1 | |||
06dbfa6d21 | |||
017b840525 | |||
51fc56553f | |||
83d768fab8 | |||
1a81687ad2 | |||
a23476f0db | |||
307656b48a | |||
5b2d0bbc4c | |||
e6704af1fc | |||
ff340a84b8 | |||
361842881e | |||
24f717ac22 | |||
cec1d280ad | |||
90a422f071 | |||
0583825f3c | |||
52312385c0 | |||
65d68f62f1 | |||
f0c7103db5 | |||
7d612c3059 | |||
839f47b57f | |||
e6e90c8d70 | |||
b43070ebfc | |||
38ea116eba | |||
b253452942 | |||
b8adfcc60c | |||
109efd7941 | |||
7760eaa050 | |||
80a4ee4695 | |||
ebbae359ff | |||
accfe952eb | |||
eb7be6a606 | |||
4403646001 | |||
639f841346 | |||
9c5b190017 | |||
f532bfa297 | |||
2ceb35e1cd | |||
9a0e6a8fae | |||
2851d37855 | |||
d50bb45b1a | |||
6ddb83efcc | |||
62dee6fa48 | |||
df94811f71 | |||
00d3c5a603 | |||
aa14709a47 | |||
7518ad753f | |||
9693e29395 | |||
eb3143154e | |||
8a8b45b889 | |||
586765fb65 | |||
ecde731c72 | |||
874e65aa15 | |||
920ffe1b0a | |||
1428029738 | |||
c3ab6b2b53 | |||
b1c9bf27cb | |||
4540f8d227 | |||
6ca8d68d70 | |||
de2aa6cfc7 | |||
a07c81c4d0 | |||
b0b85c454c | |||
8e2e47803c | |||
3cfdc57b85 | |||
afe8839f01 | |||
2c85644b0b | |||
927dfcf693 | |||
3e5d48ef33 | |||
c2ddd53614 | |||
30c43afd73 | |||
2f4d2496a8 | |||
724819a10a | |||
a1092070d4 | |||
41828514bb | |||
17da0669e0 | |||
7931639b7a | |||
1740c38116 | |||
18d561c7a4 | |||
313ac7fd39 | |||
085d241531 | |||
8437e738fa | |||
c2dda6ebb3 | |||
a34e193fb7 | |||
94538e14e2 | |||
24442b60b9 | |||
de796a328d | |||
107ee906ff | |||
01374ec8b1 | |||
82162316b6 | |||
864e9457ca | |||
cd9a4232e5 | |||
2d2d6a01d7 | |||
693eac388f | |||
e123e1ee6b | |||
c7694e3e50 | |||
11bd53e322 | |||
416814e66a | |||
0c97dc4159 | |||
b2bf813e58 | |||
834ce603f9 | |||
d3f7c7b151 | |||
3ab1776b7f | |||
4a03db81cd | |||
4a6d4d4285 | |||
6bcd732ead | |||
6321fd9798 | |||
4ebfc42716 | |||
49826eda7a | |||
7976d96dd7 | |||
1aa5f85bb8 | |||
5dc404b71d | |||
222f6233b4 | |||
74d224fac3 | |||
3f81f8e4c1 | |||
dd0c42abd4 | |||
aaea56dc99 | |||
6e07f72ee5 | |||
2aa83b43d3 | |||
95eaf7ba7f | |||
9e8b7c1523 | |||
e07e9a9456 | |||
5d382c57a1 | |||
ab0b2c1996 | |||
8ce1afff88 | |||
6ae3052c06 | |||
8c58abeae1 | |||
d42b749abf | |||
0ac385bd6c | |||
20ce065124 | |||
bf8fba1e75 | |||
addaa5374c | |||
1e1f65312f | |||
0e4b921a57 | |||
dbf055efa0 | |||
0a8a79af53 | |||
cdb0e0dc3f | |||
6f9432fcaf | |||
1414cc5fdd | |||
cfd4370ad0 | |||
c69ba67032 | |||
f1c2c0e2dc | |||
06da1805bf | |||
e44bec2e34 | |||
f870c99b45 | |||
5ab8746f69 | |||
09a882bd4d | |||
56a77b4920 | |||
9f40b80ba8 | |||
92fa2e58fd | |||
df65adf136 | |||
d840fe93b0 | |||
27111b350f | |||
e5b9f355b0 | |||
e67bc20778 | |||
cd13dbb147 | |||
fb2a2e2611 | |||
53d03ba837 |
@ -11,4 +11,7 @@
|
||||
(sh-mode . (
|
||||
(indent-tabs-mode . nil)
|
||||
))
|
||||
(nxml-mode . (
|
||||
(indent-tabs-mode . nil)
|
||||
))
|
||||
)
|
||||
|
22
.gitignore
vendored
22
.gitignore
vendored
@ -5,6 +5,8 @@
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.gcov
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.orig
|
||||
*.rej
|
||||
@ -36,7 +38,10 @@
|
||||
/configure.lineno
|
||||
/daemon/*_dispatch.h
|
||||
/docs/hvsupport.html.in
|
||||
/gnulib/
|
||||
/docs/libvirt-qemu-*.xml
|
||||
/gnulib/lib/*
|
||||
/gnulib/m4/*
|
||||
/gnulib/tests/*
|
||||
/libtool
|
||||
/libvirt-*.tar.gz
|
||||
/libvirt-[0-9]*
|
||||
@ -50,16 +55,29 @@
|
||||
/mkinstalldirs
|
||||
/po/*
|
||||
/proxy/
|
||||
/python/generator.py.stamp
|
||||
/python/libvirt-qemu-export.c
|
||||
/python/libvirt-qemu.[ch]
|
||||
/python/libvirt_qemu.py
|
||||
/sc_*
|
||||
/src/hyperv/*.generated.*
|
||||
/src/libvirt_iohelper
|
||||
/src/locking/qemu-sanlock.conf
|
||||
/src/remote/*_client_bodies.h
|
||||
/src/remote/*_protocol.[ch]
|
||||
/src/rpc/virkeepaliveprotocol.[ch]
|
||||
/src/rpc/virnetprotocol.[ch]
|
||||
/src/util/virkeymaps.h
|
||||
/tests/*.log
|
||||
/tests/cputest
|
||||
/tests/domainsnapshotxml2xmltest
|
||||
/tests/hashtest
|
||||
/tests/jsontest
|
||||
/tests/networkxml2argvtest
|
||||
/tests/nwfilterxml2xmltest
|
||||
/tests/openvzutilstest
|
||||
/tests/qemuxmlnstest
|
||||
/tests/shunloadtest
|
||||
/update.log
|
||||
Makefile
|
||||
Makefile.in
|
||||
@ -71,6 +89,8 @@ results.log
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
!/gnulib/lib/Makefile.am
|
||||
!/gnulib/tests/Makefile.am
|
||||
!/m4/virt-*.m4
|
||||
!/po/*.po
|
||||
!/po/POTFILES.in
|
||||
|
2
.gnulib
2
.gnulib
Submodule .gnulib updated: cbfd25f0ed...6b93d00f54
14
.mailmap
14
.mailmap
@ -1,4 +1,6 @@
|
||||
# Format of each line:
|
||||
# 'git shortlog --help' and look for mailmap for the format of each line
|
||||
|
||||
# Email consolidation:
|
||||
# <Preferred address in AUTHORS> <other alias used by same author>
|
||||
|
||||
<amy.griffis@hp.com> <aron.griffis@hp.com>
|
||||
@ -13,7 +15,8 @@
|
||||
<meyering@redhat.com> <jim@meyering.net>
|
||||
<socketpair@gmail.com> <socketpair gmail com>
|
||||
<soren@linux2go.dk> <soren@ubuntu.com>
|
||||
<jfehlig@novell.com> <jfehlig@linux-ypgk.site>
|
||||
<jfehlig@suse.com> <jfehlig@novell.com>
|
||||
<jfehlig@suse.com> <jfehlig@linux-ypgk.site>
|
||||
<jclift@redhat.com> <justin@salasaga.org>
|
||||
<berrange@redhat.com> <dan@berrange.com>
|
||||
<soren@linux2go.dk> <soren@canonical.com>
|
||||
@ -22,3 +25,10 @@
|
||||
<cardoe@cardoe.com> <cardoe@gentoo.org>
|
||||
<fsimonce@redhat.com> <federico.simoncelli@gmail.com>
|
||||
<marcandre.lureau@redhat.com> <marcandre.lureau@gmail.com>
|
||||
<supriyak@linux.vnet.ibm.com> <supriyak@in.ibm.com>
|
||||
<neil@aldur.co.uk> <neil@brightbox.co.uk>
|
||||
<stefanb@us.ibm.com> <stefanb@linux.vnet.ibm.com>
|
||||
|
||||
# Name consolidation:
|
||||
# Preferred author spelling <preferred email>
|
||||
Alex Jia <ajia@redhat.com>
|
||||
|
41
AUTHORS
41
AUTHORS
@ -13,7 +13,7 @@ The primary maintainers and people with commit access rights:
|
||||
Mark McLoughlin <markmc@redhat.com>
|
||||
Anthony Liguori <aliguori@us.ibm.com>
|
||||
Jim Meyering <meyering@redhat.com>
|
||||
Jim Fehlig <jfehlig@novell.com>
|
||||
Jim Fehlig <jfehlig@suse.com>
|
||||
Chris Lalancette <clalance@redhat.com>
|
||||
Cole Robinson <crobinso@redhat.com>
|
||||
Guido Günther <agx@sigxcpu.org>
|
||||
@ -28,6 +28,8 @@ The primary maintainers and people with commit access rights:
|
||||
Osier Yang <jyang@redhat.com>
|
||||
Wen Congyang <wency@cn.fujitsu.com>
|
||||
Michal Prívozník <mprivozn@redhat.com>
|
||||
Peter Krempa <pkrempa@redhat.com>
|
||||
Christophe Fergeau <cfergeau@redhat.com>
|
||||
|
||||
Previous maintainers:
|
||||
Karel Zak <kzak@redhat.com>
|
||||
@ -156,7 +158,6 @@ Patches have also been contributed by:
|
||||
Zdenek Styblik <stybla@turnovfree.net>
|
||||
Gui Jianfeng <guijianfeng@cn.fujitsu.com>
|
||||
Michal Novotny <minovotn@redhat.com>
|
||||
Christophe Fergeau <cfergeau@redhat.com>
|
||||
Markus Groß <gross@univention.de>
|
||||
Phil Petty <phpetty@cisco.com>
|
||||
Taku Izumi <izumi.taku@jp.fujitsu.com>
|
||||
@ -169,7 +170,7 @@ Patches have also been contributed by:
|
||||
Richard Laager <rlaager@wiktel.com>
|
||||
Mark Wu <dwu@redhat.com>
|
||||
Yufang Zhang <yuzhang@redhat.com>
|
||||
Supriya Kannery <supriyak@in.ibm.com>
|
||||
Supriya Kannery <supriyak@linux.vnet.ibm.com>
|
||||
Dirk Herrendoerfer <d.herrendoerfer@herrendoerfer.name>
|
||||
Taisuke Yamada <tai@rakugaki.org>
|
||||
Heath Petersen <HeathPetersen@Kandre.com>
|
||||
@ -179,6 +180,40 @@ Patches have also been contributed by:
|
||||
Daniel Gollub <gollub@b1-systems.de>
|
||||
David S. Wang <dwang2@cisco.com>
|
||||
Ruben Kerkhof <ruben@rubenkerkhof.com>
|
||||
Scott Moser <smoser@ubuntu.com>
|
||||
Guannan Ren <gren@redhat.com>
|
||||
John Williams <john.williams@petalogix.com>
|
||||
Michael Santos <michael.santos@gmail.com>
|
||||
Alex Jia <ajia@redhat.com>
|
||||
Oskari Saarenmaa <os@ohmu.fi>
|
||||
Nan Zhang <nzhang@redhat.com>
|
||||
Wieland Hoffmann <themineo@googlemail.com>
|
||||
Douglas Schilling Landgraf <dougsland@redhat.com>
|
||||
Tom Vijlbrief <tom.vijlbrief@xs4all.nl>
|
||||
Shradha Shah <sshah@solarflare.com>
|
||||
Steve Hodgson <shodgson@solarflare.com>
|
||||
Xu He Jie <xuhj@linux.vnet.ibm.com>
|
||||
Lei Li <lilei@linux.vnet.ibm.com>
|
||||
Matthias Witte <witte@netzquadrat.de>
|
||||
Tang Chen <tangchen@cn.fujitsu.com>
|
||||
Dan Horák <dan@danny.cz>
|
||||
Sage Weil <sage@newdream.net>
|
||||
David L Stevens <dlstevens@us.ibm.com>
|
||||
Tyler Coumbes <coumbes@gmail.com>
|
||||
Josh Durgin <josh.durgin@dreamhost.com>
|
||||
Wen Ruo Lv <lvroyce@linux.vnet.ibm.com>
|
||||
Patrice LACHANCE <patlachance@gmail.com>
|
||||
Eli Qiao <taget@linux.vnet.ibm.com>
|
||||
Michael Wood <esiotrot@gmail.com>
|
||||
Bharata B Rao <bharata@linux.vnet.ibm.com>
|
||||
Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
|
||||
Chang Liu <lingjiao.lc@taobao.com>
|
||||
Lorin Hochstein <lorin@isi.edu>
|
||||
Christian Franke <nobody@nowhere.ws>
|
||||
Prerna Saxena <prerna@linux.vnet.ibm.com>
|
||||
Michael Ellerman <michael@ellerman.id.au>
|
||||
Rommer <rommer@active.by>
|
||||
Yuri Chornoivan <yurchor@ukr.net>
|
||||
|
||||
[....send patches to get your name here....]
|
||||
|
||||
|
9
HACKING
9
HACKING
@ -417,7 +417,7 @@ File handling
|
||||
Usage of the "fdopen()", "close()", "fclose()" APIs is deprecated in libvirt
|
||||
code base to help avoiding double-closing of files or file descriptors, which
|
||||
is particulary dangerous in a multi-threaded applications. Instead of these
|
||||
APIs, use the macros from files.h
|
||||
APIs, use the macros from virfile.h
|
||||
|
||||
- Open a file from a file descriptor:
|
||||
|
||||
@ -496,6 +496,13 @@ following semantically named macros
|
||||
|
||||
|
||||
|
||||
- To avoid having to check if a or b are NULL:
|
||||
|
||||
STREQ_NULLABLE(a, b)
|
||||
STRNEQ_NULLABLE(a, b)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
LCOV = lcov
|
||||
GENHTML = genhtml
|
||||
|
||||
|
21
autobuild.sh
21
autobuild.sh
@ -15,8 +15,11 @@ rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Run with options not normally exercised by the rpm build, for
|
||||
# more complete code coverage.
|
||||
../autogen.sh --prefix="$AUTOBUILD_INSTALL_ROOT" \
|
||||
--enable-test-coverage \
|
||||
--disable-nls \
|
||||
--enable-compile-warnings=error
|
||||
|
||||
# If the MAKEFLAGS envvar does not yet include a -j option,
|
||||
@ -61,6 +64,7 @@ if [ -f /usr/bin/rpmbuild ]; then
|
||||
-ba --clean libvirt.spec
|
||||
fi
|
||||
|
||||
# Test mingw cross-compile
|
||||
if [ -x /usr/bin/i686-pc-mingw32-gcc ]; then
|
||||
make distclean
|
||||
|
||||
@ -71,21 +75,8 @@ if [ -x /usr/bin/i686-pc-mingw32-gcc ]; then
|
||||
--host=i686-pc-mingw32 \
|
||||
--prefix="$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw" \
|
||||
--enable-compile-warnings=error \
|
||||
--without-sasl \
|
||||
--without-avahi \
|
||||
--without-polkit \
|
||||
--without-python \
|
||||
--without-xen \
|
||||
--without-qemu \
|
||||
--without-lxc \
|
||||
--without-uml \
|
||||
--without-vbox \
|
||||
--without-openvz \
|
||||
--without-phyp \
|
||||
--without-netcf \
|
||||
--without-audit \
|
||||
--without-dtrace \
|
||||
--without-libvirtd
|
||||
--without-libvirtd \
|
||||
--without-python
|
||||
|
||||
make
|
||||
make install
|
||||
|
@ -41,10 +41,13 @@ fi
|
||||
# is required. The first is just the SHA1 that selects a gnulib snapshot.
|
||||
# The second ensures that whenever we change the set of gnulib modules used
|
||||
# by this package, we rerun bootstrap to pull in the matching set of files.
|
||||
# The third ensures that whenever we change the set of local gnulib diffs,
|
||||
# we rerun bootstrap to pull in those diffs.
|
||||
bootstrap_hash()
|
||||
{
|
||||
git submodule status | sed 's/^[ +-]//;s/ .*//'
|
||||
git hash-object bootstrap.conf
|
||||
git ls-tree -d HEAD gnulib/local | awk '{print $3}'
|
||||
}
|
||||
|
||||
# Ensure that whenever we pull in a gnulib update or otherwise change to a
|
||||
|
17
bootstrap
17
bootstrap
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2011-06-22.06; # UTC
|
||||
scriptversion=2011-08-11.17; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
@ -800,20 +800,7 @@ slurp() {
|
||||
echo "$me: $dir/$file overrides $1/$dir/$file"
|
||||
else
|
||||
copied=$copied$sep$file; sep=$nl
|
||||
if test $file = gettext.m4; then
|
||||
echo "$me: patching m4/gettext.m4 to remove need for intl/* ..."
|
||||
rm -f $dir/$file
|
||||
sed '
|
||||
/^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
|
||||
AC_DEFUN([AM_INTL_SUBDIR], [])
|
||||
/^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
|
||||
AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
|
||||
$a\
|
||||
AC_DEFUN([gl_LOCK_EARLY], [])
|
||||
' $1/$dir/$file >$dir/$file
|
||||
else
|
||||
cp_mark_as_generated $1/$dir/$file $dir/$file
|
||||
fi
|
||||
cp_mark_as_generated $1/$dir/$file $dir/$file
|
||||
fi || exit
|
||||
done
|
||||
|
||||
|
@ -27,6 +27,7 @@ byteswap
|
||||
c-ctype
|
||||
c-strcase
|
||||
c-strcasestr
|
||||
calloc-posix
|
||||
canonicalize-lgpl
|
||||
chown
|
||||
close
|
||||
@ -35,8 +36,14 @@ configmake
|
||||
count-one-bits
|
||||
crypto/md5
|
||||
dirname-lgpl
|
||||
environ
|
||||
fclose
|
||||
fcntl
|
||||
fcntl-h
|
||||
fdatasync
|
||||
ffs
|
||||
fnmatch
|
||||
fsync
|
||||
func
|
||||
getaddrinfo
|
||||
getcwd-lgpl
|
||||
@ -52,6 +59,7 @@ ignore-value
|
||||
inet_pton
|
||||
intprops
|
||||
ioctl
|
||||
largefile
|
||||
listen
|
||||
maintainer-makefile
|
||||
manywarnings
|
||||
@ -60,6 +68,7 @@ mkstemps
|
||||
mktempd
|
||||
netdb
|
||||
nonblocking
|
||||
openpty
|
||||
passfd
|
||||
perror
|
||||
physmem
|
||||
@ -68,6 +77,7 @@ pipe2
|
||||
poll
|
||||
posix-shell
|
||||
pthread
|
||||
pthread_sigmask
|
||||
recv
|
||||
random_r
|
||||
sched
|
||||
@ -80,6 +90,7 @@ socket
|
||||
stdarg
|
||||
stpcpy
|
||||
strchrnul
|
||||
strdup-posix
|
||||
strndup
|
||||
strerror
|
||||
strerror_r-posix
|
||||
@ -91,12 +102,14 @@ sys_wait
|
||||
termios
|
||||
time_r
|
||||
timegm
|
||||
ttyname_r
|
||||
uname
|
||||
useless-if-before-free
|
||||
usleep
|
||||
vasprintf
|
||||
verify
|
||||
vc-list-files
|
||||
vsnprintf
|
||||
waitpid
|
||||
warnings
|
||||
'
|
||||
@ -147,18 +160,20 @@ fi
|
||||
|
||||
# Tell gnulib to:
|
||||
# require LGPLv2+
|
||||
# apply any local diffs in gnulib/local/ dir
|
||||
# put *.m4 files in new gnulib/m4/ dir
|
||||
# put *.[ch] files in new gnulib/lib/ dir.
|
||||
# import gnulib tests in new gnulib/tests/ dir.
|
||||
# put *.[ch] files in new gnulib/lib/ dir
|
||||
# import gnulib tests in new gnulib/tests/ dir
|
||||
gnulib_name=libgnu
|
||||
m4_base=gnulib/m4
|
||||
source_base=gnulib/lib
|
||||
tests_base=gnulib/tests
|
||||
gnulib_mk=Makefile.am
|
||||
gnulib_tool_option_extras="\
|
||||
--lgpl=2\
|
||||
--with-tests\
|
||||
--avoid=pt_chown\
|
||||
"
|
||||
local_gl_dir=gnulib/local
|
||||
|
||||
# Convince bootstrap to use multiple m4 directories.
|
||||
: ${ACLOCAL=aclocal}
|
||||
@ -166,6 +181,12 @@ ACLOCAL="$ACLOCAL -I m4"
|
||||
export ACLOCAL
|
||||
|
||||
# Build prerequisites
|
||||
# Note that some of these programs are only required for 'make dist' to
|
||||
# succeed from a fresh git checkout; not all of these programs are
|
||||
# required to run 'make dist' on a tarball. As a special case, we want
|
||||
# to require the equivalent of the Fedora python-devel package, but
|
||||
# RHEL 5 lacks the witness python-config package; we hack around that
|
||||
# old environment below.
|
||||
buildreq="\
|
||||
autoconf 2.59
|
||||
automake 1.9.6
|
||||
@ -174,11 +195,22 @@ gettext 0.17
|
||||
git 1.5.5
|
||||
gzip -
|
||||
libtool -
|
||||
patch -
|
||||
perl 5.5
|
||||
pkg-config -
|
||||
python-config -
|
||||
rpcgen -
|
||||
tar -
|
||||
xmllint -
|
||||
xsltproc -
|
||||
"
|
||||
# Use rpm as a fallback to bypass the bootstrap probe for python-config,
|
||||
# for the sake of RHEL 5; without requiring it on newer systems that
|
||||
# have python-config to begin with.
|
||||
if `(${PYTHON_CONFIG-python-config} --version;
|
||||
test $? -lt 126 || rpm -q python-devel) >/dev/null 2>&1`; then
|
||||
PYTHON_CONFIG=true
|
||||
fi
|
||||
|
||||
# Automake requires that ChangeLog exist.
|
||||
touch ChangeLog || exit 1
|
||||
@ -196,9 +228,9 @@ gnulib_extra_files="
|
||||
|
||||
bootstrap_epilogue()
|
||||
{
|
||||
# Change paths in gnulib/tests/Makefile.am from "../../.." to "../..",
|
||||
# Change paths in gnulib/tests/gnulib.mk from "../../.." to "../..",
|
||||
# then ensure that gnulib/tests/Makefile.in is up-to-date.
|
||||
m=gnulib/tests/Makefile.am
|
||||
m=gnulib/tests/gnulib.mk
|
||||
sed 's,\.\./\.\./\.\.,../..,g' $m > $m-t
|
||||
mv -f $m-t $m
|
||||
${AUTOMAKE-automake} gnulib/tests/Makefile
|
||||
|
100
cfg.mk
100
cfg.mk
@ -36,6 +36,9 @@ generated_files = \
|
||||
$(srcdir)/src/remote/*_protocol.[ch] \
|
||||
$(srcdir)/gnulib/lib/*.[ch]
|
||||
|
||||
# We haven't converted all scripts to using gnulib's init.sh yet.
|
||||
_test_script_regex = \<\(init\|test-lib\)\.sh\>
|
||||
|
||||
# Tests not to run as part of "make distcheck".
|
||||
local-checks-to-skip = \
|
||||
changelog-check \
|
||||
@ -74,7 +77,8 @@ local-checks-to-skip = \
|
||||
sc_useless_cpp_parens
|
||||
|
||||
# Files that should never cause syntax check failures.
|
||||
VC_LIST_ALWAYS_EXCLUDE_REGEX = (^(HACKING|docs/news\.html\.in)|\.po)$$
|
||||
VC_LIST_ALWAYS_EXCLUDE_REGEX = \
|
||||
(^(HACKING|docs/(news\.html\.in|.*\.patch))|\.po)$$
|
||||
|
||||
# Functions like free() that are no-ops on NULL arguments.
|
||||
useless_free_options = \
|
||||
@ -83,6 +87,7 @@ useless_free_options = \
|
||||
--name=qemuMigrationCookieFree \
|
||||
--name=qemuMigrationCookieGraphicsFree \
|
||||
--name=sexpr_free \
|
||||
--name=virBandwidthDefFree \
|
||||
--name=virBitmapFree \
|
||||
--name=virCPUDefFree \
|
||||
--name=virCapabilitiesFree \
|
||||
@ -96,6 +101,7 @@ useless_free_options = \
|
||||
--name=virCommandFree \
|
||||
--name=virConfFreeList \
|
||||
--name=virConfFreeValue \
|
||||
--name=virDomainActualNetDefFree \
|
||||
--name=virDomainChrDefFree \
|
||||
--name=virDomainChrSourceDefFree \
|
||||
--name=virDomainControllerDefFree \
|
||||
@ -118,6 +124,7 @@ useless_free_options = \
|
||||
--name=virDomainSoundDefFree \
|
||||
--name=virDomainVideoDefFree \
|
||||
--name=virDomainWatchdogDefFree \
|
||||
--name=virFileDirectFdFree \
|
||||
--name=virHashFree \
|
||||
--name=virInterfaceDefFree \
|
||||
--name=virInterfaceIpDefFree \
|
||||
@ -155,12 +162,15 @@ useless_free_options = \
|
||||
--name=virSecretDefFree \
|
||||
--name=virStorageEncryptionFree \
|
||||
--name=virStorageEncryptionSecretFree \
|
||||
--name=virStorageFileFreeMetadata \
|
||||
--name=virStoragePoolDefFree \
|
||||
--name=virStoragePoolObjFree \
|
||||
--name=virStoragePoolSourceFree \
|
||||
--name=virStorageVolDefFree \
|
||||
--name=virThreadPoolFree \
|
||||
--name=xmlBufferFree \
|
||||
--name=xmlFree \
|
||||
--name=xmlFreeDoc \
|
||||
--name=xmlXPathFreeContext \
|
||||
--name=xmlXPathFreeObject
|
||||
|
||||
@ -205,7 +215,7 @@ useless_free_options = \
|
||||
# y virDomainWatchdogDefFree
|
||||
# n virDrvNodeGetCellsFreeMemory (returns int)
|
||||
# n virDrvNodeGetFreeMemory (returns long long)
|
||||
# n virFree (dereferences param)
|
||||
# n virFree - dereferences param
|
||||
# n virFreeError
|
||||
# n virHashFree (takes 2 args)
|
||||
# y virInterfaceDefFree
|
||||
@ -268,6 +278,43 @@ sc_avoid_write:
|
||||
halt='consider using safewrite instead of write' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# In debug statements, print flags as bitmask and mode_t as octal.
|
||||
sc_flags_debug:
|
||||
@prohibit='\<mode=%[0-9.]*[diux]' \
|
||||
halt='use %o to debug mode_t values' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='[Ff]lags=%[0-9.]*l*[diou]' \
|
||||
halt='use %x to debug flag values' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Prefer 'unsigned int flags', along with checks for unknown flags.
|
||||
# For historical reasons, we are stuck with 'unsigned long flags' in
|
||||
# migration, so check for those known 4 instances and no more in public
|
||||
# API. Also check that no flags are marked unused, and 'unsigned' should
|
||||
# appear before any declaration of a flags variable (achieved by
|
||||
# prohibiting the word prior to the type from ending in anything other
|
||||
# than d). The existence of long long, and of documentation about
|
||||
# flags, makes the regex in the third test slightly harder.
|
||||
sc_flags_usage:
|
||||
@test "$$(cat $(srcdir)/include/libvirt/libvirt.h.in \
|
||||
$(srcdir)/include/libvirt/virterror.h \
|
||||
$(srcdir)/include/libvirt/libvirt-qemu.h \
|
||||
| grep -c '\(long\|unsigned\) flags')" != 4 && \
|
||||
{ echo '$(ME): new API should use "unsigned int flags"' 1>&2; \
|
||||
exit 1; } || :
|
||||
@prohibit=' flags ''ATTRIBUTE_UNUSED' \
|
||||
halt='flags should be checked with virCheckFlags' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='^[^@]*([^d] (int|long long)|[^dg] long) flags[;,)]' \
|
||||
halt='flags should be unsigned' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Avoid functions that should only be called via macro counterparts.
|
||||
sc_prohibit_internal_functions:
|
||||
@prohibit='vir(Free|AllocN?|ReallocN|File(Close|Fclose|Fdopen)) *\(' \
|
||||
halt='use VIR_ macros instead of internal functions' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Avoid functions that can lead to double-close bugs.
|
||||
sc_prohibit_close:
|
||||
@prohibit='([^>.]|^)\<[fp]?close *\(' \
|
||||
@ -403,6 +450,14 @@ sc_prohibit_xmlGetProp:
|
||||
halt='use virXMLPropString, not xmlGetProp' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# ATTRIBUTE_UNUSED should only be applied in implementations, not
|
||||
# header declarations
|
||||
sc_avoid_attribute_unused_in_header:
|
||||
@prohibit='^[^#]*ATTRIBUTE_UNUSED([^:]|$$)' \
|
||||
in_vc_files='\.h$$' \
|
||||
halt='use ATTRIBUTE_UNUSED in .c rather than .h files' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Many of the function names below came from this filter:
|
||||
# git grep -B2 '\<_('|grep -E '\.c- *[[:alpha:]_][[:alnum:]_]* ?\(.*[,;]$' \
|
||||
# |sed 's/.*\.c- *//'|perl -pe 's/ ?\(.*//'|sort -u \
|
||||
@ -411,6 +466,7 @@ sc_prohibit_xmlGetProp:
|
||||
msg_gen_function =
|
||||
msg_gen_function += ESX_ERROR
|
||||
msg_gen_function += ESX_VI_ERROR
|
||||
msg_gen_function += HYPERV_ERROR
|
||||
msg_gen_function += PHYP_ERROR
|
||||
msg_gen_function += VIR_ERROR
|
||||
msg_gen_function += VMX_ERROR
|
||||
@ -543,6 +599,9 @@ sc_copyright_format:
|
||||
@prohibit='Copyright [^(].*Red 'Hat \
|
||||
halt='consistently use (C) in Red Hat copyright' \
|
||||
$(_sc_search_regexp)
|
||||
@prohibit='\<Red''Hat\>' \
|
||||
halt='spell Red Hat as two words' \
|
||||
$(_sc_search_regexp)
|
||||
|
||||
# Some functions/macros produce messages intended solely for developers
|
||||
# and maintainers. Do not mark them for translation.
|
||||
@ -571,6 +630,7 @@ ifeq (0,$(MAKELEVEL))
|
||||
test -f po/Makevars || { echo 1; exit; }; \
|
||||
actual=$$(git submodule status | $(_submodule_hash); \
|
||||
git hash-object bootstrap.conf; \
|
||||
git ls-tree -d HEAD gnulib/local | awk '{print $$3}'; \
|
||||
git diff .gnulib); \
|
||||
stamp="$$($(_submodule_hash) $(_curr_status) 2>/dev/null)"; \
|
||||
test "$$stamp" = "$$actual"; echo $$?)
|
||||
@ -605,15 +665,29 @@ _autogen:
|
||||
# regenerate HACKING as part of the syntax-check
|
||||
syntax-check: $(top_srcdir)/HACKING
|
||||
|
||||
# sc_po_check can fail if generated files are not built first
|
||||
sc_po_check: \
|
||||
$(srcdir)/daemon/remote_dispatch.h \
|
||||
$(srcdir)/daemon/qemu_dispatch.h \
|
||||
$(srcdir)/src/remote/remote_client_bodies.h
|
||||
$(srcdir)/daemon/remote_dispatch.h: $(srcdir)/src/remote/remote_protocol.x
|
||||
$(MAKE) -C daemon remote_dispatch.h
|
||||
$(srcdir)/daemon/qemu_dispatch.h: $(srcdir)/src/remote/qemu_protocol.x
|
||||
$(MAKE) -C daemon qemu_dispatch.h
|
||||
$(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protocol.x
|
||||
$(MAKE) -C src remote/remote_client_bodies.h
|
||||
|
||||
# List all syntax-check exemptions:
|
||||
exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.c$$
|
||||
|
||||
_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket
|
||||
_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller
|
||||
exclude_file_name_regexp--sc_avoid_write = \
|
||||
^(src/($(_src1))|daemon/libvirtd|tools/console)\.c$$
|
||||
^(src/($(_src1))|daemon/libvirtd|tools/console|tests/(shunload|virnettlscontext)test)\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_bindtextdomain = ^(tests|examples)/
|
||||
|
||||
exclude_file_name_regexp--sc_flags_usage = ^docs/
|
||||
|
||||
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
|
||||
^src/rpc/gendispatch\.pl$$
|
||||
|
||||
@ -625,36 +699,38 @@ exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \
|
||||
exclude_file_name_regexp--sc_prohibit_access_xok = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
|
||||
(^docs|^python/(libvirt-override|typewrappers)\.c$$)
|
||||
^python/(libvirt-(qemu-)?override|typewrappers)\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_asprintf = \
|
||||
^(bootstrap.conf$$|src/util/util\.c$$|examples/domain-events/events-c/event-test\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_close = \
|
||||
(\.p[yl]$$|^docs/|(src/util/files\.c|src/libvirt\.c)$$)
|
||||
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c)$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
|
||||
(^docs/api_extension/|^tests/qemuhelpdata/|\.(gif|ico|png)$$)
|
||||
(^tests/qemuhelpdata/|\.(gif|ico|png)$$)
|
||||
|
||||
_src2=src/(util/command|libvirt|lxc/lxc_controller)
|
||||
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
|
||||
(^docs|^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$)
|
||||
(^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_gettext_noop = ^docs/
|
||||
exclude_file_name_regexp--sc_prohibit_internal_functions = \
|
||||
^src/(util/(memory|util|virfile)\.[hc]|esx/esx_vi\.c)$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
|
||||
^src/rpc/gendispatch\.pl$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_nonreentrant = \
|
||||
^((po|docs|tests)/|tools/(virsh|console)\.c$$)
|
||||
^((po|tests)/|docs/.*py$$|tools/(virsh|console)\.c$$)
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_readlink = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/util\.c$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_sprintf = ^(docs/|HACKING$$)
|
||||
exclude_file_name_regexp--sc_prohibit_sprintf = \
|
||||
^(docs/hacking\.html\.in)|(examples/systemtap/.*stp)|(src/dtrace2systemtap\.pl)|(src/rpc/gensystemtap\.pl)$$
|
||||
|
||||
exclude_file_name_regexp--sc_prohibit_strncpy = \
|
||||
^(src/util/util|tools/virsh)\.c$$
|
||||
@ -665,7 +741,7 @@ exclude_file_name_regexp--sc_require_config_h = ^examples/
|
||||
|
||||
exclude_file_name_regexp--sc_require_config_h_first = ^examples/
|
||||
|
||||
exclude_file_name_regexp--sc_trailing_blank = (^docs/|\.(fig|gif|ico|png)$$)
|
||||
exclude_file_name_regexp--sc_trailing_blank = \.(fig|gif|ico|png)$$
|
||||
|
||||
exclude_file_name_regexp--sc_unmarked_diagnostics = \
|
||||
^(docs/apibuild.py|tests/virt-aa-helper-test)$$
|
||||
|
279
configure.ac
279
configure.ac
@ -1,6 +1,9 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([libvirt], [0.9.2], [libvir-list@redhat.com], [], [http://libvirt.org])
|
||||
dnl Copyright (C) 2005-2012 Red Hat, Inc.
|
||||
dnl See COPYING.LIB for the License of this software
|
||||
|
||||
AC_INIT([libvirt], [0.9.9], [libvir-list@redhat.com], [], [http://libvirt.org])
|
||||
AC_CONFIG_SRCDIR([src/libvirt.c])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@ -66,9 +69,11 @@ XMLRPC_REQUIRED=1.14.0
|
||||
HAL_REQUIRED=0.5.0
|
||||
DEVMAPPER_REQUIRED=1.0.0
|
||||
LIBCURL_REQUIRED="7.18.0"
|
||||
OPENWSMAN_REQUIRED="2.2.3"
|
||||
LIBPCAP_REQUIRED="1.0.0"
|
||||
LIBNL_REQUIRED="1.1"
|
||||
LIBSSH2_REQUIRED="1.0"
|
||||
LIBBLKID_REQUIRED="2.17"
|
||||
|
||||
dnl Checks for C compiler.
|
||||
AC_PROG_CC
|
||||
@ -81,10 +86,6 @@ gl_INIT
|
||||
|
||||
AC_TYPE_UID_T
|
||||
|
||||
dnl Make sure we have an ANSI compiler
|
||||
AM_C_PROTOTYPES
|
||||
test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant])
|
||||
|
||||
dnl Support building Win32 DLLs (must appear *before* AM_PROG_LIBTOOL)
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
|
||||
@ -92,9 +93,18 @@ AM_PROG_LIBTOOL
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_LD
|
||||
|
||||
AC_MSG_CHECKING([for how to mark DSO non-deletable at runtime])
|
||||
LIBVIRT_NODELETE=
|
||||
`$LD --help 2>&1 | grep -- "-z nodelete" >/dev/null` && \
|
||||
LIBVIRT_NODELETE="-Wl,-z -Wl,nodelete"
|
||||
AC_MSG_RESULT([$LIBVIRT_NODELETE])
|
||||
AC_SUBST([LIBVIRT_NODELETE])
|
||||
|
||||
AC_MSG_CHECKING([for how to set DSO symbol versions])
|
||||
VERSION_SCRIPT_FLAGS=-Wl,--version-script=
|
||||
`$LD --help 2>&1 | grep -- --version-script >/dev/null` || \
|
||||
VERSION_SCRIPT_FLAGS="-Wl,-M -Wl,"
|
||||
AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS])
|
||||
|
||||
LIBVIRT_COMPILE_WARNINGS([maximum])
|
||||
|
||||
@ -121,22 +131,52 @@ AC_CHECK_SIZEOF([long])
|
||||
|
||||
dnl Availability of various common functions (non-fatal if missing),
|
||||
dnl and various less common threadsafe functions
|
||||
AC_CHECK_FUNCS_ONCE([cfmakeraw regexec sched_getaffinity getuid getgid \
|
||||
geteuid initgroups posix_fallocate mmap kill \
|
||||
getmntent_r getgrnam_r getpwuid_r])
|
||||
AC_CHECK_FUNCS_ONCE([cfmakeraw geteuid getgid getgrnam_r getmntent_r \
|
||||
getpwuid_r getuid initgroups kill mmap posix_fallocate posix_memalign \
|
||||
regexec sched_getaffinity])
|
||||
|
||||
dnl Availability of pthread functions (if missing, win32 threading is
|
||||
dnl assumed). Because of $LIB_PTHREAD, we cannot use AC_CHECK_FUNCS_ONCE.
|
||||
dnl LIB_PTHREAD was set during gl_INIT by gnulib.
|
||||
dnl LIB_PTHREAD and LIBMULTITHREAD were set during gl_INIT by gnulib.
|
||||
old_LIBS=$LIBS
|
||||
LIBS="$LIBS $LIB_PTHREAD"
|
||||
AC_CHECK_FUNCS([pthread_sigmask pthread_mutexattr_init])
|
||||
LIBS="$LIBS $LIB_PTHREAD $LIBMULTITHREAD"
|
||||
AC_CHECK_FUNCS([pthread_mutexattr_init])
|
||||
LIBS=$old_libs
|
||||
|
||||
old_LIBS=$LIBS
|
||||
RT_LIBS=
|
||||
LIBS="$LIBS $LIB_PTHREAD -lrt"
|
||||
AC_CHECK_FUNC([clock_gettime],[
|
||||
AC_DEFINE([HAVE_CLOCK_GETTIME],[],[Defined if clock_gettime() exists in librt.so])
|
||||
RT_LIBS=-lrt
|
||||
])
|
||||
LIBS=$old_libs
|
||||
AC_SUBST(RT_LIBS)
|
||||
|
||||
dnl Availability of various common headers (non-fatal if missing).
|
||||
AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \
|
||||
sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \
|
||||
sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h])
|
||||
sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h \
|
||||
net/if.h])
|
||||
|
||||
AC_MSG_CHECKING([for struct ifreq in net/if.h])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <net/if.h>
|
||||
]],
|
||||
[[
|
||||
struct ifreq ifr;
|
||||
]])],[
|
||||
AC_DEFINE([HAVE_STRUCT_IFREQ],[],[Defined if struct ifreq existsin net/if.h])
|
||||
AC_MSG_RESULT([yes])
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
])
|
||||
|
||||
dnl Our only use of libtasn1.h is in the testsuite, and can be skipped
|
||||
dnl if the header is not present. Assume -ltasn1 is present if the
|
||||
dnl header could be found.
|
||||
AM_CONDITIONAL([HAVE_LIBTASN1], [test "x$ac_cv_header_libtasn1_h" = "xyes"])
|
||||
|
||||
AC_CHECK_LIB([intl],[gettext],[])
|
||||
|
||||
@ -165,6 +205,8 @@ AC_PATH_PROG([RADVD], [radvd], [radvd],
|
||||
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
|
||||
AC_PATH_PROG([BRCTL], [brctl], [brctl],
|
||||
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
|
||||
AC_PATH_PROG([TC], [tc], [tc],
|
||||
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
|
||||
AC_PATH_PROG([UDEVADM], [udevadm], [],
|
||||
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
|
||||
AC_PATH_PROG([UDEVSETTLE], [udevsettle], [],
|
||||
@ -176,8 +218,8 @@ AC_DEFINE_UNQUOTED([DNSMASQ],["$DNSMASQ"],
|
||||
[Location or name of the dnsmasq program])
|
||||
AC_DEFINE_UNQUOTED([RADVD],["$RADVD"],
|
||||
[Location or name of the radvd program])
|
||||
AC_DEFINE_UNQUOTED([BRCTL],["$BRCTL"],
|
||||
[Location or name of the brctl program (see bridge-utils)])
|
||||
AC_DEFINE_UNQUOTED([TC],["$TC"],
|
||||
[Location or name of the tc profram (see iproute2)])
|
||||
if test -n "$UDEVADM"; then
|
||||
AC_DEFINE_UNQUOTED([UDEVADM],["$UDEVADM"],
|
||||
[Location or name of the udevadm program])
|
||||
@ -223,9 +265,10 @@ if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then
|
||||
fi
|
||||
|
||||
dnl Make some notes about which OS we're compiling for, as the lxc and qemu
|
||||
dnl drivers require linux headers, while storage_mpath and nwfilter are also
|
||||
dnl linux specific. The "network" and storage_fs drivers are known to not
|
||||
dnl work on MacOS X presently, so we also make a note if compiling for that
|
||||
dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter
|
||||
dnl are also linux specific. The "network" and storage_fs drivers are known
|
||||
dnl to not work on MacOS X presently, so we also make a note if compiling
|
||||
dnl for that
|
||||
|
||||
with_linux=no with_osx=no
|
||||
case $host in
|
||||
@ -242,6 +285,7 @@ if test $with_linux = no; then
|
||||
then
|
||||
with_qemu=no
|
||||
fi
|
||||
with_dtrace=no
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
|
||||
@ -275,6 +319,8 @@ AC_ARG_WITH([lxc],
|
||||
AC_HELP_STRING([--with-lxc], [add Linux Container support @<:@default=check@:>@]),[],[with_lxc=check])
|
||||
AC_ARG_WITH([esx],
|
||||
AC_HELP_STRING([--with-esx], [add ESX support @<:@default=check@:>@]),[],[with_esx=check])
|
||||
AC_ARG_WITH([hyperv],
|
||||
AC_HELP_STRING([--with-hyperv], [add Hyper-V support @<:@default=check@:>@]),[],[with_hyperv=check])
|
||||
AC_ARG_WITH([test],
|
||||
AC_HELP_STRING([--with-test], [add test driver support @<:@default=yes@:>@]),[],[with_test=yes])
|
||||
AC_ARG_WITH([remote],
|
||||
@ -305,16 +351,41 @@ dnl init script flavor
|
||||
dnl
|
||||
AC_MSG_CHECKING([for init script flavor])
|
||||
AC_ARG_WITH([init-script],
|
||||
[AC_HELP_STRING([--with-init-script=@<:@redhat|auto|none@:>@],
|
||||
[Style of init script to install @<:@default=auto@:>@])])
|
||||
if test "x$with_init_script" = "x" || test "x$with_init_script" = "xauto"; then
|
||||
if test "$cross_compiling" = yes || test ! -f /etc/redhat-release; then
|
||||
with_init_script=none
|
||||
else
|
||||
with_init_script=redhat
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test x$with_init_script = xredhat)
|
||||
[AC_HELP_STRING([--with-init-script@<:@=STYLE@:>@],
|
||||
[Style of init script to install: redhat, systemd, systemd+redhat,
|
||||
upstart, auto, none @<:@default=auto@:>@])],[],[with_init_script=check])
|
||||
init_redhat=no
|
||||
init_systemd=no
|
||||
init_upstart=no
|
||||
case "$with_init_script" in
|
||||
systemd+redhat)
|
||||
init_redhat=yes
|
||||
init_systemd=yes
|
||||
;;
|
||||
systemd)
|
||||
init_systemd=yes
|
||||
;;
|
||||
upstart)
|
||||
init_upstart=yes
|
||||
;;
|
||||
redhat)
|
||||
init_redhat=yes
|
||||
;;
|
||||
none)
|
||||
;;
|
||||
check)
|
||||
if test "$cross_compiling" != yes && test -f /etc/redhat-release; then
|
||||
init_redhat=yes
|
||||
with_init_script=redhat
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unknown initscript flavour $with_init_script])
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test "$init_redhat" = "yes")
|
||||
AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_UPSTART], test "$init_upstart" = "yes")
|
||||
AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_SYSTEMD], test "$init_systemd" = "yes")
|
||||
AC_MSG_RESULT($with_init_script)
|
||||
|
||||
dnl RHEL-5 has a peculiar version of Xen, which requires some special casing
|
||||
@ -662,8 +733,9 @@ fi
|
||||
if test "$with_lxc" = "yes" || test "$with_lxc" = "check"; then
|
||||
AC_TRY_LINK([
|
||||
#include <sched.h>
|
||||
#include <linux/loop.h>
|
||||
], [
|
||||
unshare (1);
|
||||
unshare (!LO_FLAGS_AUTOCLEAR);
|
||||
], [
|
||||
with_lxc=yes
|
||||
], [
|
||||
@ -822,20 +894,6 @@ fi
|
||||
AC_SUBST([GNUTLS_CFLAGS])
|
||||
AC_SUBST([GNUTLS_LIBS])
|
||||
|
||||
dnl Old versions of GnuTLS uses types like 'gnutls_session' instead
|
||||
dnl of 'gnutls_session_t'. Try to detect this type if defined so
|
||||
dnl that we can offer backwards compatibility.
|
||||
old_cflags="$CFLAGS"
|
||||
old_libs="$LIBS"
|
||||
CFLAGS="$CFLAGS $GNUTLS_CFLAGS"
|
||||
LIBS="$LIBS $GNUTLS_LIBS"
|
||||
AC_CHECK_TYPE([gnutls_session],
|
||||
AC_DEFINE([GNUTLS_1_0_COMPAT],[],
|
||||
[enable GnuTLS 1.0 compatibility macros]),,
|
||||
[#include <gnutls/gnutls.h>])
|
||||
CFLAGS="$old_cflags"
|
||||
LIBS="$old_libs"
|
||||
|
||||
|
||||
dnl Cyrus SASL
|
||||
AC_ARG_WITH([sasl],
|
||||
@ -952,7 +1010,7 @@ AC_SUBST([YAJL_LIBS])
|
||||
|
||||
dnl SANLOCK https://fedorahosted.org/sanlock/
|
||||
AC_ARG_WITH([sanlock],
|
||||
AC_HELP_STRING([--with-sanlock], [use SANLOCK for lock management @<:@default=check@:>@]),
|
||||
AC_HELP_STRING([--with-sanlock], [build Sanlock plugin for lock management @<:@default=check@:>@]),
|
||||
[],
|
||||
[with_sanlock=check])
|
||||
|
||||
@ -975,8 +1033,8 @@ if test "x$with_sanlock" != "xno"; then
|
||||
fail=1
|
||||
fi])
|
||||
if test "x$with_sanlock" != "xno" ; then
|
||||
AC_CHECK_LIB([sanlock], [sanlock_restrict],[
|
||||
SANLOCK_LIBS="$SANLOCK_LIBS -lsanlock"
|
||||
AC_CHECK_LIB([sanlock_client], [sanlock_init],[
|
||||
SANLOCK_LIBS="$SANLOCK_LIBS -lsanlock_client"
|
||||
with_sanlock=yes
|
||||
],[
|
||||
if test "x$with_sanlock" = "xcheck" ; then
|
||||
@ -987,12 +1045,12 @@ if test "x$with_sanlock" != "xno"; then
|
||||
])
|
||||
fi
|
||||
test $fail = 1 &&
|
||||
AC_MSG_ERROR([You must install the SANLOCK development package in order to compile libvirt])
|
||||
AC_MSG_ERROR([You must install the Sanlock development package in order to compile libvirt])
|
||||
CPPFLAGS="$old_cppflags"
|
||||
LIBS="$old_libs"
|
||||
if test "x$with_sanlock" = "xyes" ; then
|
||||
AC_DEFINE_UNQUOTED([HAVE_SANLOCK], 1,
|
||||
[whether SANLOCK is available for JSON parsing/formatting])
|
||||
[whether Sanlock plugin for lock management is available])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_SANLOCK], [test "x$with_sanlock" = "xyes"])
|
||||
@ -1010,6 +1068,7 @@ AC_ARG_WITH([polkit],
|
||||
[with_polkit=check])
|
||||
|
||||
with_polkit0=no
|
||||
with_dbus=no
|
||||
with_polkit1=no
|
||||
if test "x$with_polkit" = "xyes" || test "x$with_polkit" = "xcheck"; then
|
||||
dnl Check for new polkit first - just a binary
|
||||
@ -1038,6 +1097,8 @@ if test "x$with_polkit" = "xyes" || test "x$with_polkit" = "xcheck"; then
|
||||
[use PolicyKit for UNIX socket access checks])
|
||||
AC_DEFINE_UNQUOTED([HAVE_POLKIT0], 1,
|
||||
[use PolicyKit for UNIX socket access checks])
|
||||
AC_DEFINE_UNQUOTED([HAVE_DBUS], 1,
|
||||
[use DBus for PolicyKit])
|
||||
|
||||
old_CFLAGS=$CFLAGS
|
||||
old_LIBS=$LIBS
|
||||
@ -1052,11 +1113,13 @@ if test "x$with_polkit" = "xyes" || test "x$with_polkit" = "xcheck"; then
|
||||
AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
|
||||
fi
|
||||
with_polkit0="yes"
|
||||
with_dbus="yes"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_POLKIT], [test "x$with_polkit" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_POLKIT0], [test "x$with_polkit0" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_DBUS], [test "x$with_dbus" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_POLKIT1], [test "x$with_polkit1" = "xyes"])
|
||||
AC_SUBST([POLKIT_CFLAGS])
|
||||
AC_SUBST([POLKIT_LIBS])
|
||||
@ -1637,12 +1700,15 @@ fi
|
||||
if test "$with_storage_fs" = "yes" || test "$with_storage_fs" = "check"; then
|
||||
AC_PATH_PROG([MOUNT], [mount], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([UMOUNT], [umount], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([MKFS], [mkfs], [], [$PATH:/sbin:/usr/sbin])
|
||||
if test "$with_storage_fs" = "yes" ; then
|
||||
if test -z "$MOUNT" ; then AC_MSG_ERROR([We need mount for FS storage driver]) ; fi
|
||||
if test -z "$UMOUNT" ; then AC_MSG_ERROR([We need umount for FS storage driver]) ; fi
|
||||
if test -z "$MKFS" ; then AC_MSG_ERROR([We need mkfs for FS storage driver]) ; fi
|
||||
else
|
||||
if test -z "$MOUNT" ; then with_storage_fs=no ; fi
|
||||
if test -z "$UMOUNT" ; then with_storage_fs=no ; fi
|
||||
if test -z "$MKFS" ; then with_storage_fs=no ; fi
|
||||
|
||||
if test "$with_storage_fs" = "check" ; then with_storage_fs=yes ; fi
|
||||
fi
|
||||
@ -1653,6 +1719,8 @@ if test "$with_storage_fs" = "yes" || test "$with_storage_fs" = "check"; then
|
||||
[Location or name of the mount program])
|
||||
AC_DEFINE_UNQUOTED([UMOUNT],["$UMOUNT"],
|
||||
[Location or name of the mount program])
|
||||
AC_DEFINE_UNQUOTED([MKFS],["$MKFS"],
|
||||
[Location or name of the mkfs program])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_STORAGE_FS], [test "$with_storage_fs" = "yes"])
|
||||
@ -1669,6 +1737,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
|
||||
AC_PATH_PROG([PVREMOVE], [pvremove], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([VGREMOVE], [vgremove], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([LVREMOVE], [lvremove], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([LVCHANGE], [lvchange], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([VGCHANGE], [vgchange], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([VGSCAN], [vgscan], [], [$PATH:/sbin:/usr/sbin])
|
||||
AC_PATH_PROG([PVS], [pvs], [], [$PATH:/sbin:/usr/sbin])
|
||||
@ -1682,6 +1751,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
|
||||
if test -z "$PVREMOVE" ; then AC_MSG_ERROR([We need pvremove for LVM storage driver]) ; fi
|
||||
if test -z "$VGREMOVE" ; then AC_MSG_ERROR([We need vgremove for LVM storage driver]) ; fi
|
||||
if test -z "$LVREMOVE" ; then AC_MSG_ERROR([We need lvremove for LVM storage driver]) ; fi
|
||||
if test -z "$LVCHANGE" ; then AC_MSG_ERROR([We need lvchange for LVM storage driver]) ; fi
|
||||
if test -z "$VGCHANGE" ; then AC_MSG_ERROR([We need vgchange for LVM storage driver]) ; fi
|
||||
if test -z "$VGSCAN" ; then AC_MSG_ERROR([We need vgscan for LVM storage driver]) ; fi
|
||||
if test -z "$PVS" ; then AC_MSG_ERROR([We need pvs for LVM storage driver]) ; fi
|
||||
@ -1694,6 +1764,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
|
||||
if test -z "$PVREMOVE" ; then with_storage_lvm=no ; fi
|
||||
if test -z "$VGREMOVE" ; then with_storage_lvm=no ; fi
|
||||
if test -z "$LVREMOVE" ; then with_storage_lvm=no ; fi
|
||||
if test -z "$LVCHANGE" ; then with_storage_lvm=no ; fi
|
||||
if test -z "$VGCHANGE" ; then with_storage_lvm=no ; fi
|
||||
if test -z "$VGSCAN" ; then with_storage_lvm=no ; fi
|
||||
if test -z "$PVS" ; then with_storage_lvm=no ; fi
|
||||
@ -1711,6 +1782,7 @@ if test "$with_storage_lvm" = "yes" || test "$with_storage_lvm" = "check"; then
|
||||
AC_DEFINE_UNQUOTED([PVREMOVE],["$PVREMOVE"],[Location of pvremove program])
|
||||
AC_DEFINE_UNQUOTED([VGREMOVE],["$VGREMOVE"],[Location of vgremove program])
|
||||
AC_DEFINE_UNQUOTED([LVREMOVE],["$LVREMOVE"],[Location of lvremove program])
|
||||
AC_DEFINE_UNQUOTED([LVCHANGE],["$LVCHANGE"],[Location of lvchange program])
|
||||
AC_DEFINE_UNQUOTED([VGCHANGE],["$VGCHANGE"],[Location of vgchange program])
|
||||
AC_DEFINE_UNQUOTED([VGSCAN],["$VGSCAN"],[Location of vgscan program])
|
||||
AC_DEFINE_UNQUOTED([PVS],["$PVS"],[Location of pvs program])
|
||||
@ -1907,6 +1979,35 @@ LIBCURL_CFLAGS="-DCURL_DISABLE_TYPECHECK $LIBCURL_CFLAGS"
|
||||
AC_SUBST([LIBCURL_CFLAGS])
|
||||
AC_SUBST([LIBCURL_LIBS])
|
||||
|
||||
|
||||
dnl
|
||||
dnl check for openwsman (Hyper-V)
|
||||
dnl
|
||||
|
||||
OPENWSMAN_CFLAGS=""
|
||||
OPENWSMAN_LIBS=""
|
||||
|
||||
if test "$with_hyperv" = "yes" || test "$with_hyperv" = "check"; then
|
||||
PKG_CHECK_MODULES([OPENWSMAN], [openwsman >= $OPENWSMAN_REQUIRED], [
|
||||
if test "$with_hyperv" = "check"; then
|
||||
with_hyperv=yes
|
||||
fi
|
||||
], [
|
||||
if test "$with_hyperv" = "check"; then
|
||||
with_hyperv=no
|
||||
AC_MSG_NOTICE([openwsman is required for the Hyper-V driver, disabling it])
|
||||
elif test "$with_hyperv" = "yes"; then
|
||||
AC_MSG_ERROR([openwsman >= $OPENWSMAN_REQUIRED is required for the Hyper-V driver])
|
||||
fi
|
||||
])
|
||||
fi
|
||||
|
||||
if test "$with_hyperv" = "yes" ; then
|
||||
AC_DEFINE_UNQUOTED([WITH_HYPERV], 1, [whether Hyper-V driver is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_HYPERV], [test "$with_hyperv" = "yes"])
|
||||
|
||||
|
||||
dnl
|
||||
dnl check for python
|
||||
dnl
|
||||
@ -1982,30 +2083,6 @@ AM_CONDITIONAL([WITH_PYTHON], [test "$with_python" = "yes"])
|
||||
AC_SUBST([PYTHON_VERSION])
|
||||
AC_SUBST([PYTHON_INCLUDES])
|
||||
|
||||
|
||||
|
||||
AC_MSG_CHECKING([whether this host is running a Xen kernel])
|
||||
RUNNING_XEN=
|
||||
if test -d /proc/sys/xen
|
||||
then
|
||||
RUNNING_XEN=yes
|
||||
else
|
||||
RUNNING_XEN=no
|
||||
fi
|
||||
AC_MSG_RESULT($RUNNING_XEN)
|
||||
|
||||
AC_MSG_CHECKING([If XenD UNIX socket /var/run/xend/xmlrpc.sock is accessible])
|
||||
RUNNING_XEND=
|
||||
if test -S /var/run/xend/xmlrpc.sock
|
||||
then
|
||||
RUNNING_XEND=yes
|
||||
else
|
||||
RUNNING_XEND=no
|
||||
fi
|
||||
AC_MSG_RESULT($RUNNING_XEND)
|
||||
|
||||
AM_CONDITIONAL([ENABLE_XEN_TESTS], [test "$RUNNING_XEN" != "no" && test "$RUNNING_XEND" != "no"])
|
||||
|
||||
AC_ARG_ENABLE([test-coverage],
|
||||
AC_HELP_STRING([--enable-test-coverage], [turn on code coverage instrumentation @<:@default=no@:>@]),
|
||||
[case "${enableval}" in
|
||||
@ -2065,8 +2142,30 @@ dnl Enable building libvirtd?
|
||||
AM_CONDITIONAL([WITH_LIBVIRTD],[test "x$with_libvirtd" = "xyes"])
|
||||
|
||||
dnl Check for gettext - don't go any newer than what RHEL 5 supports
|
||||
dnl
|
||||
dnl save and restore CPPFLAGS around gettext check as the internal iconv
|
||||
dnl check might leave -I/usr/local/include in CPPFLAGS on FreeBSD resulting
|
||||
dnl in the build picking up previously installed libvirt/libvirt.h instead
|
||||
dnl of the correct one from the source tree.
|
||||
dnl compute the difference between save_CPPFLAGS and CPPFLAGS and append it
|
||||
dnl to INCLUDES in order to preserve changes made by gettext but in a place
|
||||
dnl that does not break the build
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
AM_GNU_GETTEXT_VERSION([0.17])
|
||||
AM_GNU_GETTEXT([external])
|
||||
GETTEXT_CPPFLAGS=
|
||||
if test "x$save_CPPFLAGS" != "x$CPPFLAGS"; then
|
||||
set dummy $CPPFLAGS; shift
|
||||
for var
|
||||
do
|
||||
case " $var " in
|
||||
" $save_CPPFLAGS ") ;;
|
||||
*) GETTEXT_CPPFLAGS="$GETTEXT_CPPFLAGS $var" ;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
AC_SUBST([GETTEXT_CPPFLAGS])
|
||||
|
||||
ALL_LINGUAS=`cd "$srcdir/po" > /dev/null && ls *.po | sed 's+\.po$++'`
|
||||
|
||||
@ -2271,6 +2370,26 @@ if test "$with_nwfilter" = "yes" ; then
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_NWFILTER], [test "$with_nwfilter" = "yes"])
|
||||
|
||||
dnl libblkid is used by several storage drivers; therefore we probe
|
||||
dnl for it unconditionally.
|
||||
AC_ARG_WITH([libblkid],
|
||||
[AS_HELP_STRING([--with-libblkid],
|
||||
[use libblkid to scan for filesystems and partitions @<:@default=check@:>@])],
|
||||
[],
|
||||
[with_libblkid=check])
|
||||
|
||||
if test "x$with_libblkid" = "xyes" || test "x$with_libblkid" = "xcheck"; then
|
||||
PKG_CHECK_MODULES([BLKID],
|
||||
[blkid >= $LIBBLKID_REQUIRED],
|
||||
[with_libblkid="yes"],
|
||||
[with_libblkid="no"])
|
||||
fi
|
||||
|
||||
if test "x$with_libblkid" = "xyes"; then
|
||||
AC_DEFINE([HAVE_LIBBLKID], [1], [libblkid is present])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_LIBBLKID], [test "x$with_libblkid" = "xyes"])
|
||||
|
||||
AC_ARG_WITH([qemu-user],
|
||||
AC_HELP_STRING([--with-qemu-user], [username to run QEMU system instance as @<:@default=root@:>@]),
|
||||
[QEMU_USER=${withval}],
|
||||
@ -2389,9 +2508,16 @@ cp -f COPYING.LIB COPYING
|
||||
|
||||
# Detect when running under the clang static analyzer's scan-build driver
|
||||
# or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly.
|
||||
AC_CACHE_CHECK([whether this build is done by a static analysis tool],
|
||||
[lv_cv_static_analysis], [
|
||||
lv_cv_static_analysis=no
|
||||
if test -n "${CCC_ANALYZER_ANALYSIS+set}" || \
|
||||
test -n "$COVERITY_BUILD_COMMAND$COVERITY_LD_PRELOAD"; then
|
||||
lv_cv_static_analysis=yes
|
||||
fi
|
||||
])
|
||||
t=0
|
||||
test -n "${CCC_ANALYZER_ANALYSIS+set}" && t=1
|
||||
test -n "$COVERITY_BUILD_COMMAND$COVERITY_LD_PRELOAD" && t=1
|
||||
test "x$lv_cv_static_analysis" = xyes && t=1
|
||||
AC_DEFINE_UNQUOTED([STATIC_ANALYSIS], [$t],
|
||||
[Define to 1 when performing static analysis.])
|
||||
|
||||
@ -2433,6 +2559,7 @@ AC_MSG_NOTICE([xenlight: $with_libxl])
|
||||
AC_MSG_NOTICE([ LXC: $with_lxc])
|
||||
AC_MSG_NOTICE([ PHYP: $with_phyp])
|
||||
AC_MSG_NOTICE([ ESX: $with_esx])
|
||||
AC_MSG_NOTICE([ Hyper-V: $with_hyperv])
|
||||
AC_MSG_NOTICE([ Test: $with_test])
|
||||
AC_MSG_NOTICE([ Remote: $with_remote])
|
||||
AC_MSG_NOTICE([ Network: $with_network])
|
||||
@ -2474,6 +2601,11 @@ AC_MSG_NOTICE([ libcurl: $LIBCURL_CFLAGS $LIBCURL_LIBS])
|
||||
else
|
||||
AC_MSG_NOTICE([ libcurl: no])
|
||||
fi
|
||||
if test "$with_hyperv" = "yes" ; then
|
||||
AC_MSG_NOTICE([openwsman: $OPENWSMAN_CFLAGS $OPENWSMAN_LIBS])
|
||||
else
|
||||
AC_MSG_NOTICE([openwsman: no])
|
||||
fi
|
||||
if test "$with_libssh2" != "no" ; then
|
||||
AC_MSG_NOTICE([ libssh2: $LIBSSH2_CFLAGS $LIBSSH2_LIBS])
|
||||
else
|
||||
@ -2599,6 +2731,7 @@ AC_MSG_NOTICE([ Readline: $lv_use_readline])
|
||||
AC_MSG_NOTICE([ Python: $with_python])
|
||||
AC_MSG_NOTICE([ DTrace: $with_dtrace])
|
||||
AC_MSG_NOTICE([ XML Catalog: $XML_CATALOG_FILE])
|
||||
AC_MSG_NOTICE([ Init script: $with_init_script])
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_NOTICE([Privileges])
|
||||
AC_MSG_NOTICE([])
|
||||
|
1
daemon/.gitignore
vendored
1
daemon/.gitignore
vendored
@ -7,6 +7,7 @@ Makefile.in
|
||||
libvirt_qemud
|
||||
libvirtd
|
||||
libvirtd.init
|
||||
libvirtd.service
|
||||
libvirtd*.logrotate
|
||||
libvirtd.8
|
||||
libvirtd.8.in
|
||||
|
@ -1,5 +1,18 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/gnulib/lib -I../gnulib/lib \
|
||||
-I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/src -I../src \
|
||||
-I$(top_srcdir)/src/util \
|
||||
-I$(top_srcdir)/src/conf \
|
||||
-I$(top_srcdir)/src/rpc \
|
||||
-I$(top_srcdir)/src/remote \
|
||||
$(GETTEXT_CPPFLAGS)
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
DAEMON_GENERATED = \
|
||||
@ -25,6 +38,7 @@ EXTRA_DIST = \
|
||||
libvirtd.policy-1 \
|
||||
libvirtd.sasl \
|
||||
libvirtd.sysconf \
|
||||
libvirtd.sysctl \
|
||||
libvirtd.aug \
|
||||
libvirtd.logrotate.in \
|
||||
libvirtd.qemu.logrotate.in \
|
||||
@ -34,7 +48,6 @@ EXTRA_DIST = \
|
||||
THREADS.txt \
|
||||
libvirtd.pod.in \
|
||||
libvirtd.8.in \
|
||||
libvirtd.stp \
|
||||
$(DAEMON_SOURCES)
|
||||
|
||||
BUILT_SOURCES =
|
||||
@ -44,7 +57,7 @@ QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
|
||||
|
||||
$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
|
||||
$(REMOTE_PROTOCOL)
|
||||
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c -b remote \
|
||||
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -b remote \
|
||||
$(REMOTE_PROTOCOL) > $@
|
||||
|
||||
$(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
|
||||
@ -79,13 +92,6 @@ libvirtd_SOURCES = $(DAEMON_SOURCES)
|
||||
|
||||
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
|
||||
libvirtd_CFLAGS = \
|
||||
-I$(top_srcdir)/gnulib/lib -I../gnulib/lib \
|
||||
-I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/util \
|
||||
-I$(top_srcdir)/src/conf \
|
||||
-I$(top_srcdir)/src/rpc \
|
||||
-I$(top_srcdir)/src/remote \
|
||||
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
|
||||
$(XDR_CFLAGS) $(POLKIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
@ -103,9 +109,11 @@ libvirtd_LDADD = \
|
||||
$(SASL_LIBS) \
|
||||
$(POLKIT_LIBS)
|
||||
|
||||
if WITH_DTRACE
|
||||
libvirtd_LDADD += ../src/probes.o
|
||||
endif
|
||||
|
||||
libvirtd_LDADD += \
|
||||
../src/libvirt-net-rpc-server.la \
|
||||
../src/libvirt-net-rpc.la \
|
||||
../src/libvirt-qemu.la
|
||||
|
||||
if ! WITH_DRIVER_MODULES
|
||||
@ -162,41 +170,27 @@ policyfile = libvirtd.policy-1
|
||||
endif
|
||||
endif
|
||||
|
||||
if WITH_DTRACE
|
||||
libvirtd_LDADD += probes.o
|
||||
nodist_libvirtd_SOURCES = probes.h
|
||||
install-data-local: install-init-redhat install-init-systemd install-init-upstart \
|
||||
install-data-sasl install-data-polkit \
|
||||
install-logrotate install-sysctl
|
||||
$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt \
|
||||
$(DESTDIR)$(localstatedir)/run/libvirt \
|
||||
$(DESTDIR)$(localstatedir)/lib/libvirt
|
||||
|
||||
BUILT_SOURCES += probes.h
|
||||
|
||||
tapsetdir = $(datadir)/systemtap/tapset
|
||||
tapset_DATA = libvirtd.stp
|
||||
|
||||
probes.h: probes.d
|
||||
$(AM_V_GEN)$(DTRACE) -o $@ -h -s $<
|
||||
|
||||
probes.o: probes.d
|
||||
$(AM_V_GEN)$(DTRACE) -o $@ -G -s $<
|
||||
|
||||
CLEANFILES += probes.h probes.o
|
||||
endif
|
||||
|
||||
install-data-local: install-init install-data-sasl install-data-polkit \
|
||||
install-logrotate
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt
|
||||
|
||||
uninstall-local:: uninstall-init uninstall-data-sasl uninstall-data-polkit
|
||||
uninstall-local:: uninstall-init-redhat uninstall-init-systemd uninstall-init-upstart \
|
||||
uninstall-data-sasl uninstall-data-polkit \
|
||||
uninstall-logrotate uninstall-sysctl
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
|
||||
|
||||
if HAVE_POLKIT
|
||||
install-data-polkit:: install-init
|
||||
mkdir -p $(DESTDIR)$(policydir)
|
||||
install-data-polkit::
|
||||
$(MKDIR_P) $(DESTDIR)$(policydir)
|
||||
$(INSTALL_DATA) $(srcdir)/$(policyfile) $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
uninstall-data-polkit:: install-init
|
||||
uninstall-data-polkit::
|
||||
rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
rmdir $(DESTDIR)$(policydir) || :
|
||||
else
|
||||
install-data-polkit::
|
||||
uninstall-data-polkit::
|
||||
@ -235,30 +229,95 @@ libvirtd.uml.logrotate: libvirtd.uml.logrotate.in
|
||||
mv $@-t $@
|
||||
|
||||
install-logrotate: $(LOGROTATE_CONFS)
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu/
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/lxc/
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/uml/
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/logrotate.d/
|
||||
$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt/qemu/ \
|
||||
$(DESTDIR)$(localstatedir)/log/libvirt/lxc/ \
|
||||
$(DESTDIR)$(localstatedir)/log/libvirt/uml/ \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/
|
||||
$(INSTALL_DATA) libvirtd.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
|
||||
$(INSTALL_DATA) libvirtd.qemu.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu
|
||||
$(INSTALL_DATA) libvirtd.lxc.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc
|
||||
$(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
install-init: libvirtd.init
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d
|
||||
$(INSTALL_SCRIPT) libvirtd.init \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
|
||||
uninstall-logrotate:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc \
|
||||
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/lxc || :
|
||||
rmdir $(DESTDIR)$(localstatedir)/log/libvirt/uml || :
|
||||
rmdir $(DESTDIR)$(sysconfdir)/logrotate.d || :
|
||||
|
||||
install-sysconfig:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sysconfig
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sysconf \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
uninstall-sysconfig:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sysconfig || :
|
||||
|
||||
uninstall-init:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd \
|
||||
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
|
||||
install-sysctl:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sysctl.d
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sysctl \
|
||||
$(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd
|
||||
|
||||
uninstall-sysctl:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sysctl.d/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sysctl.d || :
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
|
||||
BUILT_SOURCES += libvirtd.init
|
||||
|
||||
install-init-redhat: install-sysconfig libvirtd.init
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/rc.d/init.d
|
||||
$(INSTALL_SCRIPT) libvirtd.init \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
|
||||
uninstall-init-redhat: uninstall-sysconfig
|
||||
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/rc.d/init.d || :
|
||||
else
|
||||
install-init-redhat:
|
||||
uninstall-init-redhat:
|
||||
endif # LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
|
||||
|
||||
if LIBVIRT_INIT_SCRIPT_UPSTART
|
||||
|
||||
install-init-upstart: install-sysconfig
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/event.d
|
||||
$(INSTALL_SCRIPT) libvirtd.upstart \
|
||||
$(DESTDIR)$(sysconfdir)/event.d/libvirtd
|
||||
|
||||
uninstall-init-upstart: uninstall-sysconfig
|
||||
rm -f $(DESTDIR)$(sysconfdir)/event.d/libvirtd
|
||||
rmdir $(DESTDIR)$(sysconfdir)/event.d || :
|
||||
else
|
||||
install-init-upstart:
|
||||
uninstall-init-upstart:
|
||||
endif # LIBVIRT_INIT_SCRIPT_UPSTART
|
||||
|
||||
|
||||
EXTRA_DIST += libvirtd.service.in
|
||||
if LIBVIRT_INIT_SCRIPT_SYSTEMD
|
||||
|
||||
SYSTEMD_UNIT_DIR = /lib/systemd/system
|
||||
BUILT_SOURCES += libvirtd.service
|
||||
|
||||
install-init-systemd: install-sysconfig libvirtd.service
|
||||
$(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR)
|
||||
$(INSTALL_SCRIPT) libvirtd.service \
|
||||
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
|
||||
|
||||
uninstall-init-systemd: uninstall-sysconfig
|
||||
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
|
||||
rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || :
|
||||
else
|
||||
install-init-systemd:
|
||||
uninstall-init-systemd:
|
||||
endif # LIBVIRT_INIT_SCRIPT_SYSTEMD
|
||||
|
||||
libvirtd.init: libvirtd.init.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN)sed \
|
||||
-e s!\@localstatedir\@!@localstatedir@!g \
|
||||
@ -268,18 +327,21 @@ libvirtd.init: libvirtd.init.in $(top_builddir)/config.status
|
||||
chmod a+x $@-t && \
|
||||
mv $@-t $@
|
||||
|
||||
libvirtd.service: libvirtd.service.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN)sed \
|
||||
-e s!\@localstatedir\@!@localstatedir@!g \
|
||||
-e s!\@sbindir\@!@sbindir@!g \
|
||||
-e s!\@sysconfdir\@!@sysconfdir@!g \
|
||||
< $< > $@-t && \
|
||||
chmod a+x $@-t && \
|
||||
mv $@-t $@
|
||||
|
||||
|
||||
check-local:
|
||||
$(AM_V_GEN)if test -x '$(AUGPARSE)'; then \
|
||||
'$(AUGPARSE)' -I $(srcdir) $(srcdir)/test_libvirtd.aug; \
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
install-init:
|
||||
uninstall-init:
|
||||
libvirtd.init:
|
||||
|
||||
endif # LIBVIRT_INIT_SCRIPT_RED_HAT
|
||||
|
||||
# This must be added last, since functions it provides/replaces
|
||||
# are used by nearly every other library.
|
||||
@ -290,9 +352,6 @@ install-data-local: install-data-sasl
|
||||
uninstall-local:: uninstall-data-sasl
|
||||
endif # WITH_LIBVIRTD
|
||||
|
||||
# This is needed for 'make dist' too, so can't wrap in WITH_LIBVIRTD.
|
||||
EXTRA_DIST += probes.d libvirtd.stp
|
||||
|
||||
POD2MAN = pod2man -c "Virtualization Support" \
|
||||
-r "$(PACKAGE)-$(VERSION)" -s 8
|
||||
|
||||
@ -303,12 +362,12 @@ $(srcdir)/libvirtd.8.in: libvirtd.pod.in
|
||||
# the WITH_LIBVIRTD conditional
|
||||
if HAVE_SASL
|
||||
install-data-sasl:
|
||||
mkdir -p $(DESTDIR)$(sysconfdir)/sasl2/
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sasl2/
|
||||
$(INSTALL_DATA) $(srcdir)/libvirtd.sasl $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
|
||||
|
||||
uninstall-data-sasl:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sasl2/
|
||||
rmdir $(DESTDIR)$(sysconfdir)/sasl2/ || :
|
||||
else
|
||||
install-data-sasl:
|
||||
uninstall-data-sasl:
|
||||
|
@ -48,6 +48,7 @@ module Libvirtd =
|
||||
| str_entry "crl_file"
|
||||
|
||||
let authorization_entry = bool_entry "tls_no_verify_certificate"
|
||||
| bool_entry "tls_no_sanity_certificate"
|
||||
| str_array_entry "tls_allowed_dn_list"
|
||||
| str_array_entry "sasl_allowed_username_list"
|
||||
|
||||
@ -56,6 +57,7 @@ module Libvirtd =
|
||||
| int_entry "max_clients"
|
||||
| int_entry "max_requests"
|
||||
| int_entry "max_client_requests"
|
||||
| int_entry "prio_workers"
|
||||
|
||||
let logging_entry = int_entry "log_level"
|
||||
| str_entry "log_filters"
|
||||
@ -64,6 +66,10 @@ module Libvirtd =
|
||||
let auditing_entry = int_entry "audit_level"
|
||||
| bool_entry "audit_logging"
|
||||
|
||||
let keepalive_entry = int_entry "keepalive_interval"
|
||||
| int_entry "keepalive_count"
|
||||
| bool_entry "keepalive_required"
|
||||
|
||||
(* Each enty in the config is one of the following three ... *)
|
||||
let entry = network_entry
|
||||
| sock_acl_entry
|
||||
@ -73,6 +79,7 @@ module Libvirtd =
|
||||
| processing_entry
|
||||
| logging_entry
|
||||
| auditing_entry
|
||||
| keepalive_entry
|
||||
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
|
||||
let empty = [ label "#empty" . eol ]
|
||||
|
||||
|
@ -34,7 +34,8 @@
|
||||
|
||||
#include "libvirt_internal.h"
|
||||
#include "virterror_internal.h"
|
||||
#include "files.h"
|
||||
#include "virfile.h"
|
||||
#include "virpidfile.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
|
||||
@ -52,7 +53,7 @@
|
||||
#include "remote_driver.h"
|
||||
#include "hooks.h"
|
||||
#include "uuid.h"
|
||||
#include "virtaudit.h"
|
||||
#include "viraudit.h"
|
||||
|
||||
#ifdef WITH_DRIVER_MODULES
|
||||
# include "driver.h"
|
||||
@ -91,7 +92,9 @@
|
||||
|
||||
#include "configmake.h"
|
||||
|
||||
#if HAVE_SASL
|
||||
virNetSASLContextPtr saslCtxt = NULL;
|
||||
#endif
|
||||
virNetServerProgramPtr remoteProgram = NULL;
|
||||
virNetServerProgramPtr qemuProgram = NULL;
|
||||
|
||||
@ -118,6 +121,7 @@ struct daemonConfig {
|
||||
char *mdns_name;
|
||||
|
||||
int tls_no_verify_certificate;
|
||||
int tls_no_sanity_certificate;
|
||||
char **tls_allowed_dn_list;
|
||||
char **sasl_allowed_username_list;
|
||||
|
||||
@ -130,6 +134,8 @@ struct daemonConfig {
|
||||
int max_workers;
|
||||
int max_clients;
|
||||
|
||||
int prio_workers;
|
||||
|
||||
int max_requests;
|
||||
int max_client_requests;
|
||||
|
||||
@ -140,6 +146,10 @@ struct daemonConfig {
|
||||
|
||||
int audit_level;
|
||||
int audit_logging;
|
||||
|
||||
int keepalive_interval;
|
||||
unsigned int keepalive_count;
|
||||
int keepalive_required;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -180,6 +190,7 @@ static int daemonForkIntoBackground(const char *argv0)
|
||||
switch (pid) {
|
||||
case 0:
|
||||
{
|
||||
/* intermediate child */
|
||||
int stdinfd = -1;
|
||||
int stdoutfd = -1;
|
||||
int nextpid;
|
||||
@ -196,9 +207,9 @@ static int daemonForkIntoBackground(const char *argv0)
|
||||
goto cleanup;
|
||||
if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO)
|
||||
goto cleanup;
|
||||
if (VIR_CLOSE(stdinfd) < 0)
|
||||
if (stdinfd > STDERR_FILENO && VIR_CLOSE(stdinfd) < 0)
|
||||
goto cleanup;
|
||||
if (VIR_CLOSE(stdoutfd) < 0)
|
||||
if (stdoutfd > STDERR_FILENO && VIR_CLOSE(stdoutfd) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (setsid() < 0)
|
||||
@ -206,92 +217,70 @@ static int daemonForkIntoBackground(const char *argv0)
|
||||
|
||||
nextpid = fork();
|
||||
switch (nextpid) {
|
||||
case 0:
|
||||
case 0: /* grandchild */
|
||||
return statuspipe[1];
|
||||
case -1:
|
||||
return -1;
|
||||
default:
|
||||
_exit(0);
|
||||
case -1: /* error */
|
||||
goto cleanup;
|
||||
default: /* intermediate child succeeded */
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_FORCE_CLOSE(stdoutfd);
|
||||
VIR_FORCE_CLOSE(stdinfd);
|
||||
return -1;
|
||||
VIR_FORCE_CLOSE(statuspipe[1]);
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
}
|
||||
|
||||
case -1:
|
||||
return -1;
|
||||
case -1: /* error in parent */
|
||||
goto error;
|
||||
|
||||
default:
|
||||
{
|
||||
int got, exitstatus = 0;
|
||||
/* parent */
|
||||
int ret;
|
||||
char status;
|
||||
|
||||
VIR_FORCE_CLOSE(statuspipe[1]);
|
||||
|
||||
/* We wait to make sure the first child forked successfully */
|
||||
if ((got = waitpid(pid, &exitstatus, 0)) < 0 ||
|
||||
got != pid ||
|
||||
exitstatus != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (virPidWait(pid, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
/* Now block until the second child initializes successfully */
|
||||
/* If we get here, then the grandchild was spawned, so we
|
||||
* must exit. Block until the second child initializes
|
||||
* successfully */
|
||||
again:
|
||||
ret = read(statuspipe[0], &status, 1);
|
||||
if (ret == -1 && errno == EINTR)
|
||||
goto again;
|
||||
|
||||
if (ret == 1 && status != 0) {
|
||||
VIR_FORCE_CLOSE(statuspipe[0]);
|
||||
|
||||
if (ret != 1) {
|
||||
char ebuf[1024];
|
||||
|
||||
fprintf(stderr,
|
||||
_("%s: error: %s. Check /var/log/messages or run without "
|
||||
"--daemon for more info.\n"), argv0,
|
||||
_("%s: error: unable to determine if daemon is "
|
||||
"running: %s\n"), argv0,
|
||||
virStrerror(errno, ebuf, sizeof(ebuf)));
|
||||
exit(EXIT_FAILURE);
|
||||
} else if (status != 0) {
|
||||
fprintf(stderr,
|
||||
_("%s: error: %s. Check /var/log/messages or run "
|
||||
"without --daemon for more info.\n"), argv0,
|
||||
virDaemonErrTypeToString(status));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
_exit(ret == 1 && status == 0 ? 0 : 1);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int daemonWritePidFile(const char *pidFile, const char *argv0)
|
||||
{
|
||||
int fd;
|
||||
FILE *fh;
|
||||
char ebuf[1024];
|
||||
|
||||
if (pidFile[0] == '\0')
|
||||
return 0;
|
||||
|
||||
if ((fd = open(pidFile, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) {
|
||||
VIR_ERROR(_("Failed to open pid file '%s' : %s"),
|
||||
pidFile, virStrerror(errno, ebuf, sizeof ebuf));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(fh = VIR_FDOPEN(fd, "w"))) {
|
||||
VIR_ERROR(_("Failed to fdopen pid file '%s' : %s"),
|
||||
pidFile, virStrerror(errno, ebuf, sizeof ebuf));
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fprintf(fh, "%lu\n", (unsigned long)getpid()) < 0) {
|
||||
VIR_ERROR(_("%s: Failed to write to pid file '%s' : %s"),
|
||||
argv0, pidFile, virStrerror(errno, ebuf, sizeof ebuf));
|
||||
VIR_FORCE_FCLOSE(fh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_FCLOSE(fh) == EOF) {
|
||||
VIR_ERROR(_("%s: Failed to close pid file '%s' : %s"),
|
||||
argv0, pidFile, virStrerror(errno, ebuf, sizeof ebuf));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
VIR_FORCE_CLOSE(statuspipe[0]);
|
||||
VIR_FORCE_CLOSE(statuspipe[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -308,8 +297,10 @@ daemonPidFilePath(bool privileged,
|
||||
if (!(userdir = virGetUserDirectory(geteuid())))
|
||||
goto error;
|
||||
|
||||
if (virAsprintf(pidfile, "%s/.libvirt/libvirtd.pid", userdir) < 0)
|
||||
if (virAsprintf(pidfile, "%s/.libvirt/libvirtd.pid", userdir) < 0) {
|
||||
VIR_FREE(userdir);
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
VIR_FREE(userdir);
|
||||
}
|
||||
@ -387,6 +378,7 @@ static int daemonErrorLogFilter(virErrorPtr err, int priority)
|
||||
case VIR_ERR_NO_NWFILTER:
|
||||
case VIR_ERR_NO_SECRET:
|
||||
case VIR_ERR_NO_DOMAIN_SNAPSHOT:
|
||||
case VIR_ERR_OPERATION_INVALID:
|
||||
return VIR_LOG_DEBUG;
|
||||
}
|
||||
|
||||
@ -486,6 +478,7 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
unix_sock_gid,
|
||||
config->auth_unix_rw,
|
||||
false,
|
||||
config->max_client_requests,
|
||||
NULL)))
|
||||
goto error;
|
||||
if (sock_path_ro &&
|
||||
@ -494,11 +487,16 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
unix_sock_gid,
|
||||
config->auth_unix_ro,
|
||||
true,
|
||||
config->max_client_requests,
|
||||
NULL)))
|
||||
goto error;
|
||||
|
||||
if (virNetServerAddService(srv, svc, NULL) < 0)
|
||||
if (virNetServerAddService(srv, svc,
|
||||
config->mdns_adv && !ipsock ?
|
||||
"_libvirt._tcp" :
|
||||
NULL) < 0)
|
||||
goto error;
|
||||
|
||||
if (svcRO &&
|
||||
virNetServerAddService(srv, svcRO, NULL) < 0)
|
||||
goto error;
|
||||
@ -509,6 +507,7 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
config->tcp_port,
|
||||
config->auth_tcp,
|
||||
false,
|
||||
config->max_client_requests,
|
||||
NULL)))
|
||||
goto error;
|
||||
|
||||
@ -528,12 +527,14 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
config->cert_file,
|
||||
config->key_file,
|
||||
(const char *const*)config->tls_allowed_dn_list,
|
||||
config->tls_no_sanity_certificate ? false : true,
|
||||
config->tls_no_verify_certificate ? false : true)))
|
||||
goto error;
|
||||
} else {
|
||||
if (!(ctxt = virNetTLSContextNewServerPath(NULL,
|
||||
!privileged,
|
||||
(const char *const*)config->tls_allowed_dn_list,
|
||||
config->tls_no_sanity_certificate ? false : true,
|
||||
config->tls_no_verify_certificate ? false : true)))
|
||||
goto error;
|
||||
}
|
||||
@ -543,6 +544,7 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
config->tls_port,
|
||||
config->auth_tls,
|
||||
false,
|
||||
config->max_client_requests,
|
||||
ctxt))) {
|
||||
virNetTLSContextFree(ctxt);
|
||||
goto error;
|
||||
@ -556,6 +558,7 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SASL
|
||||
if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
|
||||
config->auth_unix_ro == REMOTE_AUTH_SASL ||
|
||||
config->auth_tcp == REMOTE_AUTH_SASL ||
|
||||
@ -565,25 +568,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
|
||||
if (!saslCtxt)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#if HAVE_POLKIT0
|
||||
if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
|
||||
auth_unix_ro == REMOTE_AUTH_POLKIT) {
|
||||
DBusError derr;
|
||||
|
||||
dbus_connection_set_change_sigpipe(FALSE);
|
||||
dbus_threads_init_default();
|
||||
|
||||
dbus_error_init(&derr);
|
||||
server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
|
||||
if (!(server->sysbus)) {
|
||||
VIR_ERROR(_("Failed to connect to system bus for PolicyKit auth: %s"),
|
||||
derr.message);
|
||||
dbus_error_free(&derr);
|
||||
goto error;
|
||||
}
|
||||
dbus_connection_set_exit_on_disconnect(server->sysbus, FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -741,8 +725,10 @@ static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, cons
|
||||
|
||||
if (STREQ(p->str, "none")) {
|
||||
*auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
|
||||
#if HAVE_SASL
|
||||
} else if (STREQ(p->str, "sasl")) {
|
||||
*auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
|
||||
#endif
|
||||
} else if (STREQ(p->str, "polkit")) {
|
||||
*auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
|
||||
} else {
|
||||
@ -928,6 +914,8 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
|
||||
data->max_workers = 20;
|
||||
data->max_clients = 20;
|
||||
|
||||
data->prio_workers = 5;
|
||||
|
||||
data->max_requests = 20;
|
||||
data->max_client_requests = 5;
|
||||
|
||||
@ -936,6 +924,10 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
|
||||
data->audit_level = 1;
|
||||
data->audit_logging = 0;
|
||||
|
||||
data->keepalive_interval = 5;
|
||||
data->keepalive_count = 5;
|
||||
data->keepalive_required = 0;
|
||||
|
||||
localhost = virGetHostname(NULL);
|
||||
if (localhost == NULL) {
|
||||
/* we couldn't resolve the hostname; assume that we are
|
||||
@ -1012,10 +1004,16 @@ daemonConfigFree(struct daemonConfig *data)
|
||||
*/
|
||||
static int
|
||||
daemonConfigLoad(struct daemonConfig *data,
|
||||
const char *filename)
|
||||
const char *filename,
|
||||
bool allow_missing)
|
||||
{
|
||||
virConfPtr conf;
|
||||
|
||||
if (allow_missing &&
|
||||
access(filename, R_OK) == -1 &&
|
||||
errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
conf = virConfReadFile (filename, 0);
|
||||
if (!conf)
|
||||
return -1;
|
||||
@ -1056,6 +1054,7 @@ daemonConfigLoad(struct daemonConfig *data,
|
||||
GET_CONF_INT (conf, filename, mdns_adv);
|
||||
GET_CONF_STR (conf, filename, mdns_name);
|
||||
|
||||
GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
|
||||
GET_CONF_INT (conf, filename, tls_no_verify_certificate);
|
||||
|
||||
GET_CONF_STR (conf, filename, key_file);
|
||||
@ -1077,6 +1076,8 @@ daemonConfigLoad(struct daemonConfig *data,
|
||||
GET_CONF_INT (conf, filename, max_workers);
|
||||
GET_CONF_INT (conf, filename, max_clients);
|
||||
|
||||
GET_CONF_INT (conf, filename, prio_workers);
|
||||
|
||||
GET_CONF_INT (conf, filename, max_requests);
|
||||
GET_CONF_INT (conf, filename, max_client_requests);
|
||||
|
||||
@ -1090,6 +1091,10 @@ daemonConfigLoad(struct daemonConfig *data,
|
||||
GET_CONF_STR (conf, filename, log_outputs);
|
||||
GET_CONF_INT (conf, filename, log_buffer_size);
|
||||
|
||||
GET_CONF_INT (conf, filename, keepalive_interval);
|
||||
GET_CONF_INT (conf, filename, keepalive_count);
|
||||
GET_CONF_INT (conf, filename, keepalive_required);
|
||||
|
||||
virConfFree (conf);
|
||||
return 0;
|
||||
|
||||
@ -1137,6 +1142,17 @@ static void daemonShutdownHandler(virNetServerPtr srv,
|
||||
virNetServerQuit(srv);
|
||||
}
|
||||
|
||||
static void daemonReloadHandler(virNetServerPtr srv ATTRIBUTE_UNUSED,
|
||||
siginfo_t *sig ATTRIBUTE_UNUSED,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
VIR_INFO("Reloading configuration on SIGHUP");
|
||||
virHookCall(VIR_HOOK_DRIVER_DAEMON, "-",
|
||||
VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, "SIGHUP", NULL);
|
||||
if (virStateReload() < 0)
|
||||
VIR_WARN("Error while reloading drivers");
|
||||
}
|
||||
|
||||
static int daemonSetupSignals(virNetServerPtr srv)
|
||||
{
|
||||
if (virNetServerAddSignalHandler(srv, SIGINT, daemonShutdownHandler, NULL) < 0)
|
||||
@ -1145,6 +1161,8 @@ static int daemonSetupSignals(virNetServerPtr srv)
|
||||
return -1;
|
||||
if (virNetServerAddSignalHandler(srv, SIGTERM, daemonShutdownHandler, NULL) < 0)
|
||||
return -1;
|
||||
if (virNetServerAddSignalHandler(srv, SIGHUP, daemonReloadHandler, NULL) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1153,11 +1171,13 @@ static void daemonRunStateInit(void *opaque)
|
||||
virNetServerPtr srv = opaque;
|
||||
|
||||
/* Start the stateful HV drivers
|
||||
* This is delibrately done after telling the parent process
|
||||
* This is deliberately done after telling the parent process
|
||||
* we're ready, since it can take a long time and this will
|
||||
* seriously delay OS bootup process */
|
||||
if (virStateInitialize(virNetServerIsPrivileged(srv)) < 0) {
|
||||
VIR_ERROR(_("Driver state initialization failed"));
|
||||
/* Ensure the main event loop quits */
|
||||
kill(getpid(), SIGTERM);
|
||||
virNetServerFree(srv);
|
||||
return;
|
||||
}
|
||||
@ -1257,6 +1277,7 @@ int main(int argc, char **argv) {
|
||||
char *remote_config_file = NULL;
|
||||
int statuswrite = -1;
|
||||
int ret = 1;
|
||||
int pid_file_fd = -1;
|
||||
char *pid_file = NULL;
|
||||
char *sock_file = NULL;
|
||||
char *sock_file_ro = NULL;
|
||||
@ -1266,6 +1287,10 @@ int main(int argc, char **argv) {
|
||||
int ipsock = 0;
|
||||
struct daemonConfig *config;
|
||||
bool privileged = geteuid() == 0 ? true : false;
|
||||
bool implicit_conf = false;
|
||||
bool use_polkit_dbus;
|
||||
char *run_dir = NULL;
|
||||
mode_t old_umask;
|
||||
|
||||
struct option opts[] = {
|
||||
{ "verbose", no_argument, &verbose, 1},
|
||||
@ -1287,6 +1312,9 @@ int main(int argc, char **argv) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* initialize early logging */
|
||||
virLogSetFromEnv();
|
||||
|
||||
while (1) {
|
||||
int optidx = 0;
|
||||
int c;
|
||||
@ -1316,20 +1344,26 @@ int main(int argc, char **argv) {
|
||||
if (virStrToLong_i(optarg, &tmp, 10, &timeout) != 0
|
||||
|| timeout <= 0
|
||||
/* Ensure that we can multiply by 1000 without overflowing. */
|
||||
|| timeout > INT_MAX / 1000)
|
||||
timeout = -1;
|
||||
|| timeout > INT_MAX / 1000) {
|
||||
VIR_ERROR(_("Invalid value for timeout"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
VIR_FREE(pid_file);
|
||||
if (!(pid_file = strdup(optarg)))
|
||||
if (!(pid_file = strdup(optarg))) {
|
||||
VIR_ERROR(_("Can't allocate memory"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
VIR_FREE(remote_config_file);
|
||||
if (!(remote_config_file = strdup(optarg)))
|
||||
if (!(remote_config_file = strdup(optarg))) {
|
||||
VIR_ERROR(_("Can't allocate memory"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_VERSION:
|
||||
@ -1341,25 +1375,33 @@ int main(int argc, char **argv) {
|
||||
return 2;
|
||||
|
||||
default:
|
||||
fprintf (stderr, _("%s: internal error: unknown flag: %c\n"),
|
||||
argv[0], c);
|
||||
VIR_ERROR(_("%s: internal error: unknown flag: %c"),
|
||||
argv[0], c);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(config = daemonConfigNew(privileged)))
|
||||
if (!(config = daemonConfigNew(privileged))) {
|
||||
VIR_ERROR(_("Can't create initial configuration"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* No explicit config, so try and find a default one */
|
||||
if (remote_config_file == NULL &&
|
||||
daemonConfigFilePath(privileged,
|
||||
&remote_config_file) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
if (remote_config_file == NULL) {
|
||||
implicit_conf = true;
|
||||
if (daemonConfigFilePath(privileged,
|
||||
&remote_config_file) < 0) {
|
||||
VIR_ERROR(_("Can't determine config path"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the config file if it exists*/
|
||||
if (remote_config_file &&
|
||||
daemonConfigLoad(config, remote_config_file) < 0)
|
||||
daemonConfigLoad(config, remote_config_file, implicit_conf) < 0) {
|
||||
VIR_ERROR(_("Can't load config file '%s'"), remote_config_file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (config->host_uuid &&
|
||||
virSetHostUUIDStr(config->host_uuid) < 0) {
|
||||
@ -1367,19 +1409,25 @@ int main(int argc, char **argv) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (daemonSetupLogging(config, privileged, verbose, godaemon) < 0)
|
||||
if (daemonSetupLogging(config, privileged, verbose, godaemon) < 0) {
|
||||
VIR_ERROR(_("Can't initialize logging"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!pid_file && privileged &&
|
||||
if (!pid_file &&
|
||||
daemonPidFilePath(privileged,
|
||||
&pid_file) < 0)
|
||||
&pid_file) < 0) {
|
||||
VIR_ERROR(_("Can't determine pid file path."));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (daemonUnixSocketPaths(config,
|
||||
privileged,
|
||||
&sock_file,
|
||||
&sock_file_ro) < 0)
|
||||
&sock_file_ro) < 0) {
|
||||
VIR_ERROR(_("Can't determine socket paths"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (godaemon) {
|
||||
char ebuf[1024];
|
||||
@ -1397,37 +1445,51 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a pidfile set, claim it now, exiting if already taken */
|
||||
if (pid_file != NULL &&
|
||||
daemonWritePidFile(pid_file, argv[0]) < 0) {
|
||||
VIR_FREE(pid_file); /* Prevent unlinking of someone else's pid ! */
|
||||
/* Ensure the rundir exists (on tmpfs on some systems) */
|
||||
if (privileged) {
|
||||
run_dir = strdup(LOCALSTATEDIR "/run/libvirt");
|
||||
} else {
|
||||
char *user_dir = virGetUserDirectory(geteuid());
|
||||
|
||||
if (!user_dir) {
|
||||
VIR_ERROR(_("Can't determine user directory"));
|
||||
goto cleanup;
|
||||
}
|
||||
ignore_value(virAsprintf(&run_dir, "%s/.libvirt/", user_dir));
|
||||
VIR_FREE(user_dir);
|
||||
}
|
||||
if (!run_dir) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
old_umask = umask(022);
|
||||
if (virFileMakePath(run_dir) < 0) {
|
||||
char ebuf[1024];
|
||||
VIR_ERROR(_("unable to create rundir %s: %s"), run_dir,
|
||||
virStrerror(errno, ebuf, sizeof(ebuf)));
|
||||
ret = VIR_DAEMON_ERR_RUNDIR;
|
||||
goto cleanup;
|
||||
}
|
||||
umask(old_umask);
|
||||
|
||||
/* Try to claim the pidfile, exiting if we can't */
|
||||
if ((pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0) {
|
||||
ret = VIR_DAEMON_ERR_PIDFILE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Ensure the rundir exists (on tmpfs on some systems) */
|
||||
if (privileged) {
|
||||
const char *rundir = LOCALSTATEDIR "/run/libvirt";
|
||||
mode_t old_umask;
|
||||
|
||||
old_umask = umask(022);
|
||||
if (mkdir (rundir, 0755)) {
|
||||
if (errno != EEXIST) {
|
||||
char ebuf[1024];
|
||||
VIR_ERROR(_("unable to create rundir %s: %s"), rundir,
|
||||
virStrerror(errno, ebuf, sizeof(ebuf)));
|
||||
ret = VIR_DAEMON_ERR_RUNDIR;
|
||||
umask(old_umask);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
umask(old_umask);
|
||||
}
|
||||
|
||||
use_polkit_dbus = config->auth_unix_rw == REMOTE_AUTH_POLKIT ||
|
||||
config->auth_unix_ro == REMOTE_AUTH_POLKIT;
|
||||
if (!(srv = virNetServerNew(config->min_workers,
|
||||
config->max_workers,
|
||||
config->prio_workers,
|
||||
config->max_clients,
|
||||
config->keepalive_interval,
|
||||
config->keepalive_count,
|
||||
!!config->keepalive_required,
|
||||
config->mdns_adv ? config->mdns_name : NULL,
|
||||
use_polkit_dbus,
|
||||
remoteClientInitHook))) {
|
||||
ret = VIR_DAEMON_ERR_INIT;
|
||||
goto cleanup;
|
||||
@ -1547,6 +1609,7 @@ int main(int argc, char **argv) {
|
||||
cleanup:
|
||||
virNetServerProgramFree(remoteProgram);
|
||||
virNetServerProgramFree(qemuProgram);
|
||||
virNetServerClose(srv);
|
||||
virNetServerFree(srv);
|
||||
if (statuswrite != -1) {
|
||||
if (ret != 0) {
|
||||
@ -1558,13 +1621,15 @@ cleanup:
|
||||
}
|
||||
VIR_FORCE_CLOSE(statuswrite);
|
||||
}
|
||||
if (pid_file)
|
||||
unlink (pid_file);
|
||||
if (pid_file_fd != -1)
|
||||
virPidFileReleasePath(pid_file, pid_file_fd);
|
||||
|
||||
VIR_FREE(sock_file);
|
||||
VIR_FREE(sock_file_ro);
|
||||
VIR_FREE(pid_file);
|
||||
VIR_FREE(remote_config_file);
|
||||
VIR_FREE(run_dir);
|
||||
|
||||
daemonConfigFree(config);
|
||||
virLogShutdown();
|
||||
|
||||
|
@ -187,6 +187,15 @@
|
||||
#
|
||||
|
||||
|
||||
# Flag to disable verification of our own server certificates
|
||||
#
|
||||
# When libvirtd starts it performs some sanity checks against
|
||||
# its own certificates.
|
||||
#
|
||||
# Default is to always run sanity checks. Uncommenting this
|
||||
# will disable sanity checks which is not a good idea
|
||||
#tls_no_sanity_certificate = 1
|
||||
|
||||
# Flag to disable verification of client certificates
|
||||
#
|
||||
# Client certificate verification is the primary authentication mechanism.
|
||||
@ -248,6 +257,12 @@
|
||||
#min_workers = 5
|
||||
#max_workers = 20
|
||||
|
||||
|
||||
# The number of priority workers. If all workers from above
|
||||
# pool will stuck, some calls marked as high priority
|
||||
# (notably domainDestroy) can be executed in this pool.
|
||||
#prio_workers = 5
|
||||
|
||||
# Total global limit on concurrent RPC calls. Should be
|
||||
# at least as large as max_workers. Beyond this, RPC requests
|
||||
# will be read into memory and queued. This directly impact
|
||||
@ -269,7 +284,7 @@
|
||||
# Logging controls
|
||||
#
|
||||
|
||||
# Logging level: 4 errors, 3 warnings, 2 informations, 1 debug
|
||||
# Logging level: 4 errors, 3 warnings, 2 information, 1 debug
|
||||
# basically 1 will log everything possible
|
||||
#log_level = 3
|
||||
|
||||
@ -294,7 +309,7 @@
|
||||
# the event layer.
|
||||
|
||||
# Logging outputs:
|
||||
# An output is one of the places to save logging informations
|
||||
# An output is one of the places to save logging information
|
||||
# The format for an output can be:
|
||||
# x:stderr
|
||||
# output goes to stderr
|
||||
@ -351,3 +366,28 @@
|
||||
# it with the output of the 'uuidgen' command and then
|
||||
# uncomment this entry
|
||||
#host_uuid = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
###################################################################
|
||||
# Keepalive protocol:
|
||||
# This allows libvirtd to detect broken client connections or even
|
||||
# dead client. A keepalive message is sent to a client after
|
||||
# keepalive_interval seconds of inactivity to check if the client is
|
||||
# still responding; keepalive_count is a maximum number of keepalive
|
||||
# messages that are allowed to be sent to the client without getting
|
||||
# any response before the connection is considered broken. In other
|
||||
# words, the connection is automatically closed approximately after
|
||||
# keepalive_interval * (keepalive_count + 1) seconds since the last
|
||||
# message received from the client. If keepalive_interval is set to
|
||||
# -1, libvirtd will never send keepalive requests; however clients
|
||||
# can still send them and the deamon will send responses. When
|
||||
# keepalive_count is set to 0, connections will be automatically
|
||||
# closed after keepalive_interval seconds of inactivity without
|
||||
# sending any keepalive messages.
|
||||
#
|
||||
#keepalive_interval = 5
|
||||
#keepalive_count = 5
|
||||
#
|
||||
# If set to 1, libvirtd will refuse to talk to clients that do not
|
||||
# support keepalive protocol. Defaults to 0.
|
||||
#
|
||||
#keepalive_required = 1
|
||||
|
@ -27,36 +27,16 @@
|
||||
|
||||
# include <config.h>
|
||||
|
||||
# if HAVE_POLKIT0
|
||||
# include <dbus/dbus.h>
|
||||
# endif
|
||||
|
||||
# include <rpc/types.h>
|
||||
# include <rpc/xdr.h>
|
||||
# include "remote_protocol.h"
|
||||
# include "qemu_protocol.h"
|
||||
# include "logging.h"
|
||||
# include "threads.h"
|
||||
# include "network.h"
|
||||
# include "virnetsaslcontext.h"
|
||||
# include "virnetserverprogram.h"
|
||||
|
||||
# if WITH_DTRACE
|
||||
# ifndef LIBVIRTD_PROBES_H
|
||||
# define LIBVIRTD_PROBES_H
|
||||
# include "probes.h"
|
||||
# endif /* LIBVIRTD_PROBES_H */
|
||||
# define PROBE(NAME, FMT, ...) \
|
||||
VIR_DEBUG_INT("trace." __FILE__ , __func__, __LINE__, \
|
||||
#NAME ": " FMT, __VA_ARGS__); \
|
||||
if (LIBVIRTD_ ## NAME ## _ENABLED()) { \
|
||||
LIBVIRTD_ ## NAME(__VA_ARGS__); \
|
||||
}
|
||||
# else
|
||||
# define PROBE(NAME, FMT, ...) \
|
||||
VIR_DEBUG_INT("trace." __FILE__, __func__, __LINE__, \
|
||||
#NAME ": " FMT, __VA_ARGS__);
|
||||
# if HAVE_SASL
|
||||
# include "virnetsaslcontext.h"
|
||||
# endif
|
||||
# include "virnetserverprogram.h"
|
||||
|
||||
typedef struct daemonClientStream daemonClientStream;
|
||||
typedef daemonClientStream *daemonClientStreamPtr;
|
||||
@ -70,7 +50,9 @@ struct daemonClientPrivate {
|
||||
|
||||
int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
|
||||
|
||||
# if HAVE_SASL
|
||||
virNetSASLSessionPtr sasl;
|
||||
# endif
|
||||
|
||||
/* This is only valid if a remote open call has been made on this
|
||||
* connection, otherwise it will be NULL. Also if remote close is
|
||||
@ -79,36 +61,13 @@ struct daemonClientPrivate {
|
||||
virConnectPtr conn;
|
||||
|
||||
daemonClientStreamPtr streams;
|
||||
bool keepalive_supported;
|
||||
};
|
||||
|
||||
# if HAVE_SASL
|
||||
extern virNetSASLContextPtr saslCtxt;
|
||||
# endif
|
||||
extern virNetServerProgramPtr remoteProgram;
|
||||
extern virNetServerProgramPtr qemuProgram;
|
||||
|
||||
/* Main server state */
|
||||
struct qemud_server {
|
||||
int privileged;
|
||||
|
||||
int sigread;
|
||||
int sigwrite;
|
||||
char *logDir;
|
||||
pthread_t eventThread;
|
||||
unsigned int hasEventThread :1;
|
||||
unsigned int quitEventThread :1;
|
||||
# ifdef HAVE_AVAHI
|
||||
struct libvirtd_mdns *mdns;
|
||||
# endif
|
||||
# if HAVE_SASL
|
||||
char **saslUsernameWhitelist;
|
||||
# endif
|
||||
# if HAVE_POLKIT0
|
||||
DBusConnection *sysbus;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
# if HAVE_POLKIT
|
||||
int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
@ -74,8 +74,9 @@ stop() {
|
||||
echo
|
||||
if [ $RETVAL -eq 0 ]; then
|
||||
rm -f @localstatedir@/lock/subsys/$SERVICE
|
||||
rm -f $PIDFILE
|
||||
rm -rf @localstatedir@/cache/libvirt/*
|
||||
else
|
||||
exit $RETVAL
|
||||
fi
|
||||
}
|
||||
|
||||
|
20
daemon/libvirtd.service.in
Normal file
20
daemon/libvirtd.service.in
Normal file
@ -0,0 +1,20 @@
|
||||
# NB we don't use socket activation. When libvirtd starts it will
|
||||
# spawn any virtual machines registered for autostart. We want this
|
||||
# to occur on every boot, regardless of whether any client connects
|
||||
# to a socket. Thus socket activation doesn't have any benefit
|
||||
|
||||
[Unit]
|
||||
Description=Virtualization daemon
|
||||
After=syslog.target
|
||||
After=udev.target
|
||||
After=avahi.target
|
||||
After=dbus.target
|
||||
Before=libvirt-guests.service
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=-/etc/sysconfig/libvirtd
|
||||
ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,65 +0,0 @@
|
||||
probe libvirt.daemon.client.connect = process("libvirtd").mark("client_connect")
|
||||
{
|
||||
fd = $arg1;
|
||||
readonly = $arg2;
|
||||
localAddr = user_string($arg3);
|
||||
remoteAddr = user_string($arg4);
|
||||
}
|
||||
|
||||
probe libvirt.daemon.client.disconnect = process("libvirtd").mark("client_disconnect")
|
||||
{
|
||||
fd = $arg1;
|
||||
}
|
||||
|
||||
|
||||
probe libvirt.daemon.client.tls_allow = process("libvirtd").mark("client_tls_allow")
|
||||
{
|
||||
fd = $arg1;
|
||||
x509dname = user_string($arg2);
|
||||
}
|
||||
|
||||
probe libvirt.daemon.client.tls_deny = process("libvirtd").mark("client_tls_deny")
|
||||
{
|
||||
fd = $arg1;
|
||||
x509dname = user_string($arg2);
|
||||
}
|
||||
|
||||
probe libvirt.daemon.client.tls_fail = process("libvirtd").mark("client_tls_fail")
|
||||
{
|
||||
fd = $arg1;
|
||||
}
|
||||
|
||||
|
||||
function authtype_to_string(authtype) {
|
||||
if (authtype == 0)
|
||||
return "none"
|
||||
if (authtype == 1)
|
||||
return "sasl"
|
||||
if (authtype == 2)
|
||||
return "polkit"
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
|
||||
probe libvirt.daemon.client.auth_allow = process("libvirtd").mark("client_auth_allow")
|
||||
{
|
||||
fd = $arg1;
|
||||
authtype = $arg2;
|
||||
authname = authtype_to_string($arg2);
|
||||
identity = user_string($arg3);
|
||||
}
|
||||
|
||||
probe libvirt.daemon.client.auth_deny = process("libvirtd").mark("client_auth_deny")
|
||||
{
|
||||
fd = $arg1;
|
||||
authtype = $arg2;
|
||||
authname = authtype_to_string($arg2);
|
||||
identity = user_string($arg3);
|
||||
}
|
||||
|
||||
probe libvirt.daemon.client.auth_fail = process("libvirtd").mark("client_auth_fail")
|
||||
{
|
||||
fd = $arg1;
|
||||
authtype = $arg2;
|
||||
authname = authtype_to_string($arg2);
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
# Override the default config file
|
||||
# NOTE: This setting is no longer honoured if using
|
||||
# systemd. Set '--config /etc/libvirt/libvirtd.conf'
|
||||
# in LIBVIRTD_ARGS instead.
|
||||
#LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf
|
||||
|
||||
# Listen for TCP/IP connections
|
||||
|
8
daemon/libvirtd.sysctl
Normal file
8
daemon/libvirtd.sysctl
Normal file
@ -0,0 +1,8 @@
|
||||
# The kernel allocates aio memory on demand, and this number limits the
|
||||
# number of parallel aio requests; the only drawback of a larger limit is
|
||||
# that a malicious guest could issue parallel requests to cause the kernel
|
||||
# to set aside memory. Set this number at least as large as
|
||||
# 128 * (number of virtual disks on the host)
|
||||
# Libvirt uses a default of 1M requests to allow 8k disks, with at most
|
||||
# 64M of kernel memory if all disks hit an aio request at the same time.
|
||||
fs.aio-max-nr = 1048576
|
@ -31,9 +31,6 @@ script
|
||||
ulimit -c "$DAEMON_COREFILE_LIMIT"
|
||||
fi
|
||||
|
||||
# Clean up a pidfile that might be left around
|
||||
rm -f /var/run/libvirtd.pid
|
||||
|
||||
mkdir -p /var/cache/libvirt
|
||||
rm -rf /var/cache/libvirt/*
|
||||
|
||||
@ -41,6 +38,5 @@ script
|
||||
end script
|
||||
|
||||
post-stop script
|
||||
rm -f $PIDFILE
|
||||
rm -rf /var/cache/libvirt/*
|
||||
end script
|
||||
|
@ -1,12 +0,0 @@
|
||||
provider libvirtd {
|
||||
probe client_connect(int fd, int readonly, const char *localAddr, const char *remoteAddr);
|
||||
probe client_disconnect(int fd);
|
||||
|
||||
probe client_auth_allow(int fd, int authtype, const char *identity);
|
||||
probe client_auth_deny(int fd, int authtype, const char *identity);
|
||||
probe client_auth_fail(int fd, int authtype);
|
||||
|
||||
probe client_tls_allow(int fd, const char *x509dname);
|
||||
probe client_tls_deny(int fd, const char *x509dname);
|
||||
probe client_tls_fail(int fd);
|
||||
};
|
905
daemon/remote.c
905
daemon/remote.c
File diff suppressed because it is too large
Load Diff
@ -31,11 +31,9 @@
|
||||
|
||||
extern virNetServerProgramProc remoteProcs[];
|
||||
extern size_t remoteNProcs;
|
||||
extern virNetServerProgramErrorHander remoteErr;
|
||||
|
||||
extern virNetServerProgramProc qemuProcs[];
|
||||
extern size_t qemuNProcs;
|
||||
extern virNetServerProgramErrorHander qemuErr;
|
||||
|
||||
int remoteClientInitHook(virNetServerPtr srv,
|
||||
virNetServerClientPtr client);
|
||||
|
146
daemon/stream.c
146
daemon/stream.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* stream.c: APIs for managing client streams
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2009, 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -38,6 +38,7 @@
|
||||
|
||||
struct daemonClientStream {
|
||||
daemonClientPrivatePtr priv;
|
||||
int refs;
|
||||
|
||||
virNetServerProgramPtr prog;
|
||||
|
||||
@ -93,7 +94,7 @@ daemonStreamUpdateEvents(daemonClientStream *stream)
|
||||
* fast stream, but slow client
|
||||
*/
|
||||
static void
|
||||
daemonStreamMessageFinished(virNetMessagePtr msg,
|
||||
daemonStreamMessageFinished(virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
daemonClientStream *stream = opaque;
|
||||
@ -102,6 +103,17 @@ daemonStreamMessageFinished(virNetMessagePtr msg,
|
||||
|
||||
stream->tx = 1;
|
||||
daemonStreamUpdateEvents(stream);
|
||||
|
||||
daemonFreeClientStream(NULL, stream);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
daemonStreamEventFreeFunc(void *opaque)
|
||||
{
|
||||
virNetServerClientPtr client = opaque;
|
||||
|
||||
virNetServerClientFree(client);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -131,7 +143,8 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
|
||||
|
||||
VIR_DEBUG("st=%p events=%d EOF=%d closed=%d", st, events, stream->recvEOF, stream->closed);
|
||||
|
||||
if (events & VIR_STREAM_EVENT_WRITABLE) {
|
||||
if (!stream->closed &&
|
||||
(events & VIR_STREAM_EVENT_WRITABLE)) {
|
||||
if (daemonStreamHandleWrite(client, stream) < 0) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
@ -139,9 +152,9 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->recvEOF &&
|
||||
(events & (VIR_STREAM_EVENT_READABLE | VIR_STREAM_EVENT_HANGUP))) {
|
||||
events = events & ~(VIR_STREAM_EVENT_READABLE | VIR_STREAM_EVENT_HANGUP);
|
||||
if (!stream->closed && !stream->recvEOF &&
|
||||
(events & (VIR_STREAM_EVENT_READABLE))) {
|
||||
events = events & ~(VIR_STREAM_EVENT_READABLE);
|
||||
if (daemonStreamHandleRead(client, stream) < 0) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
@ -178,6 +191,37 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If we got HANGUP, we need to only send an empty
|
||||
* packet so the client sees an EOF and cleans up
|
||||
*/
|
||||
if (!stream->closed && !stream->recvEOF &&
|
||||
(events & VIR_STREAM_EVENT_HANGUP)) {
|
||||
virNetMessagePtr msg;
|
||||
events &= ~(VIR_STREAM_EVENT_HANGUP);
|
||||
stream->tx = 0;
|
||||
stream->recvEOF = 1;
|
||||
if (!(msg = virNetMessageNew(false))) {
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
msg->cb = daemonStreamMessageFinished;
|
||||
msg->opaque = stream;
|
||||
stream->refs++;
|
||||
if (virNetServerProgramSendStreamData(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
stream->procedure,
|
||||
stream->serial,
|
||||
"", 0) < 0) {
|
||||
virNetMessageFree(msg);
|
||||
daemonRemoveClientStream(client, stream);
|
||||
virNetServerClientClose(client);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream->closed &&
|
||||
(events & (VIR_STREAM_EVENT_ERROR | VIR_STREAM_EVENT_HANGUP))) {
|
||||
int ret;
|
||||
@ -195,7 +239,7 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
|
||||
virNetError(VIR_ERR_RPC,
|
||||
"%s", _("stream had I/O failure"));
|
||||
|
||||
msg = virNetMessageNew();
|
||||
msg = virNetMessageNew(false);
|
||||
if (!msg) {
|
||||
ret = -1;
|
||||
} else {
|
||||
@ -232,7 +276,7 @@ cleanup:
|
||||
* -1 on fatal client error
|
||||
*/
|
||||
static int
|
||||
daemonStreamFilter(virNetServerClientPtr client,
|
||||
daemonStreamFilter(virNetServerClientPtr client ATTRIBUTE_UNUSED,
|
||||
virNetMessagePtr msg,
|
||||
void *opaque)
|
||||
{
|
||||
@ -290,6 +334,7 @@ daemonCreateClientStream(virNetServerClientPtr client,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream->refs = 1;
|
||||
stream->priv = priv;
|
||||
stream->prog = prog;
|
||||
stream->procedure = header->proc;
|
||||
@ -317,6 +362,10 @@ int daemonFreeClientStream(virNetServerClientPtr client,
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
stream->refs--;
|
||||
if (stream->refs)
|
||||
return 0;
|
||||
|
||||
VIR_DEBUG("client=%p, proc=%d, serial=%d",
|
||||
client, stream->procedure, stream->serial);
|
||||
|
||||
@ -325,12 +374,17 @@ int daemonFreeClientStream(virNetServerClientPtr client,
|
||||
msg = stream->rx;
|
||||
while (msg) {
|
||||
virNetMessagePtr tmp = msg->next;
|
||||
/* Send a dummy reply to free up 'msg' & unblock client rx */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
if (virNetServerClientSendMessage(client, msg) < 0) {
|
||||
virNetServerClientMarkClose(client);
|
||||
if (client) {
|
||||
/* Send a dummy reply to free up 'msg' & unblock client rx */
|
||||
virNetMessageClear(msg);
|
||||
msg->header.type = VIR_NET_REPLY;
|
||||
if (virNetServerClientSendMessage(client, msg) < 0) {
|
||||
virNetServerClientImmediateClose(client);
|
||||
virNetMessageFree(msg);
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
virNetMessageFree(msg);
|
||||
ret = -1;
|
||||
}
|
||||
msg = tmp;
|
||||
}
|
||||
@ -360,9 +414,11 @@ int daemonAddClientStream(virNetServerClientPtr client,
|
||||
}
|
||||
|
||||
if (virStreamEventAddCallback(stream->st, 0,
|
||||
daemonStreamEvent, client, NULL) < 0)
|
||||
daemonStreamEvent, client,
|
||||
daemonStreamEventFreeFunc) < 0)
|
||||
return -1;
|
||||
|
||||
virNetServerClientRef(client);
|
||||
if ((stream->filterID = virNetServerClientAddFilter(client,
|
||||
daemonStreamFilter,
|
||||
stream)) < 0) {
|
||||
@ -429,6 +485,28 @@ daemonRemoveClientStream(virNetServerClientPtr client,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
daemonRemoveAllClientStreams(daemonClientStream *stream)
|
||||
{
|
||||
daemonClientStream *tmp;
|
||||
|
||||
VIR_DEBUG("stream=%p", stream);
|
||||
|
||||
while (stream) {
|
||||
tmp = stream->next;
|
||||
|
||||
if (!stream->closed) {
|
||||
virStreamEventRemoveCallback(stream->st);
|
||||
virStreamAbort(stream->st);
|
||||
}
|
||||
|
||||
daemonFreeClientStream(NULL, stream);
|
||||
|
||||
VIR_DEBUG("next stream=%p", tmp);
|
||||
stream = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* -1 if fatal error occurred
|
||||
@ -456,10 +534,6 @@ daemonStreamHandleWriteData(virNetServerClientPtr client,
|
||||
/* Partial write, so indicate we have more todo later */
|
||||
if (msg->bufferOffset < msg->bufferLength)
|
||||
return 1;
|
||||
|
||||
/* A dummy 'send' just to free up 'msg' object */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
return virNetServerClientSendMessage(client, msg);
|
||||
} else if (ret == -2) {
|
||||
/* Blocking, so indicate we have more todo later */
|
||||
return 1;
|
||||
@ -482,7 +556,7 @@ daemonStreamHandleWriteData(virNetServerClientPtr client,
|
||||
|
||||
|
||||
/*
|
||||
* Process an finish handshake from the client.
|
||||
* Process a finish handshake from the client.
|
||||
*
|
||||
* Returns a VIR_NET_OK confirmation if successful, or a VIR_NET_ERROR
|
||||
* if there was a stream error
|
||||
@ -600,9 +674,25 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
|
||||
virNetMessageQueueServe(&stream->rx);
|
||||
if (ret < 0) {
|
||||
virNetMessageFree(msg);
|
||||
virNetServerClientMarkClose(client);
|
||||
virNetServerClientImmediateClose(client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 'CONTINUE' messages don't send a reply (unless error
|
||||
* occurred), so to release the 'msg' object we need to
|
||||
* send a fake zero-length reply. Nothing actually gets
|
||||
* onto the wire, but this causes the client to reset
|
||||
* its active request count / throttling
|
||||
*/
|
||||
if (msg->header.status == VIR_NET_CONTINUE) {
|
||||
virNetMessageClear(msg);
|
||||
msg->header.type = VIR_NET_REPLY;
|
||||
if (virNetServerClientSendMessage(client, msg) < 0) {
|
||||
virNetMessageFree(msg);
|
||||
virNetServerClientImmediateClose(client);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -628,7 +718,15 @@ daemonStreamHandleRead(virNetServerClientPtr client,
|
||||
size_t bufferLen = VIR_NET_MESSAGE_PAYLOAD_MAX;
|
||||
int ret;
|
||||
|
||||
VIR_DEBUG("client=%p, stream=%p", client, stream);
|
||||
VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
|
||||
client, stream, stream->tx, stream->closed);
|
||||
|
||||
/* We might have had an event pending before we shut
|
||||
* down the stream, so if we're marked as closed,
|
||||
* then do nothing
|
||||
*/
|
||||
if (stream->closed)
|
||||
return 0;
|
||||
|
||||
/* Shouldn't ever be called unless we're marked able to
|
||||
* transmit, but doesn't hurt to check */
|
||||
@ -649,7 +747,7 @@ daemonStreamHandleRead(virNetServerClientPtr client,
|
||||
|
||||
memset(&rerr, 0, sizeof(rerr));
|
||||
|
||||
if (!(msg = virNetMessageNew()))
|
||||
if (!(msg = virNetMessageNew(false)))
|
||||
ret = -1;
|
||||
else
|
||||
ret = virNetServerProgramSendStreamError(remoteProgram,
|
||||
@ -663,13 +761,13 @@ daemonStreamHandleRead(virNetServerClientPtr client,
|
||||
stream->tx = 0;
|
||||
if (ret == 0)
|
||||
stream->recvEOF = 1;
|
||||
if (!(msg = virNetMessageNew()))
|
||||
if (!(msg = virNetMessageNew(false)))
|
||||
ret = -1;
|
||||
|
||||
if (msg) {
|
||||
msg->cb = daemonStreamMessageFinished;
|
||||
msg->opaque = stream;
|
||||
virNetServerClientRef(client);
|
||||
stream->refs++;
|
||||
ret = virNetServerProgramSendStreamData(remoteProgram,
|
||||
client,
|
||||
msg,
|
||||
|
@ -45,4 +45,7 @@ int
|
||||
daemonRemoveClientStream(virNetServerClientPtr client,
|
||||
daemonClientStream *stream);
|
||||
|
||||
void
|
||||
daemonRemoveAllClientStreams(daemonClientStream *stream);
|
||||
|
||||
#endif /* __LIBVIRTD_STREAM_H__ */
|
||||
|
@ -193,6 +193,7 @@ crl_file = \"/etc/pki/CA/crl.pem\"
|
||||
# Default is to always verify. Uncommenting this will disable
|
||||
# verification - make sure an IP whitelist is set
|
||||
tls_no_verify_certificate = 1
|
||||
tls_no_sanity_certificate = 1
|
||||
|
||||
|
||||
# A whitelist of allowed x509 Distinguished Names
|
||||
@ -468,6 +469,7 @@ audit_level = 2
|
||||
{ "#comment" = "Default is to always verify. Uncommenting this will disable" }
|
||||
{ "#comment" = "verification - make sure an IP whitelist is set" }
|
||||
{ "tls_no_verify_certificate" = "1" }
|
||||
{ "tls_no_sanity_certificate" = "1" }
|
||||
{ "#empty" }
|
||||
{ "#empty" }
|
||||
{ "#comment" = "A whitelist of allowed x509 Distinguished Names" }
|
||||
|
@ -1,4 +1,8 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
SUBDIRS= schemas
|
||||
|
||||
PERL = perl
|
||||
@ -56,7 +60,12 @@ png = \
|
||||
libvirt-driver-arch.png \
|
||||
libvirt-object-model.png \
|
||||
madeWith.png \
|
||||
et.png
|
||||
et.png \
|
||||
migration-managed-direct.png \
|
||||
migration-managed-p2p.png \
|
||||
migration-native.png \
|
||||
migration-tunnel.png \
|
||||
migration-unmanaged-direct.png
|
||||
|
||||
gif = \
|
||||
architecture.gif \
|
||||
@ -72,12 +81,21 @@ xml = \
|
||||
libvirt-api.xml \
|
||||
libvirt-refs.xml
|
||||
|
||||
qemu_xml = \
|
||||
libvirt-qemu-api.xml \
|
||||
libvirt-qemu-refs.xml
|
||||
|
||||
fig = \
|
||||
libvirt-net-logical.fig \
|
||||
libvirt-net-physical.fig \
|
||||
libvirt-daemon-arch.fig \
|
||||
libvirt-driver-arch.fig \
|
||||
libvirt-object-model.fig
|
||||
libvirt-object-model.fig \
|
||||
migration-managed-direct.fig \
|
||||
migration-managed-p2p.fig \
|
||||
migration-native.fig \
|
||||
migration-tunnel.fig \
|
||||
migration-unmanaged-direct.fig
|
||||
|
||||
EXTRA_DIST= \
|
||||
apibuild.py \
|
||||
@ -85,7 +103,7 @@ EXTRA_DIST= \
|
||||
hacking1.xsl hacking2.xsl wrapstring.xsl \
|
||||
$(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
|
||||
$(devhelphtml) $(devhelppng) $(devhelpcss) $(devhelpxsl) \
|
||||
$(xml) $(fig) $(png) $(css) \
|
||||
$(xml) $(qemu_xml) $(fig) $(png) $(css) \
|
||||
$(patches) \
|
||||
sitemap.html.in \
|
||||
todo.pl hvsupport.pl todo.cfg-example
|
||||
@ -98,13 +116,14 @@ MAINTAINERCLEANFILES = \
|
||||
all: web
|
||||
|
||||
api: $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml
|
||||
qemu_api: $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
|
||||
|
||||
web: $(dot_html) html/index.html devhelp/index.html
|
||||
|
||||
todo.html.in: todo.pl
|
||||
if [ -f todo.cfg ]; then \
|
||||
echo "Generating $@"; \
|
||||
$(PERL) $(srcdir)/$< > $@ \
|
||||
$(PERL) $< > $@ \
|
||||
|| { rm $@ && exit 1; }; \
|
||||
else \
|
||||
echo "Stubbing $@"; \
|
||||
@ -153,35 +172,37 @@ internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
|
||||
|
||||
|
||||
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
|
||||
-@if [ -x $(XSLTPROC) ] ; then \
|
||||
echo "Rebuilding the HTML pages from the XML API" ; \
|
||||
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet -o $(srcdir)/ \
|
||||
$(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi
|
||||
-@if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
|
||||
$(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi && \
|
||||
if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
|
||||
if $(XMLCATALOG) '$(XML_CATALOG_FILE)' "-//W3C//DTD XHTML 1.0 Strict//EN" \
|
||||
> /dev/null ; then \
|
||||
echo "Validating the resulting XHTML pages" ; \
|
||||
SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
|
||||
$(XMLLINT) --catalogs --nonet --valid --noout $(srcdir)/html/*.html ; \
|
||||
else echo "missing XHTML1 DTD" ; fi ; fi
|
||||
|
||||
$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
|
||||
-@echo Rebuilding devhelp files
|
||||
-@if [ -x $(XSLTPROC) ] ; then \
|
||||
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
|
||||
$(XSLTPROC) --nonet -o $(srcdir)/devhelp/ \
|
||||
$(top_srcdir)/docs/devhelp/devhelp.xsl $(srcdir)/libvirt-api.xml ; fi
|
||||
|
||||
|
||||
python_generated_files = \
|
||||
$(srcdir)/html/libvirt-libvirt.html \
|
||||
$(srcdir)/html/libvirt-libvirt-qemu.html \
|
||||
$(srcdir)/html/libvirt-virterror.html \
|
||||
$(srcdir)/libvirt-api.xml \
|
||||
$(srcdir)/libvirt-refs.xml
|
||||
$(srcdir)/libvirt-refs.xml \
|
||||
$(srcdir)/libvirt-qemu-api.xml \
|
||||
$(srcdir)/libvirt-qemu-refs.xml
|
||||
|
||||
$(python_generated_files): $(srcdir)/apibuild.py \
|
||||
$(srcdir)/../include/libvirt/*.h \
|
||||
$(srcdir)/../src/libvirt.c \
|
||||
$(srcdir)/../src/libvirt-qemu.c \
|
||||
$(srcdir)/../src/util/virterror.c
|
||||
$(AM_V_GEN)srcdir=$(srcdir) $(srcdir)/apibuild.py
|
||||
$(AM_V_GEN)srcdir=$(srcdir) $(PYTHON) $(srcdir)/apibuild.py
|
||||
|
||||
check-local: all
|
||||
|
||||
@ -190,8 +211,9 @@ clean-local:
|
||||
|
||||
maintainer-clean-local: clean-local
|
||||
rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml todo.html.in hvsupport.html.in
|
||||
rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
|
||||
|
||||
rebuild: api all
|
||||
rebuild: api qemu_api all
|
||||
|
||||
install-data-local:
|
||||
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
|
||||
|
123
docs/apibuild.py
123
docs/apibuild.py
@ -11,7 +11,9 @@ import os, sys
|
||||
import string
|
||||
import glob
|
||||
|
||||
debug=0
|
||||
quiet=True
|
||||
warnings=0
|
||||
debug=False
|
||||
debugsym=None
|
||||
|
||||
#
|
||||
@ -25,6 +27,11 @@ included_files = {
|
||||
"event.c": "event loop for monitoring file handles",
|
||||
}
|
||||
|
||||
qemu_included_files = {
|
||||
"libvirt-qemu.h": "header with QEMU specific API definitions",
|
||||
"libvirt-qemu.c": "Implementations for the QEMU specific APIs",
|
||||
}
|
||||
|
||||
ignored_words = {
|
||||
"ATTRIBUTE_UNUSED": (0, "macro keyword"),
|
||||
"ATTRIBUTE_SENTINEL": (0, "macro keyword"),
|
||||
@ -95,7 +102,7 @@ class identifier:
|
||||
self.conditionals = None
|
||||
else:
|
||||
self.conditionals = conditionals[:]
|
||||
if self.name == debugsym:
|
||||
if self.name == debugsym and not quiet:
|
||||
print "=> define %s : %s" % (debugsym, (module, type, info,
|
||||
extra, conditionals))
|
||||
|
||||
@ -155,7 +162,7 @@ class identifier:
|
||||
|
||||
def update(self, header, module, type = None, info = None, extra=None,
|
||||
conditionals=None):
|
||||
if self.name == debugsym:
|
||||
if self.name == debugsym and not quiet:
|
||||
print "=> update %s : %s" % (debugsym, (module, type, info,
|
||||
extra, conditionals))
|
||||
if header != None and self.header == None:
|
||||
@ -203,7 +210,7 @@ class index:
|
||||
if d != None and name != None and type != None:
|
||||
self.references[name] = d
|
||||
|
||||
if name == debugsym:
|
||||
if name == debugsym and not quiet:
|
||||
print "New ref: %s" % (d)
|
||||
|
||||
return d
|
||||
@ -244,9 +251,9 @@ class index:
|
||||
elif type == "macro":
|
||||
self.macros[name] = d
|
||||
else:
|
||||
print "Unable to register type ", type
|
||||
self.warning("Unable to register type ", type)
|
||||
|
||||
if name == debugsym:
|
||||
if name == debugsym and not quiet:
|
||||
print "New symbol: %s" % (d)
|
||||
|
||||
return d
|
||||
@ -260,8 +267,8 @@ class index:
|
||||
if self.macros.has_key(id):
|
||||
del self.macros[id]
|
||||
if self.functions.has_key(id):
|
||||
print "function %s from %s redeclared in %s" % (
|
||||
id, self.functions[id].header, idx.functions[id].header)
|
||||
self.warning("function %s from %s redeclared in %s" % (
|
||||
id, self.functions[id].header, idx.functions[id].header))
|
||||
else:
|
||||
self.functions[id] = idx.functions[id]
|
||||
self.identifiers[id] = idx.functions[id]
|
||||
@ -273,15 +280,15 @@ class index:
|
||||
if self.macros.has_key(id):
|
||||
del self.macros[id]
|
||||
if self.variables.has_key(id):
|
||||
print "variable %s from %s redeclared in %s" % (
|
||||
id, self.variables[id].header, idx.variables[id].header)
|
||||
self.warning("variable %s from %s redeclared in %s" % (
|
||||
id, self.variables[id].header, idx.variables[id].header))
|
||||
else:
|
||||
self.variables[id] = idx.variables[id]
|
||||
self.identifiers[id] = idx.variables[id]
|
||||
for id in idx.structs.keys():
|
||||
if self.structs.has_key(id):
|
||||
print "struct %s from %s redeclared in %s" % (
|
||||
id, self.structs[id].header, idx.structs[id].header)
|
||||
self.warning("struct %s from %s redeclared in %s" % (
|
||||
id, self.structs[id].header, idx.structs[id].header))
|
||||
else:
|
||||
self.structs[id] = idx.structs[id]
|
||||
self.identifiers[id] = idx.structs[id]
|
||||
@ -294,8 +301,8 @@ class index:
|
||||
self.identifiers[id] = idx.unions[id]
|
||||
for id in idx.typedefs.keys():
|
||||
if self.typedefs.has_key(id):
|
||||
print "typedef %s from %s redeclared in %s" % (
|
||||
id, self.typedefs[id].header, idx.typedefs[id].header)
|
||||
self.warning("typedef %s from %s redeclared in %s" % (
|
||||
id, self.typedefs[id].header, idx.typedefs[id].header))
|
||||
else:
|
||||
self.typedefs[id] = idx.typedefs[id]
|
||||
self.identifiers[id] = idx.typedefs[id]
|
||||
@ -311,15 +318,15 @@ class index:
|
||||
if self.enums.has_key(id):
|
||||
continue
|
||||
if self.macros.has_key(id):
|
||||
print "macro %s from %s redeclared in %s" % (
|
||||
id, self.macros[id].header, idx.macros[id].header)
|
||||
self.warning("macro %s from %s redeclared in %s" % (
|
||||
id, self.macros[id].header, idx.macros[id].header))
|
||||
else:
|
||||
self.macros[id] = idx.macros[id]
|
||||
self.identifiers[id] = idx.macros[id]
|
||||
for id in idx.enums.keys():
|
||||
if self.enums.has_key(id):
|
||||
print "enum %s from %s redeclared in %s" % (
|
||||
id, self.enums[id].header, idx.enums[id].header)
|
||||
self.warning("enum %s from %s redeclared in %s" % (
|
||||
id, self.enums[id].header, idx.enums[id].header))
|
||||
else:
|
||||
self.enums[id] = idx.enums[id]
|
||||
self.identifiers[id] = idx.enums[id]
|
||||
@ -330,10 +337,10 @@ class index:
|
||||
# check that function condition agrees with header
|
||||
if idx.functions[id].conditionals != \
|
||||
self.functions[id].conditionals:
|
||||
print "Header condition differs from Function for %s:" \
|
||||
% id
|
||||
print " H: %s" % self.functions[id].conditionals
|
||||
print " C: %s" % idx.functions[id].conditionals
|
||||
self.warning("Header condition differs from Function for %s:" \
|
||||
% id)
|
||||
self.warning(" H: %s" % self.functions[id].conditionals)
|
||||
self.warning(" C: %s" % idx.functions[id].conditionals)
|
||||
up = idx.functions[id]
|
||||
self.functions[id].update(None, up.module, up.type, up.info, up.extra)
|
||||
# else:
|
||||
@ -356,12 +363,13 @@ class index:
|
||||
|
||||
|
||||
def analyze(self):
|
||||
self.analyze_dict("functions", self.functions)
|
||||
self.analyze_dict("variables", self.variables)
|
||||
self.analyze_dict("structs", self.structs)
|
||||
self.analyze_dict("unions", self.unions)
|
||||
self.analyze_dict("typedefs", self.typedefs)
|
||||
self.analyze_dict("macros", self.macros)
|
||||
if not quiet:
|
||||
self.analyze_dict("functions", self.functions)
|
||||
self.analyze_dict("variables", self.variables)
|
||||
self.analyze_dict("structs", self.structs)
|
||||
self.analyze_dict("unions", self.unions)
|
||||
self.analyze_dict("typedefs", self.typedefs)
|
||||
self.analyze_dict("macros", self.macros)
|
||||
|
||||
class CLexer:
|
||||
"""A lexer for the C language, tokenize the input by reading and
|
||||
@ -621,6 +629,8 @@ class CParser:
|
||||
info, extra, self.conditionals)
|
||||
|
||||
def warning(self, msg):
|
||||
global warnings
|
||||
warnings = warnings + 1
|
||||
if self.no_error:
|
||||
return
|
||||
print msg
|
||||
@ -1636,7 +1646,10 @@ class CParser:
|
||||
"virDomainMigrateSetMaxSpeed" : (False, ("bandwidth")),
|
||||
"virDomainSetMaxMemory" : (False, ("memory")),
|
||||
"virDomainSetMemory" : (False, ("memory")),
|
||||
"virDomainSetMemoryFlags" : (False, ("memory")) }
|
||||
"virDomainSetMemoryFlags" : (False, ("memory")),
|
||||
"virDomainBlockJobSetSpeed" : (False, ("bandwidth")),
|
||||
"virDomainBlockPull" : (False, ("bandwidth")),
|
||||
"virDomainMigrateGetMaxSpeed" : (False, ("bandwidth")) }
|
||||
|
||||
def checkLongLegacyFunction(self, name, return_type, signature):
|
||||
if "long" in return_type and "long long" not in return_type:
|
||||
@ -1662,7 +1675,8 @@ class CParser:
|
||||
# [unsigned] long long
|
||||
long_legacy_struct_fields = \
|
||||
{ "_virDomainInfo" : ("maxMem", "memory"),
|
||||
"_virNodeInfo" : ("memory") }
|
||||
"_virNodeInfo" : ("memory"),
|
||||
"_virDomainBlockJobInfo" : ("bandwidth") }
|
||||
|
||||
def checkLongLegacyStruct(self, name, fields):
|
||||
for field in fields:
|
||||
@ -1802,7 +1816,8 @@ class CParser:
|
||||
return token
|
||||
|
||||
def parse(self):
|
||||
self.warning("Parsing %s" % (self.filename))
|
||||
if not quiet:
|
||||
print "Parsing %s" % (self.filename)
|
||||
token = self.token()
|
||||
while token != None:
|
||||
if token[0] == 'name':
|
||||
@ -1822,7 +1837,10 @@ class docBuilder:
|
||||
self.name = name
|
||||
self.path = path
|
||||
self.directories = directories
|
||||
self.includes = includes + included_files.keys()
|
||||
if name == "libvirt":
|
||||
self.includes = includes + included_files.keys()
|
||||
elif name == "libvirt-qemu":
|
||||
self.includes = includes + qemu_included_files.keys()
|
||||
self.modules = {}
|
||||
self.headers = {}
|
||||
self.idx = index()
|
||||
@ -1869,7 +1887,8 @@ class docBuilder:
|
||||
pass
|
||||
|
||||
def analyze(self):
|
||||
print "Project %s : %d headers, %d modules" % (self.name, len(self.headers.keys()), len(self.modules.keys()))
|
||||
if not quiet:
|
||||
print "Project %s : %d headers, %d modules" % (self.name, len(self.headers.keys()), len(self.modules.keys()))
|
||||
self.idx.analyze()
|
||||
|
||||
def scanHeaders(self):
|
||||
@ -1995,7 +2014,7 @@ class docBuilder:
|
||||
else:
|
||||
output.write(" <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc))
|
||||
except:
|
||||
print "Failed to serialize struct %s" % (name)
|
||||
self.warning("Failed to serialize struct %s" % (name))
|
||||
output.write(" </struct>\n")
|
||||
else:
|
||||
output.write("/>\n");
|
||||
@ -2023,7 +2042,7 @@ class docBuilder:
|
||||
|
||||
def serialize_function(self, output, name):
|
||||
id = self.idx.functions[name]
|
||||
if name == debugsym:
|
||||
if name == debugsym and not quiet:
|
||||
print "=>", id
|
||||
|
||||
output.write(" <%s name='%s' file='%s' module='%s'>\n" % (id.type,
|
||||
@ -2059,7 +2078,7 @@ class docBuilder:
|
||||
output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2])))
|
||||
self.indexString(name, param[2])
|
||||
except:
|
||||
print "Failed to save function %s info: " % name, `id.info`
|
||||
self.warning("Failed to save function %s info: " % name, `id.info`)
|
||||
output.write(" </%s>\n" % (id.type))
|
||||
|
||||
def serialize_exports(self, output, file):
|
||||
@ -2074,7 +2093,7 @@ class docBuilder:
|
||||
escape(dict.info[data]),
|
||||
string.lower(data)))
|
||||
except:
|
||||
print "Header %s lacks a %s description" % (module, data)
|
||||
self.warning("Header %s lacks a %s description" % (module, data))
|
||||
if dict.info.has_key('Description'):
|
||||
desc = dict.info['Description']
|
||||
if string.find(desc, "DEPRECATED") != -1:
|
||||
@ -2287,7 +2306,8 @@ class docBuilder:
|
||||
|
||||
def serialize(self):
|
||||
filename = "%s/%s-api.xml" % (self.path, self.name)
|
||||
print "Saving XML description %s" % (filename)
|
||||
if not quiet:
|
||||
print "Saving XML description %s" % (filename)
|
||||
output = open(filename, "w")
|
||||
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
|
||||
output.write("<api name='%s'>\n" % self.name)
|
||||
@ -2323,7 +2343,8 @@ class docBuilder:
|
||||
output.close()
|
||||
|
||||
filename = "%s/%s-refs.xml" % (self.path, self.name)
|
||||
print "Saving XML Cross References %s" % (filename)
|
||||
if not quiet:
|
||||
print "Saving XML Cross References %s" % (filename)
|
||||
output = open(filename, "w")
|
||||
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
|
||||
output.write("<apirefs name='%s'>\n" % self.name)
|
||||
@ -2332,24 +2353,29 @@ class docBuilder:
|
||||
output.close()
|
||||
|
||||
|
||||
def rebuild():
|
||||
def rebuild(name):
|
||||
if name not in ["libvirt", "libvirt-qemu"]:
|
||||
self.warning("rebuild() failed, unkown module %s") % name
|
||||
return None
|
||||
builder = None
|
||||
srcdir = os.environ["srcdir"]
|
||||
if glob.glob(srcdir + "/../src/libvirt.c") != [] :
|
||||
print "Rebuilding API description for libvirt"
|
||||
if not quiet:
|
||||
print "Rebuilding API description for %s" % name
|
||||
dirs = [srcdir + "/../src",
|
||||
srcdir + "/../src/util",
|
||||
srcdir + "/../include/libvirt"]
|
||||
if glob.glob(srcdir + "/../include/libvirt/libvirt.h") == [] :
|
||||
dirs.append("../include/libvirt")
|
||||
builder = docBuilder("libvirt", srcdir, dirs, [])
|
||||
builder = docBuilder(name, srcdir, dirs, [])
|
||||
elif glob.glob("src/libvirt.c") != [] :
|
||||
print "Rebuilding API description for libvirt"
|
||||
builder = docBuilder("libvirt", srcdir,
|
||||
if not quiet:
|
||||
print "Rebuilding API description for %s" % name
|
||||
builder = docBuilder(name, srcdir,
|
||||
["src", "src/util", "include/libvirt"],
|
||||
[])
|
||||
else:
|
||||
print "rebuild() failed, unable to guess the module"
|
||||
self.warning("rebuild() failed, unable to guess the module")
|
||||
return None
|
||||
builder.scan()
|
||||
builder.analyze()
|
||||
@ -2369,4 +2395,9 @@ if __name__ == "__main__":
|
||||
debug = 1
|
||||
parse(sys.argv[1])
|
||||
else:
|
||||
rebuild()
|
||||
rebuild("libvirt")
|
||||
rebuild("libvirt-qemu")
|
||||
if warnings > 0:
|
||||
sys.exit(2)
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
@ -202,6 +202,16 @@
|
||||
<h2><a name="iaas">Infrastructure as a Service (IaaS)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.emotivecloud.net">EMOTIVE Cloud</a></dt>
|
||||
<dd>The EMOTIVE (Elastic Management Of Tasks In Virtualized
|
||||
Environments) middleware allows executing tasks and providing
|
||||
virtualized environments to the users with Xen, KVM or
|
||||
VirtualBox hypervisor. EMOTIVE's main feature is VM management
|
||||
with different scheduling policies. It can be also used as a
|
||||
cloud provider and is very easy to extend thanks to its
|
||||
modular Web Services architecture.
|
||||
</dd>
|
||||
|
||||
<dt><a href="http://www.nimbusproject.org">Nimbus</a></dt>
|
||||
<dd>
|
||||
Nimbus is an open-source toolkit focused on providing
|
||||
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -28,6 +28,7 @@
|
||||
<li><strong><a href="drvesx.html">VMware ESX</a></strong></li>
|
||||
<li><strong><a href="drvvmware.html">VMware Workstation/Player</a></strong></li>
|
||||
<li><strong><a href="drvxen.html">Xen</a></strong></li>
|
||||
<li><strong><a href="drvhyperv.html">Microsoft Hyper-V</a></strong></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="stroage">Storage drivers</a></h2>
|
||||
|
@ -8,6 +8,14 @@
|
||||
connect to a VMware vCenter 2.5/4.x (VPX).
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.vmware.com/">VMware ESX and GSX</a>
|
||||
hypervisors
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="prereq">Deployment pre-requisites</a></h2>
|
||||
<p>
|
||||
@ -48,7 +56,7 @@ esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the s
|
||||
URIs have this general form (<code>[...]</code> marks an optional part).
|
||||
</p>
|
||||
<pre>
|
||||
type://[username@]hostname[:port]/[datacenter[/cluster]/server][?extraparameters]
|
||||
type://[username@]hostname[:port]/[[folder/...]datacenter/[folder/...][cluster/]server][?extraparameters]
|
||||
</pre>
|
||||
<p>
|
||||
The <code>type://</code> is either <code>esx://</code> or
|
||||
@ -71,6 +79,14 @@ type://[username@]hostname[:port]/[datacenter[/cluster]/server][?extraparameters
|
||||
</p>
|
||||
<pre>
|
||||
vpx://example-vcenter.com/dc1/cluster1/example-esx.com
|
||||
</pre>
|
||||
<p>
|
||||
Datacenters and clusters can be organized in folders, those have to be
|
||||
specified as well. The driver can handle folders
|
||||
<span class="since">since 0.9.7</span>.
|
||||
</p>
|
||||
<pre>
|
||||
vpx://example-vcenter.com/folder1/dc1/folder2/example-esx.com
|
||||
</pre>
|
||||
|
||||
|
||||
|
112
docs/drvhyperv.html.in
Normal file
112
docs/drvhyperv.html.in
Normal file
@ -0,0 +1,112 @@
|
||||
<html><body>
|
||||
<h1>Microsoft Hyper-V hypervisor driver</h1>
|
||||
<ul id="toc"></ul>
|
||||
<p>
|
||||
The libvirt Microsoft Hyper-V driver can manage Hyper-V 2008 R2.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.microsoft.com/hyper-v-server/">Microsoft Hyper-V</a>
|
||||
hypervisor
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a name="uri">Connections to the Microsoft Hyper-V driver</a></h2>
|
||||
<p>
|
||||
Some example remote connection URIs for the driver are:
|
||||
</p>
|
||||
<pre>
|
||||
hyperv://example-hyperv.com (over HTTPS)
|
||||
hyperv://example-hyperv.com/?transport=http (over HTTP)
|
||||
</pre>
|
||||
<p>
|
||||
<strong>Note</strong>: In contrast to other drivers, the Hyper-V driver
|
||||
is a client-side-only driver. It connects to the Hyper-V server using
|
||||
WS-Management over HTTP(S). Therefore, the
|
||||
<a href="remote.html">remote transport mechanism</a> provided by the
|
||||
remote driver and libvirtd will not work, and you cannot use URIs like
|
||||
<code>hyperv+ssh://example.com</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a name="uriformat">URI Format</a></h3>
|
||||
<p>
|
||||
URIs have this general form (<code>[...]</code> marks an optional part).
|
||||
</p>
|
||||
<pre>
|
||||
hyperv://[username@]hostname[:port]/[?extraparameters]
|
||||
</pre>
|
||||
<p>
|
||||
The default HTTPS ports is 5986. If the port parameter is given, it
|
||||
overrides the default port.
|
||||
</p>
|
||||
|
||||
|
||||
<h4><a name="extraparams">Extra parameters</a></h4>
|
||||
<p>
|
||||
Extra parameters can be added to a URI as part of the query string
|
||||
(the part following <code>?</code>). A single parameter is formed by a
|
||||
<code>name=value</code> pair. Multiple parameters are separated by
|
||||
<code>&</code>.
|
||||
</p>
|
||||
<pre>
|
||||
?transport=http
|
||||
</pre>
|
||||
<p>
|
||||
The driver understands the extra parameters shown below.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Values</th>
|
||||
<th>Meaning</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>transport</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>http</code> or <code>https</code>
|
||||
</td>
|
||||
<td>
|
||||
Overrides the default HTTPS transport. The default HTTP port
|
||||
is 5985.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h3><a name="auth">Authentication</a></h3>
|
||||
<p>
|
||||
In order to perform any useful operation the driver needs to log into
|
||||
the Hyper-V server. Therefore, only <code>virConnectOpenAuth</code> can
|
||||
be used to connect to an Hyper-V server, <code>virConnectOpen</code> and
|
||||
<code>virConnectOpenReadOnly</code> don't work.
|
||||
To log into an Hyper-V server the driver will request credentials using
|
||||
the callback passed to the <code>virConnectOpenAuth</code> function.
|
||||
The driver passes the hostname as challenge parameter to the callback.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Note</strong>: Currently only <code>Basic</code> authentication
|
||||
is supported by libvirt. This method is disabled by default on the
|
||||
Hyper-V server and can be enabled via the WinRM commandline tool.
|
||||
</p>
|
||||
<pre>
|
||||
winrm set winrm/config/service/auth @{Basic="true"}
|
||||
</pre>
|
||||
<p>
|
||||
To allow <code>Basic</code> authentication with HTTP transport WinRM
|
||||
needs to allow unencrypted communication. This can be enabled via the
|
||||
WinRM commandline tool. However, this is not the recommended
|
||||
communication mode.
|
||||
</p>
|
||||
<pre>
|
||||
winrm set winrm/config/service @{AllowUnencrypted="true"}
|
||||
</pre>
|
||||
|
||||
|
||||
</body></html>
|
@ -5,10 +5,18 @@
|
||||
The libvirt LXC driver manages "Linux Containers". Containers are sets of processes
|
||||
with private namespaces which can (but don't always) look like separate machines, but
|
||||
do not have their own OS. Here are two example configurations. The first is a very
|
||||
light-weight "application container" which does not have it's own root image. You would
|
||||
start it using
|
||||
light-weight "application container" which does not have its own root image.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://lxc.sourceforge.net/">LXC</a> Linux
|
||||
container system
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Cgroups Requirements</h2>
|
||||
|
||||
<p>
|
||||
@ -31,6 +39,23 @@ driver. On such kernels, it may be neccessary to unmount the blkio controller.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Environment setup for the container init</h2>
|
||||
|
||||
<p>
|
||||
When the container "init" process is started, it will be given several useful
|
||||
environment variables.
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt>LIBVIRT_LXC_NAME</dt>
|
||||
<dd>The name assigned to the container by libvirt</dd>
|
||||
<dt>LIBVIRT_LXC_UUID</dt>
|
||||
<dd>The UUID assigned to the container by libvirt</dd>
|
||||
<dt>LIBVIRT_LXC_CMDLINE</dt>
|
||||
<dd>The unparsed command line arguments specified in the container configuration</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h3>Example config version 1</h3>
|
||||
<p></p>
|
||||
<pre>
|
||||
|
@ -13,6 +13,15 @@
|
||||
undue trouble.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://openvz.org/">OpenVZ</a> Linux container
|
||||
system
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="connections">Connections to OpenVZ driver</a></h2>
|
||||
|
||||
<p>
|
||||
|
@ -1,21 +1,35 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>QEMU/KVM hypervisor driver</h1>
|
||||
<h1>KVM/QEMU hypervisor driver</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
The libvirt QEMU driver can manage any QEMU emulator from version 0.8.1
|
||||
or later. It can also manage anything that provides the same QEMU command
|
||||
line syntax and monitor interaction. This includes KVM, and Xenner.
|
||||
The libvirt KVM/QEMU driver can manage any QEMU emulator from
|
||||
version 0.8.1 or later. It can also manage Xenner, which
|
||||
provides the same QEMU command line syntax and monitor
|
||||
interaction.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.linux-kvm.org/">KVM</a> Linux
|
||||
hypervisor
|
||||
<li>
|
||||
The <a href="http://wiki.qemu.org/Index.html">QEMU</a> emulator
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="prereq">Deployment pre-requisites</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>QEMU emulators</strong>: The driver will probe <code>/usr/bin</code>
|
||||
for the presence of <code>qemu</code>, <code>qemu-system-x86_64</code>,
|
||||
<code>qemu-system-microblaze</code>,
|
||||
<code>qemu-system-microblazeel</code>,
|
||||
<code>qemu-system-mips</code>,<code>qemu-system-mipsel</code>,
|
||||
<code>qemu-system-sparc</code>,<code>qemu-system-ppc</code>. The results
|
||||
of this can be seen from the capabilities XML output.
|
||||
@ -194,7 +208,7 @@ chmod o+x /path/to/directory
|
||||
|
||||
<p>
|
||||
If the QEMU driver is configured to run virtual machines as non-root,
|
||||
then they will already loose all their process capabilities at time
|
||||
then they will already lose all their process capabilities at time
|
||||
of startup. The Linux capability feature is thus aimed primarily at
|
||||
the scenario where the QEMU processes are running as root. In this
|
||||
case, before launching a QEMU virtual machine, libvirtd will use
|
||||
@ -499,6 +513,73 @@ $ virsh domxml-to-native qemu-argv demo.xml
|
||||
-serial none -parallel none -usb
|
||||
</pre>
|
||||
|
||||
<h2><a name="qemucommand">Pass-through of arbitrary qemu
|
||||
commands</a></h2>
|
||||
|
||||
<p>Libvirt provides an XML namespace and an optional
|
||||
library <code>libvirt-qemu.so</code> for dealing specifically
|
||||
with qemu. When used correctly, these extensions allow testing
|
||||
specific qemu features that have not yet been ported to the
|
||||
generic libvirt XML and API interfaces. However, they
|
||||
are <b>unsupported</b>, in that the library is not guaranteed to
|
||||
have a stable API, abusing the library or XML may result in
|
||||
inconsistent state the crashes libvirtd, and upgrading either
|
||||
qemu-kvm or libvirtd may break behavior of a domain that was
|
||||
relying on a qemu-specific pass-through. If you find yourself
|
||||
needing to use them to access a particular qemu feature, then
|
||||
please post an RFE to the libvirt mailing list to get that
|
||||
feature incorporated into the stable libvirt XML and API
|
||||
interfaces.
|
||||
</p>
|
||||
<p>The library provides two
|
||||
API: <code>virDomainQemuMonitorCommand</code>, for sending an
|
||||
arbitrary monitor command (in either HMP or QMP format) to a
|
||||
qemu guest (<span class="since">Since 0.8.3</span>),
|
||||
and <code>virDomainQemuAttach</code>, for registering a qemu
|
||||
domain that was manually started so that it can then be managed
|
||||
by libvirtd (<span class="since">Since 0.9.4</span>).
|
||||
</p>
|
||||
<p>Additionally, the following XML additions allow fine-tuning of
|
||||
the command line given to qemu when starting a domain
|
||||
(<span class="since">Since 0.8.3</span>). In order to use the
|
||||
XML additions, it is necessary to issue an XML namespace request
|
||||
(the special <code>xmlns:<i>name</i></code> attribute) that
|
||||
pulls in <code>http://libirt.org/schemas/domain/qemu/1.0</code>;
|
||||
typically, the namespace is given the name
|
||||
of <code>qemu</code>. With the namespace in place, it is then
|
||||
possible to add an element <code><qemu:commandline></code>
|
||||
under <code>driver</code>, with the following sub-elements
|
||||
repeated as often as needed:
|
||||
<dl>
|
||||
<dt><code>qemu:arg</code></dt>
|
||||
<dd>Add an additional command-line argument to the qemu
|
||||
process when starting the domain, given by the value of the
|
||||
attribute <code>value</code>.
|
||||
</dd>
|
||||
<dt><code>qemu:env</code></dt>
|
||||
<dd>Add an additional environment variable to the qemu
|
||||
process when starting the domain, given with the name-value
|
||||
pair recorded in the attributes <code>name</code>
|
||||
and optional <code>value</code>.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Example:</p><pre>
|
||||
<domain type='qemu' xmlns:qemu='http://libirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>QEmu-fedora-i686</name>
|
||||
<memory>219200</memory>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
</os>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
</devices>
|
||||
<qemu:commandline>
|
||||
<qemu:arg value='-newarg'/>
|
||||
<qemu:env name='QEMU_ENV' value='VAL'/>
|
||||
</qemu:commandline>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<h2><a name="xmlconfig">Example domain XML config</a></h2>
|
||||
|
||||
<h3>QEMU emulated guest on x86_64</h3>
|
||||
|
@ -11,6 +11,15 @@
|
||||
has pre-created TAP devices.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://user-mode-linux.sourceforge.net/">User
|
||||
Mode Linux</a> paravirtualized kernel
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Connections to UML driver</h2>
|
||||
|
||||
<p>
|
||||
|
@ -6,6 +6,15 @@
|
||||
from version 2.2 onwards.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.virtualbox.org/">VirtualBox</a>
|
||||
hypervisor
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Connections to VirtualBox driver</h2>
|
||||
|
||||
<p>
|
||||
@ -61,6 +70,11 @@ vbox+ssh://user@example.com/session (remote access, SSH tunnelled)
|
||||
<target dev='fda'/>
|
||||
</disk>
|
||||
|
||||
<filesystem type='mount'>
|
||||
<source dir='/home/user/stuff'/>
|
||||
<target dir='my-shared-folder'/>
|
||||
</filesystem>
|
||||
|
||||
<!--BRIDGE-->
|
||||
<interface type='bridge'>
|
||||
<source bridge='eth0'/>
|
||||
|
@ -12,6 +12,15 @@
|
||||
from <a href="http://www.vmware.com/support/developer/vix-api/">here</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.vmware.com/">VMware Workstation and
|
||||
Player</a> hypervisors
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Connections to VMware driver</h2>
|
||||
|
||||
<p>
|
||||
|
@ -9,6 +9,15 @@
|
||||
on any Xen release from 3.0.1 onwards.
|
||||
</p>
|
||||
|
||||
<h2><a name="project">Project Links</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html">Xen</a>
|
||||
hypervisor on Linux and Solaris hosts
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="prereq">Deployment pre-requisites</a></h2>
|
||||
|
||||
<p>
|
||||
|
@ -28,6 +28,11 @@ BIOS you will see</p>
|
||||
<feature name='xtpr'/>
|
||||
...
|
||||
</cpu>
|
||||
<power_management>
|
||||
<suspend_mem/>
|
||||
<suspend_disk/>
|
||||
<suspend_hybrid/>
|
||||
<power_management/>
|
||||
</host></span>
|
||||
|
||||
<!-- xen-3.0-x86_64 -->
|
||||
@ -60,20 +65,30 @@ BIOS you will see</p>
|
||||
</guest></span>
|
||||
...
|
||||
</capabilities></pre>
|
||||
<p>The first block (in red) indicates the host hardware capabilities, currently
|
||||
it is limited to the CPU properties but other information may be available,
|
||||
it shows the CPU architecture, topology, model name, and additional features
|
||||
which are not included in the model but the CPU provides them. Features of the
|
||||
chip are shown within the feature block (the block is similar to what you will
|
||||
find in a Xen fully virtualized domain description).</p>
|
||||
<p>The second block (in blue) indicates the paravirtualization support of the
|
||||
Xen support, you will see the os_type of xen to indicate a paravirtual
|
||||
kernel, then architecture information and potential features.</p>
|
||||
<p>The third block (in green) gives similar information but when running a
|
||||
32 bit OS fully virtualized with Xen using the hvm support.</p>
|
||||
<p>This section is likely to be updated and augmented in the future, see <a href="https://www.redhat.com/archives/libvir-list/2007-March/msg00215.html">the
|
||||
discussion</a> which led to the capabilities format in the mailing-list
|
||||
archives.</p>
|
||||
<p>The first block (in red) indicates the host hardware
|
||||
capabilities, such as CPU properties and the power
|
||||
management features of the host platform. CPU models are
|
||||
shown as additional features relative to the closest base
|
||||
model, within a feature block (the block is similar to what
|
||||
you will find in a Xen fully virtualized domain
|
||||
description). Further, the power management features
|
||||
supported by the host are shown, such as Suspend-to-RAM (S3),
|
||||
Suspend-to-Disk (S4) and Hybrid-Suspend (a combination of S3
|
||||
and S4). In case the host does not support
|
||||
any such feature, then an empty <power_management/>
|
||||
tag will be shown. </p>
|
||||
<p>The second block (in blue) indicates the paravirtualization
|
||||
support of the Xen support, you will see the os_type of xen
|
||||
to indicate a paravirtual kernel, then architecture
|
||||
information and potential features.</p>
|
||||
<p>The third block (in green) gives similar information but
|
||||
when running a 32 bit OS fully virtualized with Xen using
|
||||
the hvm support.</p>
|
||||
<p>This section is likely to be updated and augmented in the
|
||||
future,
|
||||
see <a href="https://www.redhat.com/archives/libvir-list/2007-March/msg00215.html">the
|
||||
discussion</a> which led to the capabilities format in the
|
||||
mailing-list archives.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,7 @@
|
||||
<pre>
|
||||
...
|
||||
<bridge name="virbr0" stp="on" delay="5"/>
|
||||
<domain name="example"/>
|
||||
<domain name="example.com"/>
|
||||
<forward mode="nat" dev="eth0"/>
|
||||
...</pre>
|
||||
|
||||
@ -70,37 +70,263 @@
|
||||
bridge device allowing them to talk to each other. The bridge device
|
||||
may also be connected to the LAN. It is recommended that bridge
|
||||
device names started with the prefix <code>vir</code>, but the name
|
||||
<code>virbr0</code> is reserved for the "default" virtual network.
|
||||
This element should always be provided when defining a new network.
|
||||
Attribute <code>stp</code> specifies if Spanning Tree Protocol is
|
||||
'on' or 'off' (default is 'on'). Attribute <code>delay</code> sets
|
||||
the bridge's forward delay value in seconds (default is 0).
|
||||
<code>virbr0</code> is reserved for the "default" virtual
|
||||
network. This element should always be provided when defining
|
||||
a new network with a <code><forward></code> mode of
|
||||
"nat" or "route" (or an isolated network with
|
||||
no <code><forward></code> element).
|
||||
Attribute <code>stp</code> specifies if Spanning Tree Protocol
|
||||
is 'on' or 'off' (default is
|
||||
'on'). Attribute <code>delay</code> sets the bridge's forward
|
||||
delay value in seconds (default is 0).
|
||||
<span class="since">Since 0.3.0</span>
|
||||
</dd>
|
||||
<dt><code>domain</code></dt>
|
||||
<dd>
|
||||
The <code>name</code> attribute on the <code>domain</code> element
|
||||
defines the DNS domain of the DHCP server. This element is optional.
|
||||
<span class="since">Since 0.4.5</span>
|
||||
The <code>name</code> attribute on the <code>domain</code>
|
||||
element defines the DNS domain of the DHCP server. This
|
||||
element is optional, and is only used for those networks with
|
||||
a <code><forward></code> mode of "nat" or "route" (or an
|
||||
isolated network with no <code><forward></code>
|
||||
element). <span class="since">Since 0.4.5</span>
|
||||
</dd>
|
||||
<dt><code>forward</code></dt>
|
||||
<dd>Inclusion of the <code>forward</code> element indicates that
|
||||
the virtual network is to be connected to the physical
|
||||
LAN. the <code>mode</code> attribute determines the method of
|
||||
forwarding; possible selections are 'nat' and 'route'. If mode
|
||||
is not specified, NAT forwarding will be used for
|
||||
connectivity. If a network has any IPv6 addresses defined,
|
||||
even if <code>mode</code> is given as 'nat', the IPv6 traffic
|
||||
will be forwarded using routing, since IPv6 has no concept of NAT.
|
||||
Firewall rules will allow forwarding to any other network device whether
|
||||
ethernet, wireless, dialup, or VPN. If the <code>dev</code> attribute
|
||||
is set, the firewall rules will restrict forwarding to the named
|
||||
device only. If the <code>mode</code> attribute is set to <code>route</code>
|
||||
then the traffic will not have NAT applied. This presumes that the
|
||||
local LAN router has suitable routing table entries to return traffic
|
||||
to this host. <span class="since">Since 0.3.0; 'mode' attribute since
|
||||
0.4.2</span></dd>
|
||||
LAN.<span class="since">Since 0.3.0.</span>
|
||||
The <code>mode</code> attribute determines the method of
|
||||
forwarding. If there is no <code>forward</code> element, the
|
||||
network will be isolated from any other network (unless a
|
||||
guest connected to that network is acting as a router, of
|
||||
course). The following are valid settings
|
||||
for <code>mode</code> (if there is a <code>forward</code>
|
||||
element but mode is not specified, <code>mode='nat'</code> is
|
||||
assumed):
|
||||
<dl>
|
||||
<dt><code>nat</code></dt>
|
||||
<dd>
|
||||
All traffic between guests connected to this network and
|
||||
the physical network will be forwarded to the physical
|
||||
network via the host's IP routing stack, after the guest's
|
||||
IP address is translated to appear as the host machine's
|
||||
public IP address (a.k.a. Network Address Translation, or
|
||||
"NAT"). This allows multiple guests, all having access to
|
||||
the physical network, on a host that is only allowed a
|
||||
single public IP address. If a network has any IPv6
|
||||
addresses defined, the IPv6 traffic will be forwarded
|
||||
using plain routing, since IPv6 has no concept of NAT.
|
||||
Firewall rules will allow outbound connections to any
|
||||
other network device whether ethernet, wireless, dialup,
|
||||
or VPN. If the <code>dev</code> attribute is set, the
|
||||
firewall rules will restrict forwarding to the named
|
||||
device only. Inbound connections from other networks are
|
||||
all prohibited; all connections between guests on the same
|
||||
network, and to/from the host to the guests, are
|
||||
unrestricted and not NATed.<span class="since">Since
|
||||
0.4.2</span>
|
||||
</dd>
|
||||
|
||||
<dt><code>route</code></dt>
|
||||
<dd>
|
||||
Guest network traffic will be forwarded to the physical
|
||||
network via the host's IP routing stack, but without
|
||||
having NAT applied. Again, if the <code>dev</code>
|
||||
attribute is set, firewall rules will restrict forwarding
|
||||
to the named device only. This presumes that the local LAN
|
||||
router has suitable routing table entries to return
|
||||
traffic to this host. All incoming and outgoing sessions
|
||||
to guest on these networks are unrestricted. (To restrict
|
||||
incoming traffic to a guest on a routed network, you can
|
||||
configure <a href="formatnwfilter.html">nwfilter rules</a>
|
||||
on the guest's interfaces.)
|
||||
<span class="since">Since 0.4.2</span>
|
||||
</dd>
|
||||
|
||||
<dt><code>bridge</code></dt>
|
||||
<dd>
|
||||
This network describes either 1) an existing host bridge
|
||||
that was configured outside of libvirt (if
|
||||
a <code><bridge name='xyz'/></code> element has been
|
||||
specified), or 2) an interface or group of interfaces to
|
||||
be used for a "direct" connection via macvtap using
|
||||
macvtap's "bridge" mode (if the forward element has one or
|
||||
more <code><interface></code> subelements)
|
||||
(see <a href="formatdomain.html#elementsNICSDirect">Direct
|
||||
attachment to physical interface</a> for descriptions of
|
||||
the various macvtap modes). libvirt doesn't attempt to
|
||||
manage the bridge interface at all, thus
|
||||
the <code><bridge></code> element's <code>stp</code>
|
||||
and <code>delay</code> attributes are not allowed; no
|
||||
iptables rules, IP addresses, or DHCP/DNS services are
|
||||
added; at the IP level, the guest interface appears to be
|
||||
directly connected to the physical
|
||||
interface.<span class="since">Since 0.9.4</span>
|
||||
</dd>
|
||||
<dt><code>private</code></dt>
|
||||
<dd>
|
||||
This network uses a macvtap "direct" connection in
|
||||
"private" mode to connect each guest to the network. The
|
||||
physical interface to be used will be picked from among
|
||||
those listed in <code><interface></code> subelements
|
||||
of the <code><forward></code> element; when using
|
||||
802.1Qbh mode (as indicated by
|
||||
the <code><virtualport></code> type attribute - note
|
||||
that this requires an 802.1Qbh-capable hardware switch),
|
||||
each physical interface can only be in use by a single
|
||||
guest interface at a time; in modes other than 802.1Qbh,
|
||||
multiple guest interfaces can share each physical
|
||||
interface (libvirt will attempt to balance usage between
|
||||
all available interfaces).<span class="since">Since
|
||||
0.9.4</span>
|
||||
</dd>
|
||||
<dt><code>vepa</code></dt>
|
||||
<dd>
|
||||
This network uses a macvtap "direct" connection in "vepa"
|
||||
mode to connect each guest to the network (this requires
|
||||
that the physical interfaces used be connected to a
|
||||
vepa-capable hardware switch. The physical interface to be
|
||||
used will be picked from among those listed
|
||||
in <code><interface></code> subelements of
|
||||
the <code><forward></code> element; multiple guest
|
||||
interfaces can share each physical interface (libvirt will
|
||||
attempt to balance usage between all available
|
||||
interfaces).<span class="since">Since 0.9.4</span>
|
||||
</dd>
|
||||
<dt><code>passthrough</code></dt>
|
||||
<dd>
|
||||
This network uses a macvtap "direct" connection in
|
||||
"passthrough" mode to connect each guest to the network
|
||||
(note that this is <i>not</i> the same thing as "PCI
|
||||
passthrough"). The physical interface to be used will be
|
||||
picked from among those listed
|
||||
in <code><interface></code> subelements of
|
||||
the <code><forward></code> element. Each physical
|
||||
interface can only be in use by a single guest interface
|
||||
at a time, so libvirt will keep track of which interfaces
|
||||
are currently in use, and only assign unused interfaces
|
||||
(if there are no available physical interfaces when a
|
||||
domain interface is being attached, an error will be
|
||||
logged, and the operation causing the attach will fail
|
||||
(usually either a domain start, or a hotplug interface
|
||||
attach to a domain).<span class="since">Since 0.9.4</span>
|
||||
</dd>
|
||||
</dl>
|
||||
As mentioned above, a <code><forward></code> element can
|
||||
have multiple <code><interface></code> subelements, each
|
||||
one giving the name of a physical interface that can be used
|
||||
for this network <span class="since">Since 0.9.4</span>:
|
||||
<pre>
|
||||
...
|
||||
<forward mode='passthrough'>
|
||||
<interface dev='eth10'/>
|
||||
<interface dev='eth11'/>
|
||||
<interface dev='eth12'/>
|
||||
<interface dev='eth13'/>
|
||||
<interface dev='eth14'/>
|
||||
</forward>
|
||||
...
|
||||
</pre>
|
||||
When a guest interface is being constructed, libvirt will pick
|
||||
an interface from this list to use for the connection. In
|
||||
modes where physical interfaces can be shared by multiple
|
||||
guest interfaces, libvirt will choose the interface that
|
||||
currently has the least number of connections. For those modes
|
||||
that do not allow sharing of the physical device (in
|
||||
particular, 'passthrough' mode, and 'private' mode when using
|
||||
802.1Qbh), libvirt will choose an unused physical interface
|
||||
or, if it can't find an unused interface, fail the operation.
|
||||
</dd>
|
||||
</dl>
|
||||
<h5><a name="elementQoS">Quality of service</a></h5>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<forward mode='nat' dev='eth0'/>
|
||||
<b><bandwidth>
|
||||
<inbound average='1000' peak='5000' burst='5120'/>
|
||||
<outbound average='128' peak='256' burst='256'/>
|
||||
</bandwidth></b>
|
||||
...</pre>
|
||||
|
||||
<p>
|
||||
This part of network XML provides setting quality of service. Incoming
|
||||
and outgoing traffic can be shaped independently. The
|
||||
<code>bandwidth</code> element can have at most one <code>inbound</code>
|
||||
and at most one <code>outbound</code> child elements. Leaving any of these
|
||||
children element out result in no QoS applied on that traffic direction.
|
||||
So, when you want to shape only network's incoming traffic, use
|
||||
<code>inbound</code> only, and vice versa. Each of these elements have one
|
||||
mandatory attribute <code>average</code>. It specifies average bit rate on
|
||||
interface being shaped. Then there are two optional attributes:
|
||||
<code>peak</code>, which specifies maximum rate at which bridge can send
|
||||
data, and <code>burst</code>, amount of bytes that can be burst at
|
||||
<code>peak</code> speed. Accepted values for attributes are integer
|
||||
numbers, The units for <code>average</code> and <code>peak</code> attributes
|
||||
are kilobytes per second, and for the <code>burst</code> just kilobytes.
|
||||
The rate is shared equally within domains connected to the network.
|
||||
Moreover, <code>bandwidth</code> element can be included in
|
||||
<code>portgroup</code> element.
|
||||
<span class="since">Since 0.9.4</span>
|
||||
</p>
|
||||
|
||||
<h5><a name="elementsPortgroup">Portgroups</a></h5>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<forward mode='private'/>
|
||||
<interface dev="eth20"/>
|
||||
<interface dev="eth21"/>
|
||||
<interface dev="eth22"/>
|
||||
<interface dev="eth23"/>
|
||||
<interface dev="eth24"/>
|
||||
</forward>
|
||||
<b><portgroup name='engineering' default='yes'>
|
||||
<virtualport type='802.1Qbh'>
|
||||
<parameters profileid='test'/>
|
||||
</virtualport>
|
||||
<bandwidth>
|
||||
<inbound average='1000' peak='5000' burst='5120'/>
|
||||
<outbound average='1000' peak='5000' burst='5120'/>
|
||||
</bandwidth>
|
||||
</portgroup></b>
|
||||
<b><portgroup name='sales'>
|
||||
<virtualport type='802.1Qbh'>
|
||||
<parameters profileid='salestest'/>
|
||||
</virtualport>
|
||||
<bandwidth>
|
||||
<inbound average='500' peak='2000' burst='2560'/>
|
||||
<outbound average='128' peak='256' burst='256'/>
|
||||
</bandwidth>
|
||||
</portgroup></b>
|
||||
...</pre>
|
||||
|
||||
<p>
|
||||
<span class="since">Since 0.9.4</span>
|
||||
A portgroup provides a method of easily putting guest
|
||||
connections to the network into different classes, with each
|
||||
class potentially having a different level/type of service.
|
||||
<span class="since">Since 0.9.4</span> Each
|
||||
network can have multiple portgroup elements (and one of those
|
||||
can optionally be designated as the 'default' portgroup for the
|
||||
network), and each portgroup has a name, as well as various
|
||||
subelements associated with it. The currently supported
|
||||
subelements are <code><bandwidth></code>
|
||||
(documented <a href="formatdomain.html#elementQoS">here</a>)
|
||||
and <code><virtualport></code>
|
||||
(documented <a href="formatdomain.html#elementsNICSDirect">here</a>).
|
||||
If a domain interface definition specifies a portgroup (by
|
||||
adding a <code>portgroup</code> attribute to
|
||||
the <code><source></code> subelement), that portgroup's
|
||||
info will be merged into the interface's configuration. If no
|
||||
portgroup is given in the interface definition, and one of the
|
||||
network's portgroups has <code>default='yes'</code>, that
|
||||
default portgroup will be used. If no portgroup is given in the
|
||||
interface definition, and there is no default portgroup, then
|
||||
none will be used. Any <code><bandwidth></code>
|
||||
or <code><virtualport></code> specified directly in the
|
||||
domain XML will take precedence over any setting in the chosen
|
||||
portgroup.
|
||||
</p>
|
||||
|
||||
<h3><a name="elementsAddress">Addressing</a></h3>
|
||||
|
||||
@ -108,14 +334,21 @@
|
||||
The final set of elements define the addresses (IPv4 and/or
|
||||
IPv6, as well as MAC) to be assigned to the bridge device
|
||||
associated with the virtual network, and optionally enable DHCP
|
||||
services.
|
||||
services. These elements are only valid for isolated networks
|
||||
(no <code>forward</code> element specified), and for those with
|
||||
a forward mode of 'route' or 'nat'.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<mac address='00:16:3E:5D:C7:9E'/>
|
||||
<domain name="example.com"/>
|
||||
<dns>
|
||||
<txt name="example" value="example value" />
|
||||
<srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/>
|
||||
<host ip='192.168.122.2'>
|
||||
<hostname>myhost</hostname>
|
||||
<hostname>myhostalias</hostname>
|
||||
</dns>
|
||||
<ip address="192.168.122.1" netmask="255.255.255.0">
|
||||
<dhcp>
|
||||
@ -124,7 +357,7 @@
|
||||
<host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" />
|
||||
</dhcp>
|
||||
</ip>
|
||||
<ip family="ipv6" address="2001:8794:ca2:2::1" prefix="64" />
|
||||
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
|
||||
</network></pre>
|
||||
|
||||
<dl>
|
||||
@ -164,6 +397,17 @@
|
||||
<span class="since">Since 0.9.3</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><code>srv</code></dt>
|
||||
<dd>The <code>dns</code> element can have also 0 or more <code>srv</code>
|
||||
record elements. Each <code>srv</code> record element defines a DNS SRV record
|
||||
and has 2 mandatory and 5 optional attributes. The mandatory attributes
|
||||
are service name and protocol (tcp, udp) and the optional attributes are
|
||||
target, port, priority, weight and domain as defined in DNS server SRV
|
||||
RFC (RFC 2782).
|
||||
<span class="since">Since 0.9.9</span>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>ip</code></dt>
|
||||
<dd>The <code>address</code> attribute defines an IPv4 address in
|
||||
@ -264,7 +508,7 @@
|
||||
<range start="192.168.122.2" end="192.168.122.254" />
|
||||
</dhcp>
|
||||
</ip>
|
||||
<ip family="ipv6" address="2001:8794:ca2:2::1" prefix="64" />
|
||||
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
|
||||
</network></pre>
|
||||
|
||||
<h3><a name="examplesRoute">Routed network config</a></h3>
|
||||
@ -288,7 +532,7 @@
|
||||
<range start="192.168.122.2" end="192.168.122.254" />
|
||||
</dhcp>
|
||||
</ip>
|
||||
<ip family="ipv6" address="2001:8794:ca2:2::1" prefix="64" />
|
||||
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
|
||||
</network></pre>
|
||||
|
||||
<h3><a name="examplesPrivate">Isolated network config</a></h3>
|
||||
@ -310,7 +554,60 @@
|
||||
<range start="192.168.152.2" end="192.168.152.254" />
|
||||
</dhcp>
|
||||
</ip>
|
||||
<ip family="ipv6" address="2001:8794:ca2:3::1" prefix="64" />
|
||||
<ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64" />
|
||||
</network></pre>
|
||||
|
||||
<h3><a name="examplesBridge">Using an existing host bridge</a></h3>
|
||||
|
||||
<p>
|
||||
<span class="since">Since 0.9.4</span>
|
||||
This shows how to use a pre-existing host bridge "br0". The
|
||||
guests will effectively be directly connected to the physical
|
||||
network (i.e. their IP addresses will all be on the subnet of
|
||||
the physical network, and there will be no restrictions on
|
||||
inbound or outbound connections).
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<network>
|
||||
<name>host-bridge</name>
|
||||
<forward mode="bridge"/>
|
||||
<bridge name="br0"/>
|
||||
</network></pre>
|
||||
|
||||
<h3><a name="examplesDirect">Using a macvtap "direct" connection</a></h3>
|
||||
|
||||
<p>
|
||||
<span class="since">Since 0.9.4, QEMU and KVM only, requires
|
||||
Linux kernel 2.6.34 or newer</span>
|
||||
This shows how to use macvtap to connect to the physical network
|
||||
directly through one of a group of physical devices (without
|
||||
using a host bridge device). As with the host bridge network,
|
||||
the guests will effectively be directly connected to the
|
||||
physical network so their IP addresses will all be on the subnet
|
||||
of the physical network, and there will be no restrictions on
|
||||
inbound or outbound connections. Note that, due to a limitation
|
||||
in the implementation of macvtap, these connections do not allow
|
||||
communication directly between the host and the guests - if you
|
||||
require this you will either need the attached physical switch
|
||||
to be operating in a mirroring mode (so that all traffic coming
|
||||
to the switch is reflected back to the host's interface), or
|
||||
provide alternate means for this communication (e.g. a second
|
||||
interface on each guest that is connected to an isolated
|
||||
network). The other forward modes that use macvtap (private,
|
||||
vepa, and passthrough) would be used in a similar fashion.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<network>
|
||||
<name>direct-macvtap</name>
|
||||
<forward mode="bridge">
|
||||
<interface dev="eth20"/>
|
||||
<interface dev="eth21"/>
|
||||
<interface dev="eth22"/>
|
||||
<interface dev="eth23"/>
|
||||
<interface dev="eth24"/>
|
||||
</forward>
|
||||
</network></pre>
|
||||
|
||||
</body>
|
||||
|
@ -1,5 +1,232 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Node devices XML format</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<h2><a name="NodedevAttributes">Node Device XML</a></h2>
|
||||
|
||||
<p>
|
||||
There are several libvirt functions, all with the
|
||||
prefix <code>virNodeDevice</code>, which deal with management of
|
||||
host devices that can be handed to guests via passthrough as
|
||||
<hostdev> elements
|
||||
in <a href="formatdomain.html#elementsUSB">the domain XML</a>.
|
||||
These devices are represented as a hierarchy, where a device on
|
||||
a bus has a parent of the bus controller device; the root of the
|
||||
hierarchy is the node named "computer".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When represented in XML, a node device uses the
|
||||
top-level <code>device</code> element, with the following
|
||||
elements present according to the type of device:
|
||||
</p>
|
||||
<dl>
|
||||
<dt><code>name</code></dt>
|
||||
<dd>The name for this device. The name will be alphanumeric,
|
||||
with words separated by underscore. For many devices, the
|
||||
name is just the bus type and address, as in
|
||||
"pci_0000_00_02_1" or "usb_1_5_3", but some devices are able
|
||||
to provide more specific names, such as
|
||||
"net_eth1_00_27_13_6a_fe_00".
|
||||
</dd>
|
||||
<dt><code>parent</code></dt>
|
||||
<dd>If this element is present, it names the parent device (that
|
||||
is, a controller to which this node belongs).
|
||||
</dd>
|
||||
<dt><code>capability</code></dt>
|
||||
<dd>This node appears for each capability that libvirt
|
||||
associates with a node. A mandatory
|
||||
attribute <code>type</code> lists which category the device
|
||||
belongs to, and controls which further subelements will be
|
||||
present to describe the node:
|
||||
<dl>
|
||||
<dt><code>system</code></dt>
|
||||
<dd>Describes the overall host. Sub-elements include:
|
||||
<dl>
|
||||
<dt><code>product</code></dt>
|
||||
<dd>If present, a simple text string giving the product
|
||||
name of the system.</dd>
|
||||
<dt><code>hardware</code></dt>
|
||||
<dd>Describes the hardware of the system, including
|
||||
sub-elements for <code>vendor</code>, <code>version</code>,
|
||||
<code>serial</code>, and <code>uuid</code>.</dd>
|
||||
<dt><code>firmware</code></dt>
|
||||
<dd>Describes the firmware of the system, including
|
||||
sub-elements for <code>vendor</code>, <code>version</code>,
|
||||
and <code>release_date</code>.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>pci</code></dt>
|
||||
<dd>Describes a device on the host's PCI bus. Sub-elements
|
||||
include:
|
||||
<dl>
|
||||
<dt><code>domain</code></dt>
|
||||
<dd>Which domain the device belongs to.</dd>
|
||||
<dt><code>bus</code></dt>
|
||||
<dd>Which bus within the domain.</dd>
|
||||
<dt><code>slot</code></dt>
|
||||
<dd>Which slot within the bus.</dd>
|
||||
<dt><code>function</code></dt>
|
||||
<dd>Which function within the slot.</dd>
|
||||
<dt><code>product</code></dt>
|
||||
<dd>Product details from the device ROM, including an
|
||||
attribute <code>id</code> with the hexadecimal product
|
||||
id, and an optional text description of that id.</dd>
|
||||
<dt><code>vendor</code></dt>
|
||||
<dd>Vendor details from the device ROM, including an
|
||||
attribute <code>id</code> with the hexadecimal vendor
|
||||
id, and an optional text name of that vendor.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>usb_device</code></dt>
|
||||
<dd>Describes a device on the host's USB bus, based on its
|
||||
location within the bus. Sub-elements include:
|
||||
<dl>
|
||||
<dt><code>bus</code></dt>
|
||||
<dd>Which bus the device belongs to.</dd>
|
||||
<dt><code>device</code></dt>
|
||||
<dd>Which device within the bus.</dd>
|
||||
<dt><code>product</code></dt>
|
||||
<dd>Product details from the device ROM, including an
|
||||
attribute <code>id</code> with the hexadecimal product
|
||||
id, and an optional text description of that id.</dd>
|
||||
<dt><code>vendor</code></dt>
|
||||
<dd>Vendor details from the device ROM, including an
|
||||
attribute <code>id</code> with the hexadecimal vendor
|
||||
id, and an optional text name of that vendor.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>usb</code></dt>
|
||||
<dd>Describes a USB device, based on its advertised driver
|
||||
interface. Sub-elements include:
|
||||
<dl>
|
||||
<dt><code>number</code></dt>
|
||||
<dd>The device number.</dd>
|
||||
<dt><code>number</code></dt>
|
||||
<dd>The device class.</dd>
|
||||
<dt><code>number</code></dt>
|
||||
<dd>The device subclass.</dd>
|
||||
<dt><code>number</code></dt>
|
||||
<dd>The device protocol.</dd>
|
||||
<dt><code>description</code></dt>
|
||||
<dd>If present, a description of the device.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>net</code></dt>
|
||||
<dd>Describes a device capable for use as a network
|
||||
interface. Sub-elements include:
|
||||
<dl>
|
||||
<dt><code>interface</code></dt>
|
||||
<dd>The interface name tied to this device.</dd>
|
||||
<dt><code>address</code></dt>
|
||||
<dd>If present, the MAC address of the device.</dd>
|
||||
<dt><code>capability</code></dt>
|
||||
<dd>A network protocol exposed by the device, where the
|
||||
attribute <code>type</code> can be "80203" for IEEE
|
||||
802.3, or "80211" for various flavors of IEEE 802.11.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>scsi_host</code></dt>
|
||||
<dd>Describes a SCSI host device. Sub-elements include:
|
||||
<dl>
|
||||
<dt><code>host</code></dt>
|
||||
<dd>The SCSI host number.</dd>
|
||||
<dt><code>capability</code></dt>
|
||||
<dd>Current capabilities include "vports_ops" (indicates
|
||||
vport operations are supported) and "fc_host", the later
|
||||
implies following sub-elements: <code>wwnn</code>,
|
||||
<code>wwpn</code>, <code>fabric_wwn</code>.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>scsi</code></dt>
|
||||
<dd>Desribes a SCSI device. Sub-elements include:
|
||||
<dl>
|
||||
<dt><code>host</code></dt>
|
||||
<dd>The SCSI host containing the device.</dd>
|
||||
<dt><code>bus</code></dt>
|
||||
<dd>The bus within the host.</dd>
|
||||
<dt><code>target</code></dt>
|
||||
<dd>The target within the bus.</dd>
|
||||
<dt><code>lun</code></dt>
|
||||
<dd>The lun within the target.</dd>
|
||||
<dt><code>type</code></dt>
|
||||
<dd>The type of SCSI device.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>storage</code></dt>
|
||||
<dd>Describes a device usable for storage. Sub-elements
|
||||
include:
|
||||
<dl>
|
||||
<dt><code>block</code></dt>
|
||||
<dd>A block device file name that accesses the storage
|
||||
present on the device.</dd>
|
||||
<dt><code>bus</code></dt>
|
||||
<dd>If present, the name of the bus the device is found
|
||||
on.</dd>
|
||||
<dt><code>drive_type</code></dt>
|
||||
<dd>The type of the drive, such as "disk" or
|
||||
"cdrom".</dd>
|
||||
<dt><code>model</code></dt>
|
||||
<dd>Any model information available from the
|
||||
device.</dd>
|
||||
<dt><code>vendor</code></dt>
|
||||
<dd>Any vendor information available from the
|
||||
device.</dd>
|
||||
<dt><code>serial</code></dt>
|
||||
<dd>Any serial number information available from the
|
||||
device.</dd>
|
||||
<dt><code>size</code></dt>
|
||||
<dd>For fixed-size storage, the amount of storage
|
||||
available.</dd>
|
||||
<dt><code>capability</code></dt>
|
||||
<dd>If present, an additional capability is listed via
|
||||
the attribute <code>type</code>. Current capabilites
|
||||
include "hotpluggable" and "removable", with the
|
||||
latter implying the following
|
||||
sub-elements: <code>media_available</code> (0 or
|
||||
1), <code>media_size</code>,
|
||||
and <code>media_label</code>.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="nodeExample">Examples</a></h2>
|
||||
|
||||
<p>The following are some example node device XML outputs:</p>
|
||||
<pre>
|
||||
<device>
|
||||
<name>computer</name>
|
||||
<capability type='system'>
|
||||
<product>2241B36</product>
|
||||
<hardware>
|
||||
<vendor>LENOVO</vendor>
|
||||
<version>ThinkPad T500</version>
|
||||
<serial>R89055N</serial>
|
||||
<uuid>c9488981-5049-11cb-9c1c-993d0230b4cd</uuid>
|
||||
</hardware>
|
||||
<firmware>
|
||||
<vendor>LENOVO</vendor>
|
||||
<version>6FET82WW (3.12 )</version>
|
||||
<release_date>11/26/2009</release_date>
|
||||
</firmware>
|
||||
</capability>
|
||||
</device>
|
||||
|
||||
<device>
|
||||
<name>net_eth1_00_27_13_6a_fe_00</name>
|
||||
<parent>pci_0000_00_19_0</parent>
|
||||
<capability type='net'>
|
||||
<interface>eth1</interface>
|
||||
<address>00:27:13:6a:fe:00</address>
|
||||
<capability type='80203'/>
|
||||
</capability>
|
||||
</device></pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -109,40 +109,49 @@
|
||||
<br/><br/>
|
||||
</p>
|
||||
|
||||
<h3><a name="nwfconceptsvars">Usage of variables in filters</a></h3>
|
||||
<h3><a name="nwfconceptschains">Filtering chains</a></h3>
|
||||
<p>
|
||||
|
||||
Two variables names have so far been reserved for usage by the
|
||||
network traffic filtering subsystem: <code>MAC</code> and
|
||||
<code>IP</code>.
|
||||
<br/><br/>
|
||||
<code>MAC</code> is the MAC address of the
|
||||
network interface. A filtering rule that references this variable
|
||||
will automatically be instantiated with the MAC address of the
|
||||
interface. This works without the user having to explicitly provide
|
||||
the MAC parameter. Even though it is possible to specify the MAC
|
||||
parameter similar to the IP parameter above, it is discouraged
|
||||
since libvirt knows what MAC address an interface will be using.
|
||||
<br/><br/>
|
||||
The parameter <code>IP</code> represents the IP address
|
||||
that the operating system inside the virtual machine is expected
|
||||
to use on the given interface. The <code>IP</code> parameter
|
||||
is special in so far as the libvirt daemon will try to determine
|
||||
the IP address (and thus the IP parameter's value) that is being
|
||||
used on an interface if the parameter
|
||||
is not explicitly provided but referenced.
|
||||
For current limitations on IP address detection, consult the
|
||||
<a href="#nwflimits">section on limitations</a> on how to use this
|
||||
feature and what to expect when using it.
|
||||
<br/><br/>
|
||||
The following is the XML description of the network filer
|
||||
<code>no-arp-spoofing</code>. It serves as an example for
|
||||
a network filter XML referencing the <code>MAC</code> and
|
||||
<code>IP</code> parameters. This particular filter is referenced by the
|
||||
<code>clean-traffic</code> filter.
|
||||
Filtering rules are organized in filter chains. These chains can be
|
||||
thought of as having a tree structure with packet
|
||||
filtering rules as entries in individual chains (branches). <br>
|
||||
Packets start their filter evaluation in the <code>root</code> chain
|
||||
and can then continue their evaluation in other chains, return from
|
||||
those chains back into the <code>root</code> chain or be
|
||||
dropped or accepted by a filtering rule in one of the traversed chains.
|
||||
<br/>
|
||||
Libvirt's network filtering system automatically creates individual
|
||||
<code>root</code> chains for every virtual machine's network interface
|
||||
on which the user chooses to activate traffic filtering.
|
||||
The user may write filtering rules that are either directly instantiated
|
||||
in the <code>root</code> chain or may create protocol-specific
|
||||
filtering chains for efficient evaluation of protocol-specific rules.
|
||||
The following chains exist:
|
||||
</p>
|
||||
<ul>
|
||||
<li>root</li>
|
||||
<li>mac <span class="since">(since 0.9.8)</span></li>
|
||||
<li>stp (spanning tree protocol)
|
||||
<span class="since">(since 0.9.8)</span></li>
|
||||
<li>vlan (802.1Q) <span class="since">(since 0.9.8)</span></li>
|
||||
<li>arp, rarp</li>
|
||||
<li>ipv4</li>
|
||||
<li>ipv6</li>
|
||||
</ul>
|
||||
<p>
|
||||
<span class="since">Since 0.9.8</span> multiple chains evaluating the
|
||||
<code>mac</code>, <code>stp</code>, <code>vlan</code>,
|
||||
<code>arp</code>, <code>rarp</code>, <code>ipv4</code>, or
|
||||
<code>ipv6</code> protocol can be created using
|
||||
the protocol name only as a prefix in the chain's name. This for
|
||||
examples allows chains with names <code>arp-xyz</code> or
|
||||
<code>arp-test</code> to be specified and have ARP protocol packets
|
||||
evaluated in those chains.
|
||||
<br/><br/>
|
||||
The following filter shows an example of filtering ARP traffic
|
||||
in the <code>arp</code> chain.
|
||||
</p>
|
||||
<pre>
|
||||
<filter name='no-arp-spoofing' chain='arp'>
|
||||
<filter name='no-arp-spoofing' chain='arp' priority='-500'>
|
||||
<uuid>f88f1932-debf-4aa1-9fbe-f10d3aa4bc95</uuid>
|
||||
<rule action='drop' direction='out' priority='300'>
|
||||
<mac match='no' srcmacaddr='$MAC'/>
|
||||
@ -169,8 +178,93 @@
|
||||
<rule action='drop' direction='inout' priority='1000'/>
|
||||
</filter>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The consequence of putting ARP-specific rules in the <code>arp</code>
|
||||
chain, rather than for example in the <code>root</code> chain, is that
|
||||
packets for any other protocol than ARP do not need to be evaluated by
|
||||
ARP protocol-specific rules. This improves the efficiency
|
||||
of the traffic filtering. However, one must then pay attention to only
|
||||
put filtering rules for the given protocol into the chain since
|
||||
any other rules will not be evaluated, i.e., an IPv4 rule will not
|
||||
be evaluated in the ARP chain since no IPv4 protocol packets will
|
||||
traverse the ARP chain.
|
||||
<br/><br/>
|
||||
</p>
|
||||
<h3><a name="nwfconceptschainpriorities">Filtering chain priorities</a></h3>
|
||||
<p>
|
||||
All chains are connected to the <code>root</code> chain. The order in
|
||||
which those chains are accessed is influenced by the priority of the
|
||||
chain. The following table shows the chains that can be assigned a
|
||||
priority and their default priorities.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th> Chain (prefix) </th>
|
||||
<th> Default priority </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>stp</td><td>-810</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>mac</td><td>-800</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vlan</td><td>-750</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ipv4</td><td>-700</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ipv6</td><td>-600</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>arp</td><td>-500</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rarp</td><td>-400</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
A chain with a lower priority value is accessed before one with a
|
||||
higher value.
|
||||
<br><br>
|
||||
<span class="since">Since 0.9.8</span> the above listed chains
|
||||
can be assigned custom priorities by writing a value in the
|
||||
range [-1000, 1000] into the priority (XML) attribute in the filter
|
||||
node. The above example filter shows the default priority of -500
|
||||
for <code>arp</code> chains.
|
||||
</p>
|
||||
<h3><a name="nwfconceptsvars">Usage of variables in filters</a></h3>
|
||||
<p>
|
||||
|
||||
Two variables names have so far been reserved for usage by the
|
||||
network traffic filtering subsystem: <code>MAC</code> and
|
||||
<code>IP</code>.
|
||||
<br/><br/>
|
||||
<code>MAC</code> is the MAC address of the
|
||||
network interface. A filtering rule that references this variable
|
||||
will automatically be instantiated with the MAC address of the
|
||||
interface. This works without the user having to explicitly provide
|
||||
the MAC parameter. Even though it is possible to specify the MAC
|
||||
parameter similar to the IP parameter above, it is discouraged
|
||||
since libvirt knows what MAC address an interface will be using.
|
||||
<br/><br/>
|
||||
The parameter <code>IP</code> represents the IP address
|
||||
that the operating system inside the virtual machine is expected
|
||||
to use on the given interface. The <code>IP</code> parameter
|
||||
is special in so far as the libvirt daemon will try to determine
|
||||
the IP address (and thus the IP parameter's value) that is being
|
||||
used on an interface if the parameter
|
||||
is not explicitly provided but referenced.
|
||||
For current limitations on IP address detection, consult the
|
||||
<a href="#nwflimits">section on limitations</a> on how to use this
|
||||
feature and what to expect when using it.
|
||||
<br/><br/>
|
||||
The above-shown network filer <code>no-arp-spoofing</code>
|
||||
is an example of
|
||||
a network filter XML referencing the <code>MAC</code> and
|
||||
<code>IP</code> variables.
|
||||
<br/><br/>
|
||||
Note that referenced variables are always prefixed with the
|
||||
$ (dollar) sign. The format of the value of a variable
|
||||
must be of the type expected by the filter attribute in the
|
||||
@ -182,7 +276,38 @@
|
||||
interface from attaching when hotplugging is used. The types
|
||||
that are expected for each XML attribute are shown
|
||||
below.
|
||||
<br/><br/>
|
||||
<span class="since">Since 0.9.8</span> variables can contain lists of
|
||||
elements, e.g., the variable <code>IP</code> can contain multiple IP
|
||||
addresses that are valid on a particular interface. The notation for
|
||||
providing multiple elements for the IP variable is:
|
||||
</p>
|
||||
<pre>
|
||||
...
|
||||
<devices>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:16:3e:5d:c7:9e'/>
|
||||
<filterref filter='clean-traffic'>
|
||||
<parameter name='IP' value='10.0.0.1'/>
|
||||
<parameter name='IP' value='10.0.0.2'/>
|
||||
<parameter name='IP' value='10.0.0.3'/>
|
||||
</filterref>
|
||||
</interface>
|
||||
</devices>
|
||||
...</pre>
|
||||
<p>
|
||||
This then allows filters to enable multiple IP addresses
|
||||
per interface. Therefore, with the list
|
||||
of IP address shown above, the following rule will create 3
|
||||
individual filtering rules, one for each IP address.
|
||||
</p>
|
||||
<pre>
|
||||
...
|
||||
<rule action='accept' direction='in' priority='500'>
|
||||
<tcp srpipaddr='$IP'/>
|
||||
</rule>
|
||||
...
|
||||
</pre>
|
||||
|
||||
<h2><a name="nwfelems">Element and attribute overview</a></h2>
|
||||
|
||||
@ -258,11 +383,19 @@
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
action -- mandatory; must either be <code>drop</code>,
|
||||
<code>reject</code><span class="since">(since 0.9.0)</span>,
|
||||
or <code>accept</code> if
|
||||
the evaluation of the filtering rule is supposed to drop,
|
||||
reject (using ICMP message), or accept a packet
|
||||
action -- mandatory; must either be <code>drop</code>
|
||||
(matching the rule silently discards the packet with no
|
||||
further analysis),
|
||||
<code>reject</code> (matching the rule generates an ICMP
|
||||
reject message with no further analysis) <span class="since">(since
|
||||
0.9.0)</span>, <code>accept</code> (matching the rule accepts
|
||||
the packet with no further analysis), <code>return</code>
|
||||
(matching the rule passes this filter, but returns control to
|
||||
the calling filter for further
|
||||
analysis) <span class="since">(since 0.9.7)</span>,
|
||||
or <code>continue<code> (matching the rule goes on to the next
|
||||
rule for further analysis) <span class="since">(since
|
||||
0.9.7)</span>.
|
||||
</li>
|
||||
<li>
|
||||
direction -- mandatory; must either be <code>in</code>, <code>out</code> or
|
||||
@ -272,10 +405,21 @@
|
||||
<li>
|
||||
priority -- optional; the priority of the rule controls the order in
|
||||
which the rule will be instantiated relative to other rules.
|
||||
Rules with lower value will be instantiated and therefore evaluated
|
||||
before rules with higher value.
|
||||
Valid values are in the range of 0 to 1000. If this attribute is not
|
||||
provided, the value 500 will automatically be assigned.
|
||||
Rules with lower value will be instantiated before rules with higher
|
||||
values.
|
||||
Valid values are in the range of 0 to 1000.
|
||||
<span class="since">Since 0.9.8</span> this has been extended to cover
|
||||
the range of -1000 to 1000. If this attribute is not
|
||||
provided, priority 500 will automatically be assigned.
|
||||
<br>
|
||||
Note that filtering rules in the <code>root</code> chain are sorted
|
||||
with filters connected to the <code>root</code> chain following
|
||||
their priorities. This allows to interleave filtering rules with
|
||||
access to filter chains.
|
||||
(See also section on
|
||||
<a href="#nwfconceptschainpriorities">
|
||||
filtering chain priorities
|
||||
</a>.)
|
||||
</li>
|
||||
<li>
|
||||
statematch -- optional; possible values are '0' or 'false' to
|
||||
@ -404,6 +548,203 @@
|
||||
[...]
|
||||
</pre>
|
||||
|
||||
<h5><a name="nwfelemsRulesProtoVLAN">VLAN (802.1Q)</a>
|
||||
<span class="since">(Since 0.9.8)</span>
|
||||
</h5>
|
||||
<p>
|
||||
Protocol ID: <code>vlan</code>
|
||||
<br/>
|
||||
Note: Rules of this type should go either into the <code>root</code> or
|
||||
<code>vlan</code> chain.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th> Attribute </th>
|
||||
<th> Datatype </th>
|
||||
<th> Semantics </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>srcmacaddr</td>
|
||||
<td>MAC_ADDR</td>
|
||||
<td>MAC address of sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>srcmacmask</td>
|
||||
<td>MAC_MASK</td>
|
||||
<td>Mask applied to MAC address of sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>dstmacaddr</td>
|
||||
<td>MAC_ADDR</td>
|
||||
<td>MAC address of destination</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>dstmacmask</td>
|
||||
<td>MAC_MASK</td>
|
||||
<td>Mask applied to MAC address of destination</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vlan-id</td>
|
||||
<td>UINT16 (0x0-0xfff, 0 - 4095)</td>
|
||||
<td>VLAN ID</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>encap-protocol</td>
|
||||
<td>UINT16 (0x03c-0xfff), String</td>
|
||||
<td>Encapsulated layer 3 protocol ID</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>comment </td>
|
||||
<td>STRING</td>
|
||||
<td>text with max. 256 characters</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Valid Strings for <code>encap-protocol</code> are: arp, ipv4, ipv6
|
||||
</p>
|
||||
|
||||
<h5><a name="nwfelemsRulesProtoSTP">STP (Spanning Tree Protocol)</a>
|
||||
<span class="since">(Since 0.9.8)</span>
|
||||
</h5>
|
||||
<p>
|
||||
Protocol ID: <code>stp</code>
|
||||
<br/>
|
||||
Note: Rules of this type should go either into the <code>root</code> or
|
||||
<code>stp</code> chain.
|
||||
</p>
|
||||
<table class="top_table">
|
||||
<tr>
|
||||
<th> Attribute </th>
|
||||
<th> Datatype </th>
|
||||
<th> Semantics </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>srcmacaddr</td>
|
||||
<td>MAC_ADDR</td>
|
||||
<td>MAC address of sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>srcmacmask</td>
|
||||
<td>MAC_MASK</td>
|
||||
<td>Mask applied to MAC address of sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>type</td>
|
||||
<td>UINT8</td>
|
||||
<td>Bridge Protcol Data Unit (BPDU) type</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>flags</td>
|
||||
<td>UINT8</td>
|
||||
<td>BPDU flag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root-priority</td>
|
||||
<td>UINT16</td>
|
||||
<td>Root priority (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root-priority-hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Root priority range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root-address</td>
|
||||
<td>MAC_ADDRESS</td>
|
||||
<td>Root MAC address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root-address-mask</td>
|
||||
<td>MAC_MASK</td>
|
||||
<td>Root MAC address mask</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root-cost</td>
|
||||
<td>UINT32</td>
|
||||
<td>Root path cost (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>root-cost-hi</td>
|
||||
<td>UINT32</td>
|
||||
<td>Root path cost range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sender-priority</td>
|
||||
<td>UINT16</td>
|
||||
<td>Sender priority (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sender-priority-hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Sender priority range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sender-address</td>
|
||||
<td>MAC_ADDRESS</td>
|
||||
<td>BPDU sender MAC address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sender-address-mask</td>
|
||||
<td>MAC_MASK</td>
|
||||
<td>BPDU sender MAC address mask</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>port</td>
|
||||
<td>UINT16</td>
|
||||
<td>Port identifier (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>port_hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Port identifier range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>msg-age</td>
|
||||
<td>UINT16</td>
|
||||
<td>Message age timer (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>msg-age-hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Message age timer range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max-age</td>
|
||||
<td>UINT16</td>
|
||||
<td>Maximum age timer (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max-age-hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Maximum age timer range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>hello-time</td>
|
||||
<td>UINT16</td>
|
||||
<td>Hello time timer (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>hello-time-hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Hello time timer range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>forward-delay</td>
|
||||
<td>UINT16</td>
|
||||
<td>Forward delay (range start)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>forward-delay-hi</td>
|
||||
<td>UINT16</td>
|
||||
<td>Forward delay range end</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>comment</td>
|
||||
<td>STRING</td>
|
||||
<td>text with max. 256 characters</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h5><a name="nwfelemsRulesProtoARP">ARP/RARP</a></h5>
|
||||
<p>
|
||||
Protocol ID: <code>arp</code> or <code>rarp</code>
|
||||
@ -493,6 +834,7 @@
|
||||
<h5><a name="nwfelemsRulesProtoIP">IPv4</a></h5>
|
||||
<p>
|
||||
Protocol ID: <code>ip</code>
|
||||
<br/>
|
||||
Note: Rules of this type should either go into the
|
||||
<code>root</code> or <code>ipv4</code> chain.
|
||||
</p>
|
||||
@ -583,6 +925,7 @@
|
||||
<h5><a name="nwfelemsRulesProtoIPv6">IPv6</a></h5>
|
||||
<p>
|
||||
Protocol ID: <code>ipv6</code>
|
||||
<br/>
|
||||
Note: Rules of this type should either go into the
|
||||
<code>root</code> or <code>ipv6</code> chain.
|
||||
</p>
|
||||
@ -1423,8 +1766,10 @@
|
||||
</p>
|
||||
<ul>
|
||||
<li>mac</li>
|
||||
<li>stp (spanning tree protocol)</li>
|
||||
<li>vlan (802.1Q)</li>
|
||||
<li>arp, rarp</li>
|
||||
<li>ip</li>
|
||||
<li>ipv4</li>
|
||||
<li>ipv6</li>
|
||||
</ul>
|
||||
|
||||
@ -1436,13 +1781,14 @@
|
||||
filter subsystem first passes through the filtering support implemented
|
||||
by ebtables and only then through iptables or ip6tables filters. If
|
||||
a filter tree has rules with the protocols <code>mac</code>,
|
||||
<code>arp</code>, <code>rarp</code>, <code>ip</code>, or <code>ipv6</code>
|
||||
ebtables rules will automatically be instantiated.
|
||||
<code>stp</code>, <code>vlan</code>
|
||||
<code>arp</code>, <code>rarp</code>, <code>ipv4</code>,
|
||||
or <code>ipv6</code> ebtables rules will automatically be instantiated.
|
||||
<br/>
|
||||
The role of the <code>chain</code> attribute in the network filter
|
||||
XML is that internally a new user-defined ebtables table is created
|
||||
that then for example receives all <code>arp</code> traffic coming
|
||||
from or going to a virtual machine, if the chain <code>arp</code>
|
||||
from or going to a virtual machine if the chain <code>arp</code>
|
||||
has been specified. Further, a rule is generated in an interface's
|
||||
<code>root</code> chain that directs all ipv4 traffic into the
|
||||
user-defined chain. Therefore, all ARP traffic rules should then be
|
||||
@ -1450,6 +1796,12 @@
|
||||
into user-defined tables is only supported with filtering on the ebtables
|
||||
layer.
|
||||
<br/>
|
||||
<span class="since">Since 0.9.8</span> multiple chains for the same
|
||||
protocol can be created. For this the name of the chain must have
|
||||
a prefix of one of the previously enumerated protocols. To create an
|
||||
additional chain for handling of ARP traffic, a chain with name
|
||||
<code>arp-test</code> can be specified.
|
||||
<br/>
|
||||
As an example, it is
|
||||
possible to filter on UDP traffic by source and destination ports using
|
||||
the <code>ip</code> protocol filter and specifying attributes for the
|
||||
@ -1795,6 +2147,13 @@
|
||||
0.8.1 or later in order not to lose the network traffic filters
|
||||
associated with an interface.
|
||||
</p>
|
||||
|
||||
<h3><a name="nwflimitsvlan">VLAN filtering on Linux</a></h3>
|
||||
<p>
|
||||
VLAN (802.1Q) packets, if sent by a virtual machine, cannot be filtered
|
||||
with rules for protocol IDs <code>arp</code>, <code>rarp</code>,
|
||||
<code>ipv4</code> and <code>ipv6</code> but only
|
||||
with protocol IDs <code>mac</code> and <code>vlan</code>. Therefore,
|
||||
the example filter <code>clean-traffic</code> will not work as expected.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -39,8 +39,8 @@
|
||||
<dd>
|
||||
Specifies what this secret is used for. A mandatory
|
||||
<code>type</code> attribute specifies the usage category, currently
|
||||
only <code>volume</code> is defined. Specific usage categories are
|
||||
described below.
|
||||
only <code>volume</code> and <code>ceph</code> are defined.
|
||||
Specific usage categories are described below.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
@ -54,6 +54,18 @@
|
||||
this secret is associated with.
|
||||
</p>
|
||||
|
||||
<h3>Usage type "ceph"</h3>
|
||||
|
||||
<p>
|
||||
This secret is associated with a Ceph RBD (rados block device).
|
||||
The <code><usage type='ceph'></code> element must contain
|
||||
a single <code>name</code> element that specifies a usage name
|
||||
for the secret. The Ceph secret can then be used by UUID or by
|
||||
this usage name via the <code><auth></code> element of
|
||||
a <a href="domain.html#elementsDisks">disk
|
||||
device</a>. <span class="since">Since 0.9.7</span>.
|
||||
</p>
|
||||
|
||||
<h2><a name="example">Example</a></h2>
|
||||
|
||||
<pre>
|
||||
|
@ -6,13 +6,88 @@
|
||||
|
||||
<h2><a name="SnapshotAttributes">Snapshot XML</a></h2>
|
||||
|
||||
<p>
|
||||
There are several types of snapshots:
|
||||
</p>
|
||||
<dl>
|
||||
<dt>disk snapshot</dt>
|
||||
<dd>Contents of disks (whether a subset or all disks associated
|
||||
with the domain) are saved at a given point of time, and can
|
||||
be restored back to that state. On a running guest, a disk
|
||||
snapshot is likely to be only crash-consistent rather than
|
||||
clean (that is, it represents the state of the disk on a
|
||||
sudden power outage, and may need fsck or journal replays to
|
||||
be made consistent); on an inactive guest, a disk snapshot is
|
||||
clean if the disks were clean when the guest was last shut
|
||||
down. Disk snapshots exist in two forms: internal (file
|
||||
formats such as qcow2 track both the snapshot and changes
|
||||
since the snapshot in a single file) and external (the
|
||||
snapshot is one file, and the changes since the snapshot are
|
||||
in another file).</dd>
|
||||
<dt>VM state</dt>
|
||||
<dd>Tracks only the state of RAM and all other resources in use
|
||||
by the VM. If the disks are unmodified between the time a VM
|
||||
state snapshot is taken and restored, then the guest will
|
||||
resume in a consistent state; but if the disks are modified
|
||||
externally in the meantime, this is likely to lead to data
|
||||
corruption.</dd>
|
||||
<dt>system checkpoint</dt>
|
||||
<dd>A combination of disk snapshots for all disks as well as VM
|
||||
state, which can be used to resume the guest from where it
|
||||
left off with symptoms similar to hibernation (that is, TCP
|
||||
connections in the guest may have timed out, but no files or
|
||||
processes are lost).</dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
Libvirt can manage all three types of snapshots. For now, VM
|
||||
state snapshots are created only by
|
||||
the <code>virDomainSave()</code>, <code>virDomainSaveFlags</code>,
|
||||
and <code>virDomainManagedSave()</code> functions, and restored
|
||||
via the <code>virDomainRestore()</code>,
|
||||
<code>virDomainRestoreFlags()</code>, <code>virDomainCreate()</code>,
|
||||
and <code>virDomainCreateWithFlags()</code> functions (as well
|
||||
as via domain autostart). With managed snapshots, libvirt
|
||||
tracks all information internally; with save images, the user
|
||||
tracks the snapshot file, but libvirt provides functions such
|
||||
as <code>virDomainSaveImageGetXMLDesc()</code> to work with
|
||||
those files.
|
||||
</p>
|
||||
<p>System checkpoints are created
|
||||
by <code>virDomainSnapshotCreateXML()</code> with no flags, and
|
||||
disk snapshots are created by the same function with
|
||||
the <code>VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY</code> flag; in
|
||||
both cases, they are restored by
|
||||
the <code>virDomainRevertToSnapshot()</code> function. For
|
||||
these types of snapshots, libvirt tracks each snapshot as a
|
||||
separate <code>virDomainSnapshotPtr</code> object, and maintains
|
||||
a tree relationship of which snapshots descended from an earlier
|
||||
point in time.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Attributes of libvirt snapshots are stored as child elements of
|
||||
the <code>domainsnapshot</code> element. At snapshot creation
|
||||
time, only the <code>name</code> and <code>description</code>
|
||||
elements are settable; the rest of the fields are informational
|
||||
(and readonly) and will be filled in by libvirt when the
|
||||
snapshot is created.
|
||||
time, normally only the <code>name</code>, <code>description</code>,
|
||||
and <code>disks</code> elements are settable; the rest of the
|
||||
fields are ignored on creation, and will be filled in by
|
||||
libvirt in for informational purposes
|
||||
by <code>virDomainSnapshotGetXMLDesc()</code>. However, when
|
||||
redefining a snapshot (<span class="since">since 0.9.5</span>),
|
||||
with the <code>VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE</code> flag
|
||||
of <code>virDomainSnapshotCreateXML()</code>, all of the XML
|
||||
described here is relevant.
|
||||
</p>
|
||||
<p>
|
||||
Snapshots are maintained in a hierarchy. A domain can have a
|
||||
current snapshot, which is the most recent snapshot compared to
|
||||
the current state of the domain (although a domain might have
|
||||
snapshots without a current snapshot, if snapshots have been
|
||||
deleted in the meantime). Creating or reverting to a snapshot
|
||||
sets that snapshot as current, and the prior current snapshot is
|
||||
the parent of the new snapshot. Branches in the hierarchy can
|
||||
be formed by reverting to a snapshot with a child, then creating
|
||||
another snapshot.
|
||||
</p>
|
||||
<p>
|
||||
The top-level <code>domainsnapshot</code> element may contain
|
||||
@ -21,52 +96,187 @@
|
||||
<dl>
|
||||
<dt><code>name</code></dt>
|
||||
<dd>The name for this snapshot. If the name is specified when
|
||||
initially creating the snapshot, then the snapshot will have
|
||||
that particular name. If the name is omitted when initially
|
||||
creating the snapshot, then libvirt will make up a name for the snapshot.
|
||||
initially creating the snapshot, then the snapshot will have
|
||||
that particular name. If the name is omitted when initially
|
||||
creating the snapshot, then libvirt will make up a name for
|
||||
the snapshot, based on the time when it was created.
|
||||
</dd>
|
||||
<dt><code>description</code></dt>
|
||||
<dd>A human-readable description of the snapshot. If the
|
||||
description is omitted when initially creating the snapshot,
|
||||
then this field will be empty.
|
||||
</dd>
|
||||
<dt><code>disks</code></dt>
|
||||
<dd>On input, this is an optional listing of specific
|
||||
instructions for disk snapshots; it is needed when making a
|
||||
snapshot of only a subset of the disks associated with a
|
||||
domain, or when overriding the domain defaults for how to
|
||||
snapshot each disk, or for providing specific control over
|
||||
what file name is created in an external snapshot. On output,
|
||||
this is fully populated to show the state of each disk in the
|
||||
snapshot, including any properties that were generated by the
|
||||
hypervisor defaults. For system checkpoints, this field is
|
||||
ignored on input and omitted on output (a system checkpoint
|
||||
implies that all disks participate in the snapshot process,
|
||||
and since the current implementation only does internal system
|
||||
checkpoints, there are no extra details to add); a future
|
||||
release may allow the use of <code>disks</code> with a system
|
||||
checkpoint. This element has a list of <code>disk</code>
|
||||
sub-elements, describing anywhere from zero to all of the
|
||||
disks associated with the domain. <span class="since">Since
|
||||
0.9.5</span>
|
||||
<dl>
|
||||
<dt><code>disk</code></dt>
|
||||
<dd>This sub-element describes the snapshot properties of a
|
||||
specific disk. The attribute <code>name</code> is
|
||||
mandatory, and must match either the <code><target
|
||||
dev='name'/></code> or an unambiguous <code><source
|
||||
file='name'/></code> of one of
|
||||
the <a href="formatdomain.html#elementsDisks">disk
|
||||
devices</a> specified for the domain at the time of the
|
||||
snapshot. The attribute <code>snapshot</code> is
|
||||
optional, and has the same values of the disk device
|
||||
element for a domain
|
||||
(<code>no</code>, <code>internal</code>,
|
||||
or <code>external</code>). Some hypervisors like ESX
|
||||
require that if specified, the snapshot mode must not
|
||||
override any snapshot mode attached to the corresponding
|
||||
domain disk, while others like qemu allow this field to
|
||||
override the domain default. If the snapshot mode is
|
||||
external (whether specified or inherited), then there is
|
||||
an optional sub-element <code>source</code>, with an
|
||||
attribute <code>file</code> giving the name, and an
|
||||
optional sub-element <code>driver</code>, with an
|
||||
attribute <code>type</code> giving the driver type (such
|
||||
as qcow2), of the new file created by the external
|
||||
snapshot of the new file. If <code>source</code> is not
|
||||
given, a file name is generated that consists of the
|
||||
existing file name with anything after the trailing dot
|
||||
replaced by the snapshot name. Remember that with external
|
||||
snapshots, the original file name becomes the read-only
|
||||
snapshot, and the new file name contains the read-write
|
||||
delta of all disk changes since the snapshot.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>creationTime</code></dt>
|
||||
<dd>The time this snapshot was created. The time is specified
|
||||
in seconds since the Epoch, UTC (i.e. Unix time). Readonly.
|
||||
in seconds since the Epoch, UTC (i.e. Unix time). Readonly.
|
||||
</dd>
|
||||
<dt><code>state</code></dt>
|
||||
<dd>The state of the domain at the time this snapshot was
|
||||
taken. When the domain is reverted to this snapshot, the domain's state
|
||||
will be set to whatever is in this field. Readonly.
|
||||
<dd>The state of the domain at the time this snapshot was taken.
|
||||
If the snapshot was created as a system checkpoint, then this
|
||||
is the state of the domain at that time; when the domain is
|
||||
reverted to this snapshot, the domain's state will default to
|
||||
whatever is in this field unless additional flags are passed
|
||||
to <code>virDomainRevertToSnapshot()</code>. Additionally,
|
||||
this field can be the value "disk-snapshot"
|
||||
(<span class="since">since 0.9.5</span>) when it represents
|
||||
only a disk snapshot (no VM state), and reverting to this
|
||||
snapshot will default to an inactive guest. Readonly.
|
||||
</dd>
|
||||
<dt><code>parent</code></dt>
|
||||
<dd>The parent of this snapshot. This element contains exactly
|
||||
one child element, name. This specifies the name of the parent
|
||||
snapshot of this snapshot, and is used to represent trees of
|
||||
snapshots. Readonly.
|
||||
<dd>The parent of this snapshot. If present, this element
|
||||
contains exactly one child element, name. This specifies the
|
||||
name of the parent snapshot of this snapshot, and is used to
|
||||
represent trees of snapshots. Readonly.
|
||||
</dd>
|
||||
<dt><code>domain</code></dt>
|
||||
<dd>The domain that this snapshot was taken against. This
|
||||
element contains exactly one child element, uuid. This
|
||||
specifies the uuid of the domain that this snapshot was taken
|
||||
against. Readonly.
|
||||
<dd>The domain that this snapshot was taken against. Older
|
||||
versions of libvirt stored only a single child element, uuid;
|
||||
reverting to a snapshot like this is risky if the current
|
||||
state of the domain differs from the state that the domain was
|
||||
created in, and requires the use of the
|
||||
<code>VIR_DOMAIN_SNAPSHOT_REVERT_FORCE</code> flag
|
||||
in <code>virDomainRevertToSnapshot()</code>. Newer versions
|
||||
of libvirt (<span class="since">since 0.9.5</span>) store the entire
|
||||
inactive <a href="formatdomain.html">domain configuration</a>
|
||||
at the time of the snapshot (<span class="since">since
|
||||
0.9.5</span>). Readonly.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="example">Example</a></h2>
|
||||
<h2><a name="example">Examples</a></h2>
|
||||
|
||||
<p>Using this XML to create a disk snapshot of just vda on a qemu
|
||||
domain with two disks:</p>
|
||||
<pre>
|
||||
<domainsnapshot>
|
||||
<name>os-updates</name>
|
||||
<description>Snapshot of OS install and updates</description>
|
||||
<state>running</state>
|
||||
<creationTime>1270477159</creationTime>
|
||||
<parent>
|
||||
<name>bare-os-install</name>
|
||||
</parent>
|
||||
<domain>
|
||||
<uuid>93a5c045-6457-2c09-e56c-927cdf34e178</uuid>
|
||||
</domain>
|
||||
</domainsnapshot></pre>
|
||||
<domainsnapshot>
|
||||
<description>Snapshot of OS install and updates</description>
|
||||
<disks>
|
||||
<disk name='/path/to/old'>
|
||||
<source file='/path/to/new'/>
|
||||
</disk>
|
||||
<disk name='vdb' snapshot='no'/>
|
||||
</disks>
|
||||
</domainsnapshot></pre>
|
||||
|
||||
<p>will result in XML similar to this from
|
||||
<code>virDomainSnapshotGetXMLDesc()</code>:</p>
|
||||
<pre>
|
||||
<domainsnapshot>
|
||||
<name>1270477159</name>
|
||||
<description>Snapshot of OS install and updates</description>
|
||||
<state>running</state>
|
||||
<creationTime>1270477159</creationTime>
|
||||
<parent>
|
||||
<name>bare-os-install</name>
|
||||
</parent>
|
||||
<disks>
|
||||
<disk name='vda' snapshot='external'>
|
||||
<driver type='qcow2'/>
|
||||
<b><source file='/path/to/new'/></b>
|
||||
</disk>
|
||||
<disk name='vdb' snapshot='no'/>
|
||||
</disks>
|
||||
<domain>
|
||||
<name>fedora</name>
|
||||
<uuid>93a5c045-6457-2c09-e56c-927cdf34e178</uuid>
|
||||
<memory>1048576</memory>
|
||||
...
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<b><source file='/path/to/old'/></b>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk' snapshot='external'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/path/to/old2'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
...
|
||||
</devices>
|
||||
</domain>
|
||||
</domainsnapshot></pre>
|
||||
|
||||
<p>With that snapshot created, <code>/path/to/old</code> is the
|
||||
read-only backing file to the new active
|
||||
file <code>/path/to/new</code>. The <code><domain></code>
|
||||
element within the snapshot xml records the state of the domain
|
||||
just before the snapshot; a call
|
||||
to <code>virDomainGetXMLDesc()</code> will show that the domain
|
||||
has been changed to reflect the snapshot:
|
||||
</p>
|
||||
<pre>
|
||||
<domain>
|
||||
<name>fedora</name>
|
||||
<uuid>93a5c045-6457-2c09-e56c-927cdf34e178</uuid>
|
||||
<memory>1048576</memory>
|
||||
...
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<b><source file='/path/to/new'/></b>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk' snapshot='external'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/path/to/old2'/>
|
||||
<target dev='vdb' bus='virtio'/>
|
||||
</disk>
|
||||
...
|
||||
</devices>
|
||||
</domain></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -13,7 +13,7 @@
|
||||
volumes. Some may have constraints on volume size, or placement.
|
||||
</p>
|
||||
<p>
|
||||
The is the top level tag for a storage pool document is 'pool'. It has
|
||||
The top level tag for a storage pool document is 'pool'. It has
|
||||
a single attribute <code>type</code>, which is one of <code>dir</code>,
|
||||
<code>fs</code>,<code>netfs</code>,<code>disk</code>,<code>iscsi</code>,
|
||||
<code>logical</code>. This corresponds to the storage backend drivers
|
||||
|
@ -506,7 +506,7 @@
|
||||
Usage of the <code>fdopen()</code>, <code>close()</code>, <code>fclose()</code>
|
||||
APIs is deprecated in libvirt code base to help avoiding double-closing of files
|
||||
or file descriptors, which is particulary dangerous in a multi-threaded
|
||||
applications. Instead of these APIs, use the macros from files.h
|
||||
applications. Instead of these APIs, use the macros from virfile.h
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
@ -585,6 +585,12 @@
|
||||
<li><p>For strict equality of a prefix:</p>
|
||||
<pre>
|
||||
STRPREFIX(a,b)
|
||||
</pre>
|
||||
</li>
|
||||
<li><p>To avoid having to check if a or b are NULL:</p>
|
||||
<pre>
|
||||
STREQ_NULLABLE(a, b)
|
||||
STRNEQ_NULLABLE(a, b)
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -35,32 +35,35 @@
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html">Xen</a> hypervisor
|
||||
The <a href="http://libvirt.org/drvqemu.html">KVM/QEMU</a> Linux hypervisor
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://libvirt.org/drvxen.html">Xen</a> hypervisor
|
||||
on Linux and Solaris hosts.
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://wiki.qemu.org/Index.html">QEMU</a> emulator
|
||||
The <a href="http://libvirt.org/drvlxc.html">LXC</a> Linux container system
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://www.linux-kvm.org/">KVM</a> Linux hypervisor
|
||||
The <a href="http://libvirt.org/drvopenvz.html">OpenVZ</a> Linux container system
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://lxc.sourceforge.net/">LXC</a> Linux container system
|
||||
The <a href="http://libvirt.org/drvuml.html">User Mode Linux</a> paravirtualized kernel
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://openvz.org/">OpenVZ</a> Linux container system
|
||||
The <a href="http://libvirt.org/drvvbox.html">VirtualBox</a> hypervisor
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://user-mode-linux.sourceforge.net/">User Mode Linux</a> paravirtualized kernel
|
||||
The <a href="http://libvirt.org/drvesx.html">VMware ESX and GSX</a> hypervisors
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://www.virtualbox.org/">VirtualBox</a> hypervisor
|
||||
The <a href="http://libvirt.org/drvvmware.html">VMware Workstation and Player</a> hypervisors
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://www.vmware.com/">VMware ESX and GSX</a> hypervisors
|
||||
The <a href="http://libvirt.org/drvhyperv.html">Microsoft Hyper-V</a> hypervisor
|
||||
</li>
|
||||
<li>
|
||||
The <a href="http://www.vmware.com/">VMware Workstation and Player</a> hypervisors
|
||||
Virtual networks using bridging, NAT, VEPA and VN-LINK.
|
||||
</li>
|
||||
<li>
|
||||
Storage on IDE/SCSI/USB disks, FibreChannel, LVM, iSCSI, NFS and filesystems
|
||||
|
@ -445,7 +445,7 @@
|
||||
<strong>Note:</strong> if the command has been daemonized
|
||||
this will only block & wait for the intermediate process,
|
||||
not the real command. <code>virCommandRun</code> will
|
||||
report on any errors that have occured upon this point
|
||||
report on any errors that have occurred upon this point
|
||||
with all previous API calls. If the command fails to
|
||||
run, or exits with non-zero status an error will be
|
||||
reported via normal libvirt error infrastructure. If a
|
||||
@ -497,6 +497,23 @@
|
||||
error if not.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are two approaches to child process cleanup, determined by
|
||||
how long you want to keep the virCommand object in scope.
|
||||
</p>
|
||||
|
||||
<p>1. If the virCommand object will outlast the child process,
|
||||
then pass NULL for the pid argument, and the child process will
|
||||
automatically be reaped at virCommandFree, unless you reap it
|
||||
sooner via virCommandWait or virCommandAbort.
|
||||
</p>
|
||||
|
||||
<p>2. If the child process must exist on at least one code path
|
||||
after virCommandFree, then pass a pointer for the pid argument.
|
||||
Later, to clean up the child, call virPidWait or virPidAbort.
|
||||
Before virCommandFree, you can still use virCommandWait or
|
||||
virCommandAbort to reap the process.
|
||||
</p>
|
||||
|
||||
<h3><a name="release">Releasing resources</a></h3>
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
<p>
|
||||
The high level goal is to prevent the same disk image being
|
||||
used by more than one QEMU instance at a time (unless the
|
||||
disk is marked as sharable, or readonly). The scenarios
|
||||
disk is marked as shareable, or readonly). The scenarios
|
||||
to be prevented are thus:
|
||||
</p>
|
||||
|
||||
|
910
docs/internals/rpc.html.in
Normal file
910
docs/internals/rpc.html.in
Normal file
@ -0,0 +1,910 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>libvirt RPC infrastructure</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
libvirt includes a basic protocol and code to implement
|
||||
an extensible, secure client/server RPC service. This was
|
||||
originally designed for communication between the libvirt
|
||||
client library and the libvirtd daemon, but the code is
|
||||
now isolated to allow reuse in other areas of libvirt code.
|
||||
This document provides an overview of the protocol and
|
||||
structure / operation of the internal RPC library APIs.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="protocol">RPC protocol</a></h2>
|
||||
|
||||
<p>
|
||||
libvirt uses a simple, variable length, packet based RPC protocol.
|
||||
All structured data within packets is encoded using the
|
||||
<a href="http://en.wikipedia.org/wiki/External_Data_Representation">XDR standard</a>
|
||||
as currently defined by <a href="https://tools.ietf.org/html/rfc4506">RFC 4506</a>.
|
||||
On any connection running the RPC protocol, there can be multiple
|
||||
programs active, each supporting one or more versions. A program
|
||||
defines a set of procedures that it supports. The procedures can
|
||||
support call+reply method invocation, asynchronous events,
|
||||
and generic data streams. Method invocations can be overlapped,
|
||||
so waiting for a reply to one will not block the receipt of the
|
||||
reply to another outstanding method. The protocol was loosely
|
||||
inspired by the design of SunRPC. The definition of the RPC
|
||||
protocol is in the file <code>src/rpc/virnetprotocol.x</code>
|
||||
in the libvirt source tree.
|
||||
</p>
|
||||
|
||||
<h3><a href="protocolframing">Packet framing</a></h3>
|
||||
|
||||
<p>
|
||||
On the wire, there is no explicit packet framing marker. Instead
|
||||
each packet is preceded by an unsigned 32-bit integer giving
|
||||
the total length of the packet in bytes. This length includes
|
||||
the 4-bytes of the length word itself. Conceptually the framing
|
||||
looks like this:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|~~~ Packet 1 ~~~|~~~ Packet 2 ~~~|~~~ Packet 3 ~~~|~~~
|
||||
|
||||
+-------+------------+-------+------------+-------+------------+...
|
||||
| n=U32 | (n-4) * U8 | n=U32 | (n-4) * U8 | n=U32 | (n-4) * U8 |
|
||||
+-------+------------+-------+------------+-------+------------+...
|
||||
|
||||
|~ Len ~|~ Data ~|~ Len ~|~ Data ~|~ Len ~|~ Data ~|~
|
||||
|
||||
</pre>
|
||||
|
||||
<h3><a href="protocoldata">Packet data</a></h3>
|
||||
|
||||
<p>
|
||||
The data in each packet is split into two parts, a short
|
||||
fixed length header, followed by a variable length payload.
|
||||
So a packet from the illustration above is more correctly
|
||||
shown as
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|
||||
+-------+-------------+---------------....---+
|
||||
| n=U32 | 6*U32 | (n-(7*4))*U8 |
|
||||
+-------+-------------+---------------....---+
|
||||
|
||||
|~ Len ~|~ Header ~|~ Payload .... ~|
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a href="protocolheader">Packet header</a></h3>
|
||||
<p>
|
||||
The header contains 6 fields, encoded as signed/unsigned 32-bit
|
||||
integers.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
+---------------+
|
||||
| program=U32 |
|
||||
+---------------+
|
||||
| version=U32 |
|
||||
+---------------+
|
||||
| procedure=S32 |
|
||||
+---------------+
|
||||
| type=S32 |
|
||||
+---------------+
|
||||
| serial=U32 |
|
||||
+---------------+
|
||||
| status=S32 |
|
||||
+---------------+
|
||||
</pre>
|
||||
|
||||
<dl>
|
||||
<dt><code>program</code></dt>
|
||||
<dd>
|
||||
This is an arbitrarily chosen number that will uniquely
|
||||
identify the "service" running over the stream.
|
||||
</dd>
|
||||
<dt><code>version</code></dt>
|
||||
<dd>
|
||||
This is the version number of the program, by convention
|
||||
starting from '1'. When an incompatible change is made
|
||||
to a program, the version number is incremented. Ideally
|
||||
both versions will then be supported on the wire in
|
||||
parallel for backwards compatibility.
|
||||
</dd>
|
||||
<dt><code>procedure</code></dt>
|
||||
<dd>
|
||||
This is an arbitrarily chosen number that will uniquely
|
||||
identify the method call, or event associated with the
|
||||
packet. By convention, procedure numbers start from 1
|
||||
and are assigned monotonically thereafter.
|
||||
</dd>
|
||||
<dt><code>type</code></dt>
|
||||
<dd>
|
||||
<p>
|
||||
This can be one of the following enumeration values
|
||||
</p>
|
||||
<ol>
|
||||
<li>call: invocation of a method call</li>
|
||||
<li>reply: completion of a method call</li>
|
||||
<li>event: an asynchronous event</li>
|
||||
<li>stream: control info or data from a stream</li>
|
||||
</ol>
|
||||
</dd>
|
||||
<dt><code>serial</code></dt>
|
||||
<dd>
|
||||
This is an number that starts from 1 and increases
|
||||
each time a method call packet is sent. A reply or
|
||||
stream packet will have a serial number matching the
|
||||
original method call packet serial. Events always
|
||||
have the serial number set to 0.
|
||||
</dd>
|
||||
<dt><code>status</code></dt>
|
||||
<dd>
|
||||
<p>
|
||||
This can one of the following enumeration values
|
||||
</p>
|
||||
<ol>
|
||||
<li>ok: a normal packet. this is always set for method calls or events.
|
||||
For replies it indicates successful completion of the method. For
|
||||
streams it indicates confirmation of the end of file on the stream.</li>
|
||||
<li>error: for replies this indicates that the method call failed
|
||||
and error information is being returned. For streams this indicates
|
||||
that not all data was sent and the stream has aborted</li>
|
||||
<li>continue: for streams this indicates that further data packets
|
||||
will be following</li>
|
||||
</ol>
|
||||
</dl>
|
||||
|
||||
<h3><a href="protocolpayload">Packet payload</a></h3>
|
||||
|
||||
<p>
|
||||
The payload of a packet will vary depending on the <code>type</code>
|
||||
and <code>status</code> fields from the header.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>type=call: the in parameters for the method call, XDR encoded</li>
|
||||
<li>type=call-with-fds: number of file handles, then the in parameters for the method call, XDR encoded, followed by the file handles</li>
|
||||
<li>type=reply+status=ok: the return value and/or out parameters for the method call, XDR encoded</li>
|
||||
<li>type=reply+status=error: the error information for the method, a virErrorPtr XDR encoded</li>
|
||||
<li>type=reply-with-fds+status=ok: number of file handles, the return value and/or out parameters for the method call, XDR encoded, followed by the file handles</li>
|
||||
<li>type=reply-with-fds+status=error: number of file handles, the error information for the method, a virErrorPtr XDR encoded, followed by the file handles</li>
|
||||
<li>type=event: the parameters for the event, XDR encoded</li>
|
||||
<li>type=stream+status=ok: no payload</li>
|
||||
<li>type=stream+status=error: the error information for the method, a virErrorPtr XDR encoded</li>
|
||||
<li>type=stream+status=continue: the raw bytes of data for the stream. No XDR encoding</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
With the two packet types that support passing file descriptors, in
|
||||
between the header and the payload there will be a 4-byte integer
|
||||
specifying the number of file descriptors which are being sent.
|
||||
The actual file handles are sent after the payload has been sent.
|
||||
Each file handle has a single dummy byte transmitted as a carrier
|
||||
for the out of band file descriptor. While the sender should always
|
||||
send '\0' as the dummy byte value, the receiver ought to ignore the
|
||||
value for the sake of robustness.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For the exact payload information for each procedure, consult the XDR protocol
|
||||
definition for the program+version in question
|
||||
</p>
|
||||
|
||||
<h3><a name="wireexamples">Wire examples</a></h3>
|
||||
|
||||
<p>
|
||||
The following diagrams illustrate some example packet exchanges
|
||||
between a client and server
|
||||
</p>
|
||||
|
||||
<h4><a name="wireexamplescall">Method call</a></h4>
|
||||
|
||||
<p>
|
||||
A single method call and successful
|
||||
reply, for a program=8, version=1, procedure=3, which 10 bytes worth
|
||||
of input args, and 4 bytes worth of return values. The overall input
|
||||
packet length is 4 + 24 + 10 == 38, and output packet length 32
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --> S (call)
|
||||
+--+-----------------------+-----------+
|
||||
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | <-- S (reply)
|
||||
+--+-----------------------+--------+
|
||||
</pre>
|
||||
|
||||
<h4><a name="wireexamplescallerr">Method call with error</a></h4>
|
||||
|
||||
<p>
|
||||
An unsuccessful method call will instead return an error object
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --> S (call)
|
||||
+--+-----------------------+-----------+
|
||||
|
||||
+--+-----------------------+--------------------------+
|
||||
C <-- |48| 8 | 1 | 3 | 2 | 1 | 0 | .o.oOo.o.oOo.o.oOo.o.oOo | <-- S (error)
|
||||
+--+-----------------------+--------------------------+
|
||||
</pre>
|
||||
|
||||
<h4><a name="wireexamplescallup">Method call with upload stream</a></h4>
|
||||
|
||||
<p>
|
||||
A method call which also involves uploading some data over
|
||||
a stream will result in
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --> S (call)
|
||||
+--+-----------------------+-----------+
|
||||
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | <-- S (reply)
|
||||
+--+-----------------------+--------+
|
||||
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
...
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+
|
||||
C --> |24| 8 | 1 | 3 | 3 | 1 | 0 | --> S (stream finish)
|
||||
+--+-----------------------+
|
||||
+--+-----------------------+
|
||||
C <-- |24| 8 | 1 | 3 | 3 | 1 | 0 | <-- S (stream finish)
|
||||
+--+-----------------------+
|
||||
</pre>
|
||||
|
||||
<h4><a name="wireexamplescallbi">Method call bidirectional stream</a></h4>
|
||||
|
||||
<p>
|
||||
A method call which also involves a bi-directional stream will
|
||||
result in
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --> S (call)
|
||||
+--+-----------------------+-----------+
|
||||
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | <-- S (reply)
|
||||
+--+-----------------------+--------+
|
||||
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C <-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | <-- S (stream data down)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C <-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | <-- S (stream data down)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C <-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | <-- S (stream data down)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C <-- |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | <-- S (stream data down)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
..
|
||||
+--+-----------------------+-------------....-------+
|
||||
C --> |38| 8 | 1 | 3 | 3 | 1 | 2 | .o.oOo.o.oOo....o.oOo. | --> S (stream data up)
|
||||
+--+-----------------------+-------------....-------+
|
||||
+--+-----------------------+
|
||||
C --> |24| 8 | 1 | 3 | 3 | 1 | 0 | --> S (stream finish)
|
||||
+--+-----------------------+
|
||||
+--+-----------------------+
|
||||
C <-- |24| 8 | 1 | 3 | 3 | 1 | 0 | <-- S (stream finish)
|
||||
+--+-----------------------+
|
||||
</pre>
|
||||
|
||||
|
||||
<h4><a name="wireexamplescallmany">Method calls overlapping</a></h4>
|
||||
<pre>
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 1 | 0 | .o.oOo.o. | --> S (call 1)
|
||||
+--+-----------------------+-----------+
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 2 | 0 | .o.oOo.o. | --> S (call 2)
|
||||
+--+-----------------------+-----------+
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 2 | 0 | .o.oOo | <-- S (reply 2)
|
||||
+--+-----------------------+--------+
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 3 | 0 | .o.oOo.o. | --> S (call 3)
|
||||
+--+-----------------------+-----------+
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 3 | 0 | .o.oOo | <-- S (reply 3)
|
||||
+--+-----------------------+--------+
|
||||
+--+-----------------------+-----------+
|
||||
C --> |38| 8 | 1 | 3 | 0 | 4 | 0 | .o.oOo.o. | --> S (call 4)
|
||||
+--+-----------------------+-----------+
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | <-- S (reply 1)
|
||||
+--+-----------------------+--------+
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 4 | 0 | .o.oOo | <-- S (reply 4)
|
||||
+--+-----------------------+--------+
|
||||
</pre>
|
||||
|
||||
<h4><a name="wireexamplescallfd">Method call with passed FD</a></h4>
|
||||
|
||||
<p>
|
||||
A single method call with 2 passed file descriptors and successful
|
||||
reply, for a program=8, version=1, procedure=3, which 10 bytes worth
|
||||
of input args, and 4 bytes worth of return values. The number of
|
||||
file descriptors is encoded as a 32-bit int. Each file descriptor
|
||||
then has a 1 byte dummy payload. The overall input
|
||||
packet length is 4 + 24 + 4 + 2 + 10 == 44, and output packet length 32.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
+--+-----------------------+---------------+-------+
|
||||
C --> |44| 8 | 1 | 3 | 0 | 1 | 0 | 2 | .o.oOo.o. | 0 | 0 | --> S (call)
|
||||
+--+-----------------------+---------------+-------+
|
||||
|
||||
+--+-----------------------+--------+
|
||||
C <-- |32| 8 | 1 | 3 | 1 | 1 | 0 | .o.oOo | <-- S (reply)
|
||||
+--+-----------------------+--------+
|
||||
</pre>
|
||||
|
||||
|
||||
<h2><a name="security">RPC security</a></h2>
|
||||
|
||||
<p>
|
||||
There are various things to consider to ensure an implementation
|
||||
of the RPC protocol can be satisfactorily secured
|
||||
</p>
|
||||
|
||||
<h3><a name="securitytls">Authentication/encryption</a></h3>
|
||||
|
||||
<p>
|
||||
The basic RPC protocol does not define or require any specific
|
||||
authentication/encryption capabilities. A generic solution to
|
||||
providing encryption for the protocol is to run the protocol
|
||||
over a TLS encrypted data stream. x509 certificate checks can
|
||||
be done to form a crude authentication mechanism. It is also
|
||||
possible for an RPC program to negotiate an encryption /
|
||||
authentication capability, such as SASL, which may then also
|
||||
provide per-packet data encryption. Finally the protocol data
|
||||
stream can of course be tunnelled over transports such as SSH.
|
||||
</p>
|
||||
|
||||
<h3><a name="securitylimits">Data limits</a></h3>
|
||||
|
||||
<p>
|
||||
Although the protocol itself defines many arbitrary sized data values in the
|
||||
payloads, to avoid denial of service attack there are a number of size limit
|
||||
checks prior to encoding or decoding data. There is a limit on the maximum
|
||||
size of a single RPC message, limit on the maximum string length, and limits
|
||||
on any other parameter which uses a variable length array. These limits can
|
||||
be raised, subject to agreement between client/server, without otherwise
|
||||
breaking compatibility of the RPC data on the wire.
|
||||
</p>
|
||||
|
||||
<h3><a name="securityvalidate">Data validation</a></h3>
|
||||
|
||||
<p>
|
||||
It is important that all data be fully validated before performing
|
||||
any actions based on the data. When reading an RPC packet, the
|
||||
first four bytes must be read and the max packet size limit validated,
|
||||
before any attempt is made to read the variable length packet data.
|
||||
After a complete packet has been read, the header must be decoded
|
||||
and all 6 fields fully validated, before attempting to dispatch
|
||||
the payload. Once dispatched, the payload can be decoded and passed
|
||||
onto the appropriate API for execution. The RPC code must not take
|
||||
any action based on the payload, since it has no way to validate
|
||||
the semantics of the payload data. It must delegate this to the
|
||||
execution API (e.g. corresponding libvirt public API).
|
||||
</p>
|
||||
|
||||
<h2><a name="internals">RPC internal APIs</a></h2>
|
||||
|
||||
<p>
|
||||
The generic internal RPC library code lives in the <code>src/rpc/</code>
|
||||
directory of the libvirt source tree. Unless otherwise noted, the
|
||||
objects are all threadsafe. The core object types and their
|
||||
purposes are:
|
||||
</p>
|
||||
|
||||
<h3><a name="apioverview">Overview of RPC objects</a></h3>
|
||||
|
||||
<p>
|
||||
The following is a high level overview of the role of each
|
||||
of the main RPC objects
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>virNetSASLContextPtr</code> (virnetsaslcontext.h)</dt>
|
||||
<dd>The virNetSASLContext APIs maintain SASL state for a network
|
||||
service (server or client). This is primarily used on the server
|
||||
to provide a whitelist of allowed SASL usernames for clients.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetSASLSessionPtr</code> (virnetsaslcontext.h)</dt>
|
||||
<dd>The virNetSASLSession APIs maintain SASL state for a single
|
||||
network connection (socket). This is used to perform the multi-step
|
||||
SASL handshake and perform encryption/decryption of data once
|
||||
authenticated, via integration with virNetSocket.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetTLSContextPtr</code> (virnettlscontext.h)</dt>
|
||||
<dd>The virNetTLSContext APIs maintain TLS state for a network
|
||||
service (server or client). This is primarily used on the server
|
||||
to provide a whitelist of allowed x509 distinguished names, as
|
||||
well as diffie-hellman keys. It can also do validation of
|
||||
x509 certificates prior to initiating a connection, in order
|
||||
to improve detection of configuration errors.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetTLSSessionPtr</code> (virnettlscontext.h)</dt>
|
||||
<dd>The virNetTLSSession APIs maintain TLS state for a single
|
||||
network connection (socket). This is used to perform the multi-step
|
||||
TLS handshake and perform encryption/decryption of data once
|
||||
authenticated, via integration with virNetSocket.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetSocketPtr</code> (virnetsocket.h)</dt>
|
||||
<dd>The virNetSocket APIs provide a higher level wrapper around
|
||||
the raw BSD sockets and getaddrinfo APIs. They allow for creation
|
||||
of both server and client sockets. Data transports supported are
|
||||
TCP, UNIX, SSH tunnel or external command tunnel. Internally the
|
||||
TCP socket impl uses the getaddrinfo info APIs to ensure correct
|
||||
protocol-independent behaviour, thus supporting both IPv4 and IPv6.
|
||||
The socket APIs can be associated with a virNetSASLSessionPtr or
|
||||
virNetTLSSessionPtr object to allow seamless encryption/decryption
|
||||
of all writes and reads. For UNIX sockets it is possible to obtain
|
||||
the remote client user ID and process ID. Integration with the
|
||||
libvirt event loop also allows use of callbacks for notification
|
||||
of various I/O conditions
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetMessagePtr</code> (virnetmessage.h)</dt>
|
||||
<dd>The virNetMessage APIs provide a wrapper around the libxdr
|
||||
API calls, to facilitate processing and creation of RPC
|
||||
packets. There are convenience APIs for encoding/encoding the
|
||||
packet headers, encoding/decoding the payload using an XDR
|
||||
filter, encoding/decoding a raw payload (for streams), and
|
||||
encoding a virErrorPtr object. There is also a means to
|
||||
add to/serve from a linked-list queue of messages.</dd>
|
||||
|
||||
<dt><code>virNetClientPtr</code> (virnetclient.h)</dt>
|
||||
<dd>The virNetClient APIs provide a way to connect to a
|
||||
remote server and run one or more RPC protocols over
|
||||
the connection. Connections can be made over TCP, UNIX
|
||||
sockets, SSH tunnels, or external command tunnels. There
|
||||
is support for both TLS and SASL session encryption.
|
||||
The client also supports management of multiple data streams
|
||||
over each connection. Each client object can be used from
|
||||
multiple threads concurrently, with method calls/replies
|
||||
being interleaved on the wire as required.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetClientProgramPtr</code> (virnetclientprogram.h)</dt>
|
||||
<dd>The virNetClientProgram APIs are used to register a
|
||||
program+version with the connection. This then enables
|
||||
invocation of method calls, receipt of asynchronous
|
||||
events and use of data streams, within that program+version.
|
||||
When created a set of callbacks must be supplied to take
|
||||
care of dispatching any incoming asynchronous events.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetClientStreamPtr</code> (virnetclientstream.h)</dt>
|
||||
<dd>The virNetClientStream APIs are used to control transmission and
|
||||
receipt of data over a stream active on a client. Streams provide
|
||||
a low latency, unlimited length, bi-directional raw data exchange
|
||||
mechanism layered over the RPC connection
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetServerPtr</code> (virnetserver.h)</dt>
|
||||
<dd>The virNetServer APIs are used to manage a network server. A
|
||||
server exposed one or more programs, over one or more services.
|
||||
It manages multiple client connections invoking multiple RPC
|
||||
calls in parallel, with dispatch across multiple worker threads.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetServerMDNSPtr</code> (virnetservermdns.h)</dt>
|
||||
<dd>The virNetServerMDNS APIs are used to advertise a server
|
||||
across the local network, enabling clients to automatically
|
||||
detect the existence of remote services. This is done by
|
||||
interfacing with the Avahi mDNS advertisement service.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetServerClientPtr</code> (virnetserverclient.h)</dt>
|
||||
<dd>The virNetServerClient APIs are used to manage I/O related
|
||||
to a single client network connection. It handles initial
|
||||
validation and routing of incoming RPC packets, and transmission
|
||||
of outgoing packets.
|
||||
</dd>
|
||||
|
||||
<dt><code>virNetServerProgramPtr</code> (virnetserverprogram.h)</dt>
|
||||
<dd>The virNetServerProgram APIs are used to provide the implementation
|
||||
of a single program/version set. Primarily this includes a set of
|
||||
callbacks used to actually invoke the APIs corresponding to
|
||||
program procedure numbers. It is responsible for all the serialization
|
||||
of payloads to/from XDR.</dd>
|
||||
|
||||
<dt><code>virNetServerServicePtr</code> (virnetserverservice.h)</dt>
|
||||
<dd>The virNetServerService APIs are used to connect the server to
|
||||
one or more network protocols. A single service may involve multiple
|
||||
sockets (ie both IPv4 and IPv6). A service also has an associated
|
||||
authentication policy for incoming clients.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3><a name="apiclientdispatch">Client RPC dispatch</a></h3>
|
||||
|
||||
<p>
|
||||
The client RPC code must allow for multiple overlapping RPC method
|
||||
calls to be invoked, transmission and receipt of data for multiple
|
||||
streams and receipt of asynchronous events. Understandably this
|
||||
involves coordination of multiple threads.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The core requirement in the client dispatch code is that only
|
||||
one thread is allowed to be performing I/O on the socket at
|
||||
any time. This thread is said to be "holding the buck". When
|
||||
any other thread comes along and needs to do I/O it must place
|
||||
its packets on a queue and delegate processing of them to the
|
||||
thread that has the buck. This thread will send out the method
|
||||
call, and if it sees a reply will pass it back to the waiting
|
||||
thread. If the other thread's reply hasn't arrived, by the time
|
||||
the main thread has got its own reply, then it will transfer
|
||||
responsibility for I/O to the thread that has been waiting the
|
||||
longest. It is said to be "passing the buck" for I/O.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When no thread is performing any RPC method call, or sending
|
||||
stream data there is still a need to monitor the socket for
|
||||
incoming I/O related to asynchronous events, or stream data
|
||||
receipt. For this task, a watch is registered with the event
|
||||
loop which triggers whenever the socket is readable. This
|
||||
watch is automatically disabled whenever any other thread
|
||||
grabs the buck, and re-enabled when the buck is released.
|
||||
</p>
|
||||
|
||||
<h4><a name="apiclientdispatchex1">Example with buck passing</a></h4>
|
||||
|
||||
<p>
|
||||
In the first example, a second thread issues a API call
|
||||
while the first thread holds the buck. The reply to the
|
||||
first call arrives first, so the buck is passed to the
|
||||
second thread.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Thread-1
|
||||
|
|
||||
V
|
||||
Call API1()
|
||||
|
|
||||
V
|
||||
Grab Buck
|
||||
| Thread-2
|
||||
V |
|
||||
Send method1 V
|
||||
| Call API2()
|
||||
V |
|
||||
Wait I/O V
|
||||
|<--------Queue method2
|
||||
V |
|
||||
Send method2 V
|
||||
| Wait for buck
|
||||
V |
|
||||
Wait I/O |
|
||||
| |
|
||||
V |
|
||||
Recv reply1 |
|
||||
| |
|
||||
V |
|
||||
Pass the buck----->|
|
||||
| V
|
||||
V Wait I/O
|
||||
Return API1() |
|
||||
V
|
||||
Recv reply2
|
||||
|
|
||||
V
|
||||
Release the buck
|
||||
|
|
||||
V
|
||||
Return API2()
|
||||
</pre>
|
||||
|
||||
<h4><a name="apiclientdispatchex2">Example without buck passing</a></h4>
|
||||
|
||||
<p>
|
||||
In this second example, a second thread issues an API call
|
||||
which is sent and replied to, before the first thread's
|
||||
API call has completed. The first thread thus notifies
|
||||
the second that its reply is ready, and there is no need
|
||||
to pass the buck
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Thread-1
|
||||
|
|
||||
V
|
||||
Call API1()
|
||||
|
|
||||
V
|
||||
Grab Buck
|
||||
| Thread-2
|
||||
V |
|
||||
Send method1 V
|
||||
| Call API2()
|
||||
V |
|
||||
Wait I/O V
|
||||
|<--------Queue method2
|
||||
V |
|
||||
Send method2 V
|
||||
| Wait for buck
|
||||
V |
|
||||
Wait I/O |
|
||||
| |
|
||||
V |
|
||||
Recv reply2 |
|
||||
| |
|
||||
V |
|
||||
Notify reply2------>|
|
||||
| V
|
||||
V Return API2()
|
||||
Wait I/O
|
||||
|
|
||||
V
|
||||
Recv reply1
|
||||
|
|
||||
V
|
||||
Release the buck
|
||||
|
|
||||
V
|
||||
Return API1()
|
||||
</pre>
|
||||
|
||||
<h4><a name="apiclientdispatchex3">Example with async events</a></h4>
|
||||
|
||||
<p>
|
||||
In this example, only one thread is present and it has to
|
||||
deal with some async events arriving. The events are actually
|
||||
dispatched to the application from the event loop thread
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Thread-1
|
||||
|
|
||||
V
|
||||
Call API1()
|
||||
|
|
||||
V
|
||||
Grab Buck
|
||||
|
|
||||
V
|
||||
Send method1
|
||||
|
|
||||
V
|
||||
Wait I/O
|
||||
| Event thread
|
||||
V ...
|
||||
Recv event1 |
|
||||
| V
|
||||
V Wait for timer/fd
|
||||
Queue event1 |
|
||||
| V
|
||||
V Timer fires
|
||||
Wait I/O |
|
||||
| V
|
||||
V Emit event1
|
||||
Recv reply1 |
|
||||
| V
|
||||
V Wait for timer/fd
|
||||
Return API1() |
|
||||
...
|
||||
</pre>
|
||||
|
||||
<h3><a name="apiserverdispatch">Server RPC dispatch</a></h3>
|
||||
|
||||
<p>
|
||||
The RPC server code must support receipt of incoming RPC requests from
|
||||
multiple client connections, and parallel processing of all RPC
|
||||
requests, even many from a single client. This goal is achieved through
|
||||
a combination of event driven I/O, and multiple processing threads.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The main libvirt event loop thread is responsible for performing all
|
||||
socket I/O. It will read incoming packets from clients and willl
|
||||
transmit outgoing packets to clients. It will handle the I/O to/from
|
||||
streams associated with client API calls. When doing client I/O it
|
||||
will also pass the data through any applicable encryption layer
|
||||
(through use of the virNetSocket / virNetTLSSession and virNetSASLSession
|
||||
integration). What is paramount is that the event loop thread never
|
||||
do any task that can take a non-trivial amount of time.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When reading packets, the event loop will first read the 4 byte length
|
||||
word. This is validated to make sure it does not exceed the maximum
|
||||
permissible packet size, and the client is set to allow receipt of the
|
||||
rest of the packet data. Once a complete packet has been received, the
|
||||
next step is to decode the RPC header. The header is validated to
|
||||
ensure the request is sensible, ie the server should not receive a
|
||||
method reply from a client. If the client has not yet authenticated,
|
||||
a security check is also applied to make sure the procedure is on the
|
||||
whitelist of those allowed prior to auth. If the packet is a method
|
||||
call, it will be placed on a global processing queue. The event loop
|
||||
thread is now done with the packet for the time being.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The server has a pool of worker threads, which wait for method call
|
||||
packets to be queued. One of them will grab the new method call off
|
||||
the queue for processing. The first step is to decode the payload of
|
||||
the packet to extract the method call arguments. The worker does not
|
||||
attempt to do any semantic validation of the arguments, except to make
|
||||
sure the size of any variable length fields is below defined limits.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The worker now invokes the libvirt API call that corresponds to the
|
||||
procedure number in the packet header. The worker is thus kept busy
|
||||
until the API call completes. The implementation of the API call
|
||||
is responsible for doing semantic validation of parameters and any
|
||||
MAC security checks on the objects affected.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once the API call has completed, the worker thread will take the
|
||||
return value and output parameters, or error object and encode
|
||||
them into a reply packet. Again it does not attempt to do any
|
||||
semantic validation of output data, aside from variable length
|
||||
field limit checks. The worker thread puts the reply packet onto
|
||||
the transmission queue for the client. The worker is now finished
|
||||
and goes back to wait for another incoming method call.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The main event loop is back in charge and when the client socket
|
||||
becomes writable, it will start sending the method reply packet
|
||||
back to the client.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
At any time the libvirt connection object can emit asynchronous
|
||||
events. These are handled by callbacks in the main event thread.
|
||||
The callback will simply encode the event parameters into a new
|
||||
data packet and place the packet on the client transmission
|
||||
queue.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Incoming and outgoing stream packets are also directly handled
|
||||
by the main event thread. When an incoming stream packet is
|
||||
received, instead of placing it in the global dispatch queue
|
||||
for the worker threads, it is sidetracked into a per-stream
|
||||
processing queue. When the stream becomes writable, queued
|
||||
incoming stream packets will be processed, passing their data
|
||||
payload onto the stream. Conversely when the stream becomes
|
||||
readable, chunks of data will be read from it, encoded into
|
||||
new outgoing packets, and placed on the client's transmit
|
||||
queue
|
||||
</p>
|
||||
|
||||
<h4><a name="apiserverdispatchex1">Example with overlapping methods</a></h4>
|
||||
|
||||
<p>
|
||||
This example illustrates processing of two incoming methods with
|
||||
overlapping execution
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Event thread Worker 1 Worker 2
|
||||
| | |
|
||||
V V V
|
||||
Wait I/O Wait Job Wait Job
|
||||
| | |
|
||||
V | |
|
||||
Recv method1 | |
|
||||
| | |
|
||||
V | |
|
||||
Queue method1 V |
|
||||
| Serve method1 |
|
||||
V | |
|
||||
Wait I/O V |
|
||||
| Call API1() |
|
||||
V | |
|
||||
Recv method2 | |
|
||||
| | |
|
||||
V | |
|
||||
Queue method2 | V
|
||||
| | Serve method2
|
||||
V V |
|
||||
Wait I/O Return API1() V
|
||||
| | Call API2()
|
||||
| V |
|
||||
V Queue reply1 |
|
||||
Send reply1 | |
|
||||
| V V
|
||||
V Wait Job Return API2()
|
||||
Wait I/O | |
|
||||
| ... V
|
||||
V Queue reply2
|
||||
Send reply2 |
|
||||
| V
|
||||
V Wait Job
|
||||
Wait I/O |
|
||||
| ...
|
||||
...
|
||||
</pre>
|
||||
|
||||
<h4><a name="apiserverdispatchex2">Example with stream data</a></h4>
|
||||
|
||||
<p>
|
||||
This example illustrates processing of stream data
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Event thread
|
||||
|
|
||||
V
|
||||
Wait I/O
|
||||
|
|
||||
V
|
||||
Recv stream1
|
||||
|
|
||||
V
|
||||
Queue stream1
|
||||
|
|
||||
V
|
||||
Wait I/O
|
||||
|
|
||||
V
|
||||
Recv stream2
|
||||
|
|
||||
V
|
||||
Queue stream2
|
||||
|
|
||||
V
|
||||
Wait I/O
|
||||
|
|
||||
V
|
||||
Write stream1
|
||||
|
|
||||
V
|
||||
Write stream2
|
||||
|
|
||||
V
|
||||
Wait I/O
|
||||
|
|
||||
...
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -199,6 +199,10 @@ div.api table {
|
||||
whitespace: pre;
|
||||
}
|
||||
|
||||
div.api table td, div.variablelist table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a {
|
||||
color: inherit;
|
||||
@ -360,3 +364,51 @@ span.since {
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.diagram {
|
||||
background: rgb(230,230,230);
|
||||
border: 2px dotted rgb(178,178,178);
|
||||
padding: 1em;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.data th, table.data td {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
table.data {
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
table.data thead th {
|
||||
background: rgb(178,178,178);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.data {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.data thead tr th {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
table.data tr.head th {
|
||||
border-left: 1px solid black;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
table.data tbody td {
|
||||
background: rgb(240,240,240);
|
||||
}
|
||||
table.data tbody td.y {
|
||||
background: rgb(220,255,220);
|
||||
text-align: center;
|
||||
}
|
||||
table.data tbody td.n {
|
||||
background: rgb(255,220,220);
|
||||
text-align: center;
|
||||
}
|
||||
|
58
docs/migration-managed-direct.fig
Normal file
58
docs/migration-managed-direct.fig
Normal file
@ -0,0 +1,58 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 2775 2400 3675 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
|
||||
-6
|
||||
6 5400 2400 6300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||
1 1 1.00 135.00 180.00
|
||||
4350 4275 4350 3600 3300 3600 3300 2850
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||
1 1 1.00 135.00 180.00
|
||||
4800 4275 4800 3600 5775 3600 5775 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3225 4125 5850 4125 5850 6000 3225 6000 3225 4125
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
3375 5100 5700 5100 5700 5550 3375 5550 3375 5100
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
|
||||
1 1 1.00 135.00 180.00
|
||||
3750 5100 3750 4500 4050 4500
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
4050 4275 5100 4275 5100 4725 4050 4725 4050 4275
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 960 4725 5850 Client Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 180 1500 3525 5400 management app\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 735 4200 4575 libvirt.so\001
|
BIN
docs/migration-managed-direct.png
Normal file
BIN
docs/migration-managed-direct.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
58
docs/migration-managed-p2p.fig
Normal file
58
docs/migration-managed-p2p.fig
Normal file
@ -0,0 +1,58 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 2775 2400 3675 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
|
||||
-6
|
||||
6 5400 2400 6300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||
1 1 1.00 135.00 180.00
|
||||
4350 4275 4350 3600 3300 3600 3300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3225 4125 5850 4125 5850 6000 3225 6000 3225 4125
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
3375 5100 5700 5100 5700 5550 3375 5550 3375 5100
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
|
||||
1 1 1.00 135.00 180.00
|
||||
3750 5100 3750 4500 4050 4500
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
4050 4275 5100 4275 5100 4725 4050 4725 4050 4275
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 135.00 180.00
|
||||
3675 2625 5400 2625
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 960 4725 5850 Client Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 180 1500 3525 5400 management app\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 735 4200 4575 libvirt.so\001
|
BIN
docs/migration-managed-p2p.png
Normal file
BIN
docs/migration-managed-p2p.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
43
docs/migration-native.fig
Normal file
43
docs/migration-native.fig
Normal file
@ -0,0 +1,43 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 2775 2400 3675 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
|
||||
-6
|
||||
6 5400 2400 6300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
|
||||
-6
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 4
|
||||
1 1 1.00 135.00 180.00
|
||||
3375 1350 3375 825 5700 825 5700 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
|
BIN
docs/migration-native.png
Normal file
BIN
docs/migration-native.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
49
docs/migration-tunnel.fig
Normal file
49
docs/migration-tunnel.fig
Normal file
@ -0,0 +1,49 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 2775 2400 3675 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
|
||||
-6
|
||||
6 5400 2400 6300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
|
||||
-6
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 135.00 180.00
|
||||
3375 1950 3375 2400
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 4
|
||||
1 1 1.00 135.00 180.00
|
||||
3375 2850 3375 3375 5700 3375 5700 2850
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 135.00 180.00
|
||||
5700 2400 5700 1950
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
|
BIN
docs/migration-tunnel.png
Normal file
BIN
docs/migration-tunnel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
58
docs/migration-unmanaged-direct.fig
Normal file
58
docs/migration-unmanaged-direct.fig
Normal file
@ -0,0 +1,58 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 2775 2400 3675 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 630 2925 2700 HV Ctrl\001
|
||||
-6
|
||||
6 5400 2400 6300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 630 5550 2700 HV Ctrl\001
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||
1 1 1.00 135.00 180.00
|
||||
4350 4275 4350 3600 3300 3600 3300 2850
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3225 4125 5850 4125 5850 6000 3225 6000 3225 4125
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
3375 5100 5700 5100 5700 5550 3375 5550 3375 5100
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
|
||||
1 1 1.00 135.00 180.00
|
||||
3750 5100 3750 4500 4050 4500
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
|
||||
4050 4275 5100 4275 5100 4725 4050 4725 4050 4275
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 135.00 180.00
|
||||
3675 2625 5400 2625
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 960 4725 5850 Client Host\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 180 1500 3525 5400 management app\001
|
||||
4 0 0 50 -1 16 12 0.0000 4 150 735 4200 4575 libvirt.so\001
|
BIN
docs/migration-unmanaged-direct.png
Normal file
BIN
docs/migration-unmanaged-direct.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
601
docs/migration.html.in
Normal file
601
docs/migration.html.in
Normal file
@ -0,0 +1,601 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Guest migration</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
|
||||
<p>
|
||||
Migration of guests between hosts is a complicated problem with many possible
|
||||
solutions, each with their own positive and negative points. For maximum
|
||||
flexibility of both hypervisor integration, and adminsitrator deployment,
|
||||
libvirt implements several options for migration.
|
||||
</p>
|
||||
|
||||
<h2><a id="transport">Network data transports</a></h2>
|
||||
|
||||
<p>
|
||||
There are two options for the data transport used during migration, either
|
||||
the hypervisor's own <strong>native</strong> transport, or <strong>tunnelled</strong>
|
||||
over a libvirtd connection.
|
||||
</p>
|
||||
|
||||
<h3><a id="transportnative">Hypervisor native transport</a></h3>
|
||||
<p>
|
||||
<em>Native</em> data transports may or may not support encryption, depending
|
||||
on the hypervisor in question, but will typically have the lowest computational costs
|
||||
by minimising the number of data copies involved. The native data transports will also
|
||||
require extra hypervisor-specific network configuration steps by the administrator when
|
||||
deploying a host. For some hypervisors, it might be neccessary to open up a large range
|
||||
of ports on the firewall to allow multiple concurrent migration operations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img class="diagram" src="migration-native.png" alt="Migration native path">
|
||||
</p>
|
||||
|
||||
<h3><a id="transporttunnel">libvirt tunnelled transport</a></h3>
|
||||
<p>
|
||||
<em>Tunnelled</em> data transports will always be capable of strong encryption
|
||||
since they are able to leverage the capabilities built in to the libvirt RPC protocol.
|
||||
The downside of a tunnelled transport, however, is that there will be extra data copies
|
||||
involved on both the source and destinations hosts as the data is moved between libvirtd
|
||||
and the hypervisor. This is likely to be a more significant problem for guests with
|
||||
very large RAM sizes, which dirty memory pages quickly. On the deployment side, tunnelled
|
||||
transports do not require any extra network configuration over and above what's already
|
||||
required for general libvirtd <a href="remote.html">remote access</a>, and there is only
|
||||
need for a single port to be open on the firewall to support multiple concurrent
|
||||
migration operations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img class="diagram" src="migration-tunnel.png" alt="Migration tunnel path">
|
||||
</p>
|
||||
|
||||
<h2><a id="flow">Communication control paths/flows</a></h2>
|
||||
|
||||
<p>
|
||||
Migration of virtual machines requires close co-ordination of the two
|
||||
hosts involved, as well as the application invoking the migration,
|
||||
which may be on the source, the destination, or a third host.
|
||||
</p>
|
||||
|
||||
<h3><a id="flowmanageddirect">Managed direct migration</a></h3>
|
||||
|
||||
<p>
|
||||
With <em>managed direct</em> migration, the libvirt client process
|
||||
controls the various phases of migration. The client application must
|
||||
be able to connect and authenticate with the libvirtd daemons on both
|
||||
the source and destination hosts. There is no need for the two libvirtd
|
||||
daemons to communicate with each other. If the client application
|
||||
crashes, or otherwise loses its connection to libvirtd during the
|
||||
migration process, an attempt will be made to abort the migration and
|
||||
restart the guest CPUs on the source host. There may be scenarios
|
||||
where this cannot be safely done, in which cases the guest will be
|
||||
left paused on one or both of the hosts.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img class="diagram" src="migration-managed-direct.png" alt="Migration direct, managed">
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a id="flowpeer2peer">Managed peer to peer migration</a></h3>
|
||||
|
||||
<p>
|
||||
With <em>peer to peer</em> migration, the libvirt client process only
|
||||
talks to the libvirtd daemon on the source host. The source libvirtd
|
||||
daemon controls the entire migration process itself, by directly
|
||||
connecting the destination host libvirtd. If the client application crashes,
|
||||
or otherwise loses its connection to libvirtd, the migration process
|
||||
will continue uninterrupted until completion.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img class="diagram" src="migration-managed-p2p.png" alt="Migration peer-to-peer">
|
||||
</p>
|
||||
|
||||
|
||||
<h3><a id="flowunmanageddirect">Unmanaged direct migration</a></h3>
|
||||
|
||||
<p>
|
||||
With <em>unmanaged direct</em> migration, neither the libvirt client
|
||||
or libvirtd daemon control the migration process. Control is instead
|
||||
delegated to the hypervisor's over management services (if any). The
|
||||
libvirt client merely initiates the migration via the hypervisor's
|
||||
management layer. If the libvirt client or libvirtd crash, the
|
||||
migration process will continue uninterrupted until completion.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img class="diagram" src="migration-unmanaged-direct.png" alt="Migration direct, unmanaged">
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a id="security">Data security</a></h2>
|
||||
|
||||
<p>
|
||||
Since the migration data stream includes a complete copy of the guest
|
||||
OS RAM, snooping of the migration data stream may allow compromise
|
||||
of sensitive guest information. If the virtualization hosts have
|
||||
multiple network interfaces, or if the network switches support
|
||||
tagged VLANs, then it is very desirable to separate guest network
|
||||
traffic from migration or management traffic.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In some scenarios, even a separate network for migration data may
|
||||
not offer sufficient security. In this case it is possible to apply
|
||||
encryption to the migration data stream. If the hypervisor does not
|
||||
itself offer encryption, then the libvirt tunnelled migration
|
||||
facility should be used.
|
||||
</p>
|
||||
|
||||
<h2><a id="uris">Migration URIs</a></h2>
|
||||
|
||||
<p>
|
||||
Initiating a guest migration requires the client application to
|
||||
specify up to three URIs, depending on the choice of control
|
||||
flow and/or APIs used. The first URI is that of the libvirt
|
||||
connection to the source host, where the virtual guest is
|
||||
currently running. The second URI is that of the libvirt
|
||||
connection to the destination host, where the virtual guest
|
||||
will be moved to. The third URI is a hypervisor specific
|
||||
URI used to control how the guest will be migrated. With
|
||||
any managed migration flow, the first and second URIs are
|
||||
compulsory, while the third URI is optional. With the
|
||||
unmanaged direct migration mode, the first and third URIs are
|
||||
compulsory and the second URI is not used.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ordinarily management applications only need to care about the
|
||||
first and second URIs, which are both in the normal libvirt
|
||||
connection URI format. Libvirt will then automatically determine
|
||||
the hypervisor specific URI, by looking up the target host's
|
||||
configured hostname. There are a few scenarios where the management
|
||||
application may wish to have direct control over the third URI.
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>The configured hostname is incorrect, or DNS is broken. If a
|
||||
host has a hostname which will not resolve to match one of its
|
||||
public IP addresses, then libvirt will generate an incorrect
|
||||
URI. In this case the management application should specify the
|
||||
hypervisor specific URI explicitly, using an IP address, or a
|
||||
correct hostname.</li>
|
||||
<li>The host has multiple network interaces. If a host has multiple
|
||||
network interfaces, it might be desirable for the migration data
|
||||
stream to be sent over a specific interface for either security
|
||||
or performance reasons. In this case the management application
|
||||
should specify the hypervisor specific URI, using an IP address
|
||||
associated with the network to be used.</li>
|
||||
<li>The firewall restricts what ports are available. When libvirt
|
||||
generates a migration URI will pick a port number using hypervisor
|
||||
specific rules. Some hypervisors only require a single port to be
|
||||
open in the firewalls, while others require a whole range of port
|
||||
numbers. In the latter case the management application may wish
|
||||
to choose a specific port number outside the default range in order
|
||||
to comply with local firewall policies</li>
|
||||
</ol>
|
||||
|
||||
<h2><a id="config">Configuration file handling</a></h2>
|
||||
|
||||
<p>
|
||||
There are two types of virtual machine known to libvirt. A <em>transient</em>
|
||||
guest only exists while it is running, and has no configuration file stored
|
||||
on disk. A <em>persistent</em> guest maintains a configuration file on disk
|
||||
even when it is not running.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
By default, a migration operation will not attempt to change any configuration
|
||||
files that may be stored on either the source or destination host. It is the
|
||||
administrator, or management application's, responsibility to manage distribution
|
||||
of configuration files (if desired). It is important to note that the <code>/etc/libvirt</code>
|
||||
directory <strong>MUST NEVER BE SHARED BETWEEN HOSTS</strong>. There are some
|
||||
typical scenarios that might be applicable:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Centralized configuration files outside libvirt, in shared storage. A cluster
|
||||
aware management application may maintain all the master guest configuration
|
||||
files in a cluster filesystem. When attempting to start a guest, the config
|
||||
will be read from the cluster FS and used to deploy a persistent guest.
|
||||
For migration the configuration will need to be copied to the destination
|
||||
host and removed on the original.
|
||||
</li>
|
||||
<li>Centralized configuration files outside libvirt, in a database. A data center
|
||||
management application may not storage configuration files at all. Instead it
|
||||
may generate libvirt XML on the fly when a guest is booted. It will typically
|
||||
use transient guests, and thus not have to consider configuration files during
|
||||
migration.
|
||||
</li>
|
||||
<li>Distributed configuration inside libvirt. The configuration file for each
|
||||
guest is copied to every host where the guest is able to run. Upon migration
|
||||
the existing config merely needs to be updated with any changes
|
||||
</li>
|
||||
<li>Ad-hoc configuration management inside libvirt. Each guest is tied to a
|
||||
specific host and rarely migrated. When migration is required, the config
|
||||
is moved from one host to the other.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
As mentioned above, libvirt will not touch configuration files during
|
||||
migration by default. The <code>virsh</code> command has two flags to
|
||||
influence this behaviour. The <code>--undefine-source</code> flag
|
||||
will cause the configuration file to be removed on the source host
|
||||
after a successful migration. The <code>--persist</code> flag will
|
||||
cause a configuration file to be created on the destination host
|
||||
after a successful migration. The following table summarizes the
|
||||
configuration file handling in all possible state and flag
|
||||
combinations.
|
||||
</p>
|
||||
|
||||
<table class="data">
|
||||
<thead>
|
||||
<tr class="head">
|
||||
<th colspan="3">Before migration</th>
|
||||
<th colspan="2">Flags</th>
|
||||
<th colspan="3">After migration</th>
|
||||
</tr>
|
||||
<tr class="subhead">
|
||||
<th>Guest type</th>
|
||||
<th>Source config</th>
|
||||
<th>Dest config</th>
|
||||
<th>--undefine-source</th>
|
||||
<th>--persist</th>
|
||||
<th>Guest type</th>
|
||||
<th>Source config</th>
|
||||
<th>Dest config</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- src:N, dst:N -->
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
|
||||
<!-- src:N, dst:Y -->
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
|
||||
<!-- src:Y dst:N -->
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td>Transient</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td>Transient</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
|
||||
<!-- src:Y dst:Y -->
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="n">N</td>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Persistent</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td class="y">Y</td>
|
||||
<td>Persistent</td>
|
||||
<td class="n">N</td>
|
||||
<td class="y">Y</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2><a id="scenarios">Migration scenarios</a></h2>
|
||||
|
||||
|
||||
<h3><a id="scenarionativedirect">Native migration, client to two libvirtd servers</a></h3>
|
||||
|
||||
<p>
|
||||
At an API level this requires use of virDomainMigrate, without the
|
||||
VIR_MIGRATE_PEER2PEER flag set. The destination libvirtd server
|
||||
will automatically determine the native hypervisor URI for migration
|
||||
based off the primary hostname. To force migration over an alternate
|
||||
network interface the optional hypervisor specific URI must be provided
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
syntax: virsh migrate GUESTNAME DEST-LIBVIRT-URI [HV-URI]
|
||||
|
||||
|
||||
eg using default network interface
|
||||
|
||||
virsh migrate web1 qemu+ssh://desthost/system
|
||||
virsh migrate web1 xen+tls://desthost/system
|
||||
|
||||
|
||||
eg using secondary network interface
|
||||
|
||||
virsh migrate web1 qemu://desthost/system tcp://10.0.0.1/
|
||||
virsh migrate web1 xen+tcp://desthost/system xenmigr:10.0.0.1/
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Supported by Xen, QEMU, VMWare and VirtualBox drivers
|
||||
</p>
|
||||
|
||||
<h3><a id="scenarionativepeer2peer">Native migration, client to and peer2peer between, two libvirtd servers</a></h3>
|
||||
|
||||
<p>
|
||||
virDomainMigrate, with the VIR_MIGRATE_PEER2PEER flag set,
|
||||
using the libvirt URI format for the 'uri' parameter. The
|
||||
destination libvirtd server will automatically determine
|
||||
the native hypervisor URI for migration, based off the
|
||||
primary hostname. The optional uri parameter controls how
|
||||
the source libvirtd connects to the destination libvirtd,
|
||||
in case it is not accessible using the same address that
|
||||
the client uses to connect to the destination, or a different
|
||||
encryption/auth scheme is required. There is no
|
||||
scope for forcing an alternative network interface for the
|
||||
native migration data with this method.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This mode cannot be invoked from virsh
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Supported by QEMU driver
|
||||
</p>
|
||||
|
||||
<h3><a id="scenariotunnelpeer2peer1">Tunnelled migration, client and peer2peer between two libvirtd servers</a></h3>
|
||||
|
||||
<p>
|
||||
virDomainMigrate, with the VIR_MIGRATE_PEER2PEER & VIR_MIGRATE_TUNNELLED
|
||||
flags set, using the libvirt URI format for the 'uri' parameter. The
|
||||
destination libvirtd server will automatically determine
|
||||
the native hypervisor URI for migration, based off the
|
||||
primary hostname. The optional uri parameter controls how
|
||||
the source libvirtd connects to the destination libvirtd,
|
||||
in case it is not accessible using the same address that
|
||||
the client uses to connect to the destination, or a different
|
||||
encryption/auth scheme is required. The native hypervisor URI
|
||||
format is not used at all.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This mode cannot be invoked from virsh
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Supported by QEMU driver
|
||||
</p>
|
||||
|
||||
<h3><a id="nativedirectunmanaged">Native migration, client to one libvirtd server</a></h3>
|
||||
|
||||
<p>
|
||||
virDomainMigrateToURI, without the VIR_MIGRATE_PEER2PEER flag set,
|
||||
using a hypervisor specific URI format for the 'uri' parameter.
|
||||
There is no use or requirement for a destination libvirtd instance
|
||||
at all. This is typically used when the hypervisor has its own
|
||||
native management daemon available to handle incoming migration
|
||||
attempts on the destination.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
syntax: virsh migrate GUESTNAME HV-URI
|
||||
|
||||
|
||||
eg using same libvirt URI for all connections
|
||||
|
||||
virsh migrate --direct web1 xenmigr://desthost/
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Supported by Xen driver
|
||||
</p>
|
||||
|
||||
<h3><a id="nativepeer2peer">Native migration, peer2peer between two libvirtd servers</a></h3>
|
||||
|
||||
<p>
|
||||
virDomainMigrateToURI, with the VIR_MIGRATE_PEER2PEER flag set,
|
||||
using the libvirt URI format for the 'uri' parameter. The
|
||||
destination libvirtd server will automatically determine
|
||||
the native hypervisor URI for migration, based off the
|
||||
primary hostname. There is no scope for forcing an alternative
|
||||
network interface for the native migration data with this method.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
syntax: virsh migrate GUESTNAME DEST-LIBVIRT-URI [ALT-DEST-LIBVIRT-URI]
|
||||
|
||||
|
||||
eg using same libvirt URI for all connections
|
||||
|
||||
virsh migrate --p2p web1 qemu+ssh://desthost/system
|
||||
|
||||
|
||||
eg using different libvirt URI auth scheme for peer2peer connections
|
||||
|
||||
virsh migrate --p2p web1 qemu+ssh://desthost/system qemu+tls:/desthost/system
|
||||
|
||||
|
||||
eg using different libvirt URI hostname for peer2peer connections
|
||||
|
||||
virsh migrate --p2p web1 qemu+ssh://desthost/system qemu+ssh://10.0.0.1/system
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Supported by the QEMU driver
|
||||
</p>
|
||||
|
||||
<h3><a id="scenariotunnelpeer2peer2">Tunnelled migration, peer2peer between two libvirtd servers</a></h3>
|
||||
|
||||
<p>
|
||||
virDomainMigrateToURI, with the VIR_MIGRATE_PEER2PEER & VIR_MIGRATE_TUNNELLED
|
||||
flags set, using the libvirt URI format for the 'uri' parameter. The
|
||||
destination libvirtd server will automatically determine
|
||||
the native hypervisor URI for migration, based off the
|
||||
primary hostname. The optional uri parameter controls how
|
||||
the source libvirtd connects to the destination libvirtd,
|
||||
in case it is not accessible using the same address that
|
||||
the client uses to connect to the destination, or a different
|
||||
encryption/auth scheme is required. The native hypervisor URI
|
||||
format is not used at all.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
syntax: virsh migrate GUESTNAME DEST-LIBVIRT-URI [ALT-DEST-LIBVIRT-URI]
|
||||
|
||||
|
||||
eg using same libvirt URI for all connections
|
||||
|
||||
virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system
|
||||
|
||||
|
||||
eg using different libvirt URI auth scheme for peer2peer connections
|
||||
|
||||
virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system qemu+tls:/desthost/system
|
||||
|
||||
|
||||
eg using different libvirt URI hostname for peer2peer connections
|
||||
|
||||
virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system qemu+ssh://10.0.0.1/system
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Supported by QEMU driver
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -54,10 +54,13 @@
|
||||
because the keys are only defined on the main document -->
|
||||
<xsl:template mode="dumptoken" match='*'>
|
||||
<xsl:param name="token"/>
|
||||
<xsl:variable name="ref" select="key('symbols', $token)"/>
|
||||
<xsl:variable name="stem" select="translate($token, '(),.:;@', '')"/>
|
||||
<xsl:variable name="ref" select="key('symbols', $stem)"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$ref">
|
||||
<a href="libvirt-{$ref/@file}.html#{$ref/@name}"><xsl:value-of select="$token"/></a>
|
||||
<xsl:value-of select="substring-before($token, $stem)"/>
|
||||
<a href="libvirt-{$ref/@file}.html#{$ref/@name}"><xsl:value-of select="$stem"/></a>
|
||||
<xsl:value-of select="substring-after($token, $stem)"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$token"/>
|
||||
@ -70,7 +73,7 @@
|
||||
<xsl:param name="text"/>
|
||||
<xsl:variable name="ctxt" select='.'/>
|
||||
<!-- <xsl:value-of select="$text"/> -->
|
||||
<xsl:for-each select="str:tokenize($text, ' 	')">
|
||||
<xsl:for-each select="str:tokenize($text, ' 	 ')">
|
||||
<xsl:apply-templates select="$ctxt" mode='dumptoken'>
|
||||
<xsl:with-param name="token" select="string(.)"/>
|
||||
</xsl:apply-templates>
|
||||
|
1949
docs/news.html.in
1949
docs/news.html.in
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -53,9 +53,6 @@ machines through authenticated and encrypted connections.
|
||||
<li>
|
||||
<a href="#Remote_limitations">Limitations</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#Remote_implementation_notes">Implementation notes</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a name="Remote_basic_usage">Basic usage</a>
|
||||
@ -275,13 +272,34 @@ Note that parameter values must be
|
||||
<td colspan="2"/>
|
||||
<td> Example: <code>netcat=/opt/netcat/bin/nc</code> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<code>keyfile</code>
|
||||
</td>
|
||||
<td> ssh </td>
|
||||
<td>
|
||||
The name of the private key file to use to authentication to the remote
|
||||
machine. If this option is not used the default keys are used.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"/>
|
||||
<td> Example: <code>keyfile=/root/.ssh/example_key</code> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<code>no_verify</code>
|
||||
</td>
|
||||
<td> tls </td>
|
||||
<td> ssh, tls </td>
|
||||
<td>
|
||||
If set to a non-zero value, this disables client checks of the
|
||||
SSH: If set to a non-zero value, this disables client's strict host key
|
||||
checking making it auto-accept new host keys. Existing host keys will
|
||||
still be validated.
|
||||
<br/>
|
||||
<br/>
|
||||
TLS: If set to a non-zero value, this disables client checks of the
|
||||
server's certificate. Note that to disable server checks of
|
||||
the client's certificate or IP address you must
|
||||
<a href="#Remote_libvirtd_configuration">change the libvirtd
|
||||
@ -858,48 +876,6 @@ just read-write/read-only as at present.
|
||||
</ul>
|
||||
<p>
|
||||
Please come and discuss these issues and more on <a href="https://www.redhat.com/mailman/listinfo/libvir-list" title="libvir-list mailing list">the mailing list</a>.
|
||||
</p>
|
||||
<h3>
|
||||
<a name="Remote_implementation_notes">Implementation notes</a>
|
||||
</h3>
|
||||
<p>
|
||||
The current implementation uses <a href="http://en.wikipedia.org/wiki/External_Data_Representation" title="External Data Representation">XDR</a>-encoded packets with a
|
||||
simple remote procedure call implementation which also supports
|
||||
asynchronous messaging and asynchronous and out-of-order replies,
|
||||
although these latter features are not used at the moment.
|
||||
</p>
|
||||
<p>
|
||||
The implementation should be considered <b>strictly internal</b> to
|
||||
libvirt and <b>subject to change at any time without notice</b>. If
|
||||
you wish to talk to libvirtd, link to libvirt. If there is a problem
|
||||
that means you think you need to use the protocol directly, please
|
||||
first discuss this on <a href="https://www.redhat.com/mailman/listinfo/libvir-list" title="libvir-list mailing list">the mailing list</a>.
|
||||
</p>
|
||||
<p>
|
||||
The messaging protocol is described in
|
||||
<code>qemud/remote_protocol.x</code>.
|
||||
</p>
|
||||
<p>
|
||||
Authentication and encryption (for TLS) is done using <a href="http://www.gnu.org/software/gnutls/" title="GnuTLS project page">GnuTLS</a> and the RPC protocol is unaware of this layer.
|
||||
</p>
|
||||
<p>
|
||||
Protocol messages are sent using a simple 32 bit length word (encoded
|
||||
XDR int) followed by the message header (XDR
|
||||
<code>remote_message_header</code>) followed by the message body. The
|
||||
length count includes the length word itself, and is measured in
|
||||
bytes. Maximum message size is <code>REMOTE_MESSAGE_MAX</code> and to
|
||||
avoid denial of services attacks on the XDR decoders strings are
|
||||
individually limited to <code>REMOTE_STRING_MAX</code> bytes. In the
|
||||
TLS case, messages may be split over TLS records, but a TLS record
|
||||
cannot contain parts of more than one message. In the common RPC case
|
||||
a single <code>REMOTE_CALL</code> message is sent from client to
|
||||
server, and the server then replies synchronously with a single
|
||||
<code>REMOTE_REPLY</code> message, but other forms of messaging are
|
||||
also possible.
|
||||
</p>
|
||||
<p>
|
||||
The protocol contains support for multiple program types and protocol
|
||||
versioning, modelled after SunRPC.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,17 +1,21 @@
|
||||
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
schemadir = $(pkgdatadir)/schemas
|
||||
schema_DATA = \
|
||||
basictypes.rng \
|
||||
capability.rng \
|
||||
domain.rng \
|
||||
domaincommon.rng \
|
||||
domainsnapshot.rng \
|
||||
interface.rng \
|
||||
network.rng \
|
||||
networkcommon.rng \
|
||||
nodedev.rng \
|
||||
nwfilter.rng \
|
||||
secret.rng \
|
||||
storageencryption.rng \
|
||||
storagepool.rng \
|
||||
storagevol.rng \
|
||||
nodedev.rng \
|
||||
capability.rng \
|
||||
nwfilter.rng
|
||||
storagevol.rng
|
||||
|
||||
EXTRA_DIST = $(schema_DATA)
|
||||
|
136
docs/schemas/basictypes.rng
Normal file
136
docs/schemas/basictypes.rng
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- network-related definitions used in multiple grammars -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
|
||||
<!-- Our unsignedInt doesn"t allow a leading "+" in its lexical form -->
|
||||
<define name="unsignedInt">
|
||||
<data type="unsignedInt">
|
||||
<param name="pattern">[0-9]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="positiveInteger">
|
||||
<data type="positiveInteger">
|
||||
<param name="pattern">[0-9]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="uint8range">
|
||||
<choice>
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,2}</param>
|
||||
</data>
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
<param name="maxInclusive">255</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
<define name="uint24range">
|
||||
<choice>
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,6}</param>
|
||||
</data>
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
<param name="maxInclusive">16777215</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="UUID">
|
||||
<choice>
|
||||
<data type="string">
|
||||
<param name="pattern">[a-fA-F0-9]{32}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">[a-fA-F0-9]{8}\-([a-fA-F0-9]{4}\-){3}[a-fA-F0-9]{12}</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
|
||||
<define name="macAddr">
|
||||
<data type="string">
|
||||
<param name="pattern">([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<!-- An ipv4 "dotted quad" address -->
|
||||
<define name="ipv4Addr">
|
||||
<data type="string">
|
||||
<param name="pattern">(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<!-- Based on http://blog.mes-stats.fr/2008/10/09/regex-ipv4-et-ipv6 -->
|
||||
<define name="ipv6Addr">
|
||||
<data type="string">
|
||||
<!-- To understand this better, take apart the toplevel "|"s -->
|
||||
<param name="pattern">(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(([0-9A-Fa-f]{1,4}:){0,5}:(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(::([0-9A-Fa-f]{1,4}:){0,5}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="ipAddr">
|
||||
<choice>
|
||||
<ref name="ipv4Addr"/>
|
||||
<ref name="ipv6Addr"/>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="ipv4Prefix">
|
||||
<data type="unsignedInt">
|
||||
<param name="maxInclusive">32</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="ipv6Prefix">
|
||||
<data type="unsignedInt">
|
||||
<param name="maxInclusive">128</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="ipPrefix">
|
||||
<choice>
|
||||
<ref name="ipv4Prefix"/>
|
||||
<ref name="ipv6Prefix"/>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="genericName">
|
||||
<data type="string">
|
||||
<param name="pattern">[a-zA-Z0-9_\+\-]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="dnsName">
|
||||
<data type="string">
|
||||
<param name="pattern">[a-zA-Z0-9\.\-]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="deviceName">
|
||||
<data type="string">
|
||||
<param name="pattern">[a-zA-Z0-9_\.\-\\:/]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="filePath">
|
||||
<data type="string">
|
||||
<param name="pattern">[a-zA-Z0-9_\.\+\-\\&"'<>/%]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="absFilePath">
|
||||
<data type="string">
|
||||
<param name="pattern">/[a-zA-Z0-9_\.\+\-\\&"'<>/%]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="absDirPath">
|
||||
<data type="string">
|
||||
<param name="pattern">/[a-zA-Z0-9_\.\+\-\\&"'<>/%]*</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
</grammar>
|
@ -34,6 +34,9 @@
|
||||
<ref name='cpuspec'/>
|
||||
</optional>
|
||||
</element>
|
||||
<optional>
|
||||
<ref name='power_management'/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name='migration'/>
|
||||
</optional>
|
||||
@ -105,6 +108,28 @@
|
||||
</zeroOrMore>
|
||||
</define>
|
||||
|
||||
<define name='power_management'>
|
||||
<element name='power_management'>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name='suspend_mem'>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='suspend_disk'>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='suspend_hybrid'>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name='migration'>
|
||||
<element name='migration_features'>
|
||||
<optional>
|
||||
@ -302,6 +327,11 @@
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='deviceboot'>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
@ -325,6 +355,8 @@
|
||||
<value>arm</value>
|
||||
<value>i686</value>
|
||||
<value>ia64</value>
|
||||
<value>microblaze</value>
|
||||
<value>microblazeel</value>
|
||||
<value>mips</value>
|
||||
<value>mipsel</value>
|
||||
<value>ppc64</value>
|
||||
|
File diff suppressed because it is too large
Load Diff
2952
docs/schemas/domaincommon.rng
Normal file
2952
docs/schemas/domaincommon.rng
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- A Relax NG schema for the libvirt domain snapshot properties XML format -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
|
||||
<start>
|
||||
<ref name='domainsnapshot'/>
|
||||
</start>
|
||||
|
||||
<include href='domaincommon.rng'/>
|
||||
|
||||
<define name='domainsnapshot'>
|
||||
<element name='domainsnapshot'>
|
||||
<interleave>
|
||||
@ -19,7 +22,7 @@
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='state'>
|
||||
<text/>
|
||||
<ref name='state'/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
@ -28,17 +31,30 @@
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='active'>
|
||||
<text/>
|
||||
<element name='disks'>
|
||||
<zeroOrMore>
|
||||
<ref name='disksnapshot'/>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='domain'>
|
||||
<element name='uuid'>
|
||||
<text/>
|
||||
</element>
|
||||
<element name='active'>
|
||||
<choice>
|
||||
<value>0</value>
|
||||
<value>1</value>
|
||||
</choice>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name='domain'>
|
||||
<element name='uuid'>
|
||||
<ref name="UUID"/>
|
||||
</element>
|
||||
</element>
|
||||
<ref name='domain'/>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='parent'>
|
||||
<element name='name'>
|
||||
@ -50,4 +66,65 @@
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name='state'>
|
||||
<choice>
|
||||
<value>nostate</value>
|
||||
<value>running</value>
|
||||
<value>blocked</value>
|
||||
<value>paused</value>
|
||||
<value>shutdown</value>
|
||||
<value>shutoff</value>
|
||||
<value>crashed</value>
|
||||
<value>disk-snapshot</value>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name='disksnapshot'>
|
||||
<element name='disk'>
|
||||
<attribute name='name'>
|
||||
<choice>
|
||||
<ref name='diskTarget'/>
|
||||
<ref name='absFilePath'/>
|
||||
</choice>
|
||||
</attribute>
|
||||
<choice>
|
||||
<attribute name='snapshot'>
|
||||
<value>no</value>
|
||||
</attribute>
|
||||
<attribute name='snapshot'>
|
||||
<value>internal</value>
|
||||
</attribute>
|
||||
<group>
|
||||
<optional>
|
||||
<attribute name='snapshot'>
|
||||
<value>external</value>
|
||||
</attribute>
|
||||
</optional>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name='driver'>
|
||||
<optional>
|
||||
<attribute name='type'>
|
||||
<ref name='genericName'/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name='source'>
|
||||
<optional>
|
||||
<attribute name='file'>
|
||||
<ref name='absFilePath'/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</group>
|
||||
</choice>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
|
@ -1,3 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- A Relax NG schema for network interfaces -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
|
||||
xmlns:v="http://netcf.org/xml/version/1.0"
|
||||
@ -16,6 +17,7 @@
|
||||
</choice>
|
||||
</start>
|
||||
|
||||
<include href='basictypes.rng'/>
|
||||
<!--
|
||||
FIXME: How do we handle VLAN's ? Should they be their own interface
|
||||
or should we treat them as an option on the base interface ? For
|
||||
@ -36,7 +38,7 @@
|
||||
FIXME: What if device name and MAC don't specify the same NIC ? -->
|
||||
<optional>
|
||||
<element name="mac">
|
||||
<attribute name="address"><ref name="mac-addr"/></attribute>
|
||||
<attribute name="address"><ref name="macAddr"/></attribute>
|
||||
</element>
|
||||
</optional>
|
||||
<!-- FIXME: Allow (some) ethtool options -->
|
||||
@ -75,7 +77,7 @@
|
||||
<element name="vlan">
|
||||
<attribute name="tag"><ref name="vlan-id"/></attribute>
|
||||
<element name="interface">
|
||||
<attribute name="name"><ref name="device-name"/></attribute>
|
||||
<attribute name="name"><ref name="deviceName"/></attribute>
|
||||
</element>
|
||||
</element>
|
||||
</define>
|
||||
@ -202,7 +204,7 @@
|
||||
</element>
|
||||
<element name="arpmon">
|
||||
<attribute name="interval"><ref name="uint"/></attribute>
|
||||
<attribute name="target"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="target"><ref name="ipv4Addr"/></attribute>
|
||||
<optional>
|
||||
<attribute name="validate">
|
||||
<choice>
|
||||
@ -244,7 +246,7 @@
|
||||
<!-- Basic attributes for all interface types -->
|
||||
<define name="name-attr">
|
||||
<!-- The device name, like eth0 or br2 -->
|
||||
<attribute name="name"><ref name="device-name"/></attribute>
|
||||
<attribute name="name"><ref name="deviceName"/></attribute>
|
||||
</define>
|
||||
|
||||
<define name="mtu">
|
||||
@ -303,14 +305,14 @@
|
||||
<ref name="dhcp-element"/>
|
||||
<group>
|
||||
<element name="ip">
|
||||
<attribute name="address"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="address"><ref name="ipv4Addr"/></attribute>
|
||||
<optional>
|
||||
<attribute name="prefix"><ref name="ipv4-prefix"/></attribute>
|
||||
<attribute name="prefix"><ref name="ipv4Prefix"/></attribute>
|
||||
</optional>
|
||||
</element>
|
||||
<optional>
|
||||
<element name="route">
|
||||
<attribute name="gateway"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="gateway"><ref name="ipv4Addr"/></attribute>
|
||||
</element>
|
||||
</optional>
|
||||
</group>
|
||||
@ -331,15 +333,15 @@
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<element name="ip">
|
||||
<attribute name="address"><ref name="ipv6-addr"/></attribute>
|
||||
<attribute name="address"><ref name="ipv6Addr"/></attribute>
|
||||
<optional>
|
||||
<attribute name="prefix"><ref name="ipv6-prefix"/></attribute>
|
||||
<attribute name="prefix"><ref name="ipv6Prefix"/></attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<element name="route">
|
||||
<attribute name="gateway"><ref name="ipv6-addr"/></attribute>
|
||||
<attribute name="gateway"><ref name="ipv6Addr"/></attribute>
|
||||
</element>
|
||||
</optional>
|
||||
</element>
|
||||
@ -417,55 +419,6 @@
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='device-name'>
|
||||
<data type='string'>
|
||||
<param name="pattern">[a-zA-Z0-9_\.\-:/]+</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='UUID'>
|
||||
<choice>
|
||||
<data type='string'>
|
||||
<param name="pattern">[a-fA-F0-9]{32}</param>
|
||||
</data>
|
||||
<data type='string'>
|
||||
<param name="pattern">[a-fA-F0-9]{8}\-([a-fA-F0-9]{4}\-){3}[a-fA-F0-9]{12}</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name='mac-addr'>
|
||||
<data type='string'>
|
||||
<param name="pattern">([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='ipv4-addr'>
|
||||
<data type='string'>
|
||||
<param name="pattern">(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='ipv4-prefix'>
|
||||
<data type='unsignedInt'>
|
||||
<param name="maxInclusive">32</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<!-- Based on http://blog.mes-stats.fr/2008/10/09/regex-ipv4-et-ipv6 -->
|
||||
<define name='ipv6-addr'>
|
||||
<data type='string'>
|
||||
<!-- To understand this better, take apart the toplevel '|'s -->
|
||||
<param name="pattern">(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((((25[0-5])|(1[0-9]{2})|(2[0-4][0-9])|([0-9]{1,2})))\.){3}(((25[0-5])|(1[0-9]{2})|(2[0-4][0-9])|([0-9]{1,2}))))|(([0-9A-Fa-f]{1,4}:){0,5}:((((25[0-5])|(1[0-9]{2})|(2[0-4][0-9])|([0-9]{1,2})))\.){3}(((25[0-5])|(1[0-9]{2})|(2[0-4][0-9])|([0-9]{1,2}))))|(::([0-9A-Fa-f]{1,4}:){0,5}((((25[0-5])|(1[0-9]{2})|(2[0-4][0-9])|([0-9]{1,2})))\.){3}(((25[0-5])|(1[0-9]{2})|(2[0-4][0-9])|([0-9]{1,2}))))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='ipv6-prefix'>
|
||||
<data type='unsignedInt'>
|
||||
<param name="maxInclusive">128</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='vlan-id'>
|
||||
<data type="unsignedInt">
|
||||
<param name="maxInclusive">4096</param>
|
||||
|
@ -1,3 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- A Relax NG schema for the libvirt network XML format -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
|
||||
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
@ -5,6 +6,9 @@
|
||||
<ref name="network"/>
|
||||
</start>
|
||||
|
||||
<include href='basictypes.rng'/>
|
||||
<include href='networkcommon.rng'/>
|
||||
|
||||
<define name="network">
|
||||
|
||||
<element name="network">
|
||||
@ -18,7 +22,7 @@
|
||||
|
||||
<!-- <uuid> element -->
|
||||
<optional>
|
||||
<element name="uuid"><text/></element>
|
||||
<element name="uuid"><ref name="UUID"/></element>
|
||||
</optional>
|
||||
|
||||
<!-- <bridge> element -->
|
||||
@ -28,7 +32,7 @@
|
||||
<element name="bridge">
|
||||
<optional>
|
||||
<attribute name="name">
|
||||
<text/>
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
|
||||
@ -53,7 +57,7 @@
|
||||
<!-- <mac> element -->
|
||||
<optional>
|
||||
<element name="mac">
|
||||
<attribute name="address"><ref name="mac-addr"/></attribute>
|
||||
<attribute name="address"><ref name="macAddr"/></attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
@ -65,7 +69,7 @@
|
||||
<element name="forward">
|
||||
<optional>
|
||||
<attribute name="dev">
|
||||
<text/>
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
|
||||
@ -74,16 +78,52 @@
|
||||
<choice>
|
||||
<value>nat</value>
|
||||
<value>route</value>
|
||||
<value>bridge</value>
|
||||
<value>passthrough</value>
|
||||
<value>private</value>
|
||||
<value>vepa</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<element name='interface'>
|
||||
<attribute name='dev'>
|
||||
<ref name='deviceName'/>
|
||||
</attribute>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
<!-- <virtualport> element -->
|
||||
<optional>
|
||||
<ref name="virtualPortProfile"/>
|
||||
</optional>
|
||||
|
||||
<!-- <portgroup> elements -->
|
||||
<zeroOrMore>
|
||||
<element name="portgroup">
|
||||
<attribute name="name">
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="default">
|
||||
<choice>
|
||||
<value>yes</value>
|
||||
<value>no</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="virtualPortProfile"/>
|
||||
</optional>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
|
||||
<!-- <domain> element -->
|
||||
<optional>
|
||||
<element name="domain">
|
||||
<attribute name="name"><text/></attribute>
|
||||
<attribute name="name"><ref name="dnsName"/></attribute>
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
@ -93,20 +133,47 @@
|
||||
<element name="dns">
|
||||
<zeroOrMore>
|
||||
<element name="txt">
|
||||
<attribute name="name"><ref name="dns-name"/></attribute>
|
||||
<attribute name="name"><ref name="dnsName"/></attribute>
|
||||
<attribute name="value"><text/></attribute>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<element name="srv">
|
||||
<attribute name="service"><text/></attribute>
|
||||
<attribute name="protocol"><ref name="protocol"/></attribute>
|
||||
<optional>
|
||||
<attribute name="domain"><ref name="dnsName"/></attribute>
|
||||
<attribute name="target"><text/></attribute>
|
||||
<attribute name="port"><ref name="unsignedShort"/></attribute>
|
||||
<attribute name="priority"><ref name="unsignedShort"/></attribute>
|
||||
<attribute name="weight"><ref name="unsignedShort"/></attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<element name="host">
|
||||
<attribute name="ip"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="ip"><ref name="ipv4Addr"/></attribute>
|
||||
<oneOrMore>
|
||||
<element name="hostname"><text/></element>
|
||||
<element name="hostname"><ref name="dnsName"/></element>
|
||||
</oneOrMore>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="bandwidth"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="link">
|
||||
<attribute name="state">
|
||||
<choice>
|
||||
<value>up</value>
|
||||
<value>down</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
<!-- <ip> element -->
|
||||
<zeroOrMore>
|
||||
@ -114,12 +181,12 @@
|
||||
local to the host. -->
|
||||
<element name="ip">
|
||||
<optional>
|
||||
<attribute name="address"><ref name="ip-addr"/></attribute>
|
||||
<attribute name="address"><ref name="ipAddr"/></attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<attribute name="netmask"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="prefix"><ref name="ip-prefix"/></attribute>
|
||||
<attribute name="netmask"><ref name="ipv4Addr"/></attribute>
|
||||
<attribute name="prefix"><ref name="ipPrefix"/></attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
@ -136,22 +203,22 @@
|
||||
<element name="dhcp">
|
||||
<zeroOrMore>
|
||||
<element name="range">
|
||||
<attribute name="start"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="end"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="start"><ref name="ipv4Addr"/></attribute>
|
||||
<attribute name="end"><ref name="ipv4Addr"/></attribute>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<element name="host">
|
||||
<attribute name="mac"><ref name="mac-addr"/></attribute>
|
||||
<attribute name="mac"><ref name="macAddr"/></attribute>
|
||||
<attribute name="name"><text/></attribute>
|
||||
<attribute name="ip"><ref name="ipv4-addr"/></attribute>
|
||||
<attribute name="ip"><ref name="ipv4Addr"/></attribute>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<element name="bootp">
|
||||
<attribute name="file"><text/></attribute>
|
||||
<attribute name="file"><ref name="filePath"/></attribute>
|
||||
<optional>
|
||||
<attribute name="server"><text/></attribute>
|
||||
<attribute name="server"><ref name="dnsName"/></attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</optional>
|
||||
@ -162,53 +229,4 @@
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<!-- An ipv4 "dotted quad" address -->
|
||||
<define name='ipv4-addr'>
|
||||
<data type='string'>
|
||||
<param name="pattern">(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<!-- Based on http://blog.mes-stats.fr/2008/10/09/regex-ipv4-et-ipv6 -->
|
||||
<define name='ipv6-addr'>
|
||||
<data type='string'>
|
||||
<!-- To understand this better, take apart the toplevel '|'s -->
|
||||
<param name="pattern">(([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(([0-9A-Fa-f]{1,4}:){0,5}:(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|(::([0-9A-Fa-f]{1,4}:){0,5}(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9])|([0-9])))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='ip-addr'>
|
||||
<choice>
|
||||
<ref name='ipv4-addr'/>
|
||||
<ref name='ipv6-addr'/>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name='ip-prefix'>
|
||||
<data type='unsignedInt'>
|
||||
<param name="maxInclusive">128</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='addr-family'>
|
||||
<data type='string'>
|
||||
<param name="pattern">(ipv4)|(ipv6)</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
|
||||
<define name='mac-addr'>
|
||||
<data type='string'>
|
||||
<param name="pattern">([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<!-- a valid DNS name -->
|
||||
<define name='dns-name'>
|
||||
<data type='string'>
|
||||
<param name="pattern">([a-zA-Z\-]+)</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
|
115
docs/schemas/networkcommon.rng
Normal file
115
docs/schemas/networkcommon.rng
Normal file
@ -0,0 +1,115 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- network-related definitions used in multiple grammars -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
|
||||
<define name="virtualPortProfileID">
|
||||
<data type="string">
|
||||
<param name="maxLength">39</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name="virtualPortProfile">
|
||||
<choice>
|
||||
<group>
|
||||
<element name="virtualport">
|
||||
<attribute name="type">
|
||||
<value>802.1Qbg</value>
|
||||
</attribute>
|
||||
<element name="parameters">
|
||||
<attribute name="managerid">
|
||||
<ref name="uint8range"/>
|
||||
</attribute>
|
||||
<attribute name="typeid">
|
||||
<ref name="uint24range"/>
|
||||
</attribute>
|
||||
<attribute name="typeidversion">
|
||||
<ref name="uint8range"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="instanceid">
|
||||
<ref name="UUID"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</element>
|
||||
</group>
|
||||
<group>
|
||||
<element name="virtualport">
|
||||
<attribute name="type">
|
||||
<value>802.1Qbh</value>
|
||||
</attribute>
|
||||
<element name="parameters">
|
||||
<attribute name="profileid">
|
||||
<ref name="virtualPortProfileID"/>
|
||||
</attribute>
|
||||
</element>
|
||||
</element>
|
||||
</group>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="bandwidth">
|
||||
<element name="bandwidth">
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="inbound">
|
||||
<ref name="bandwidth-attributes"/>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="outbound">
|
||||
<ref name="bandwidth-attributes"/>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="bandwidth-attributes">
|
||||
<attribute name="average">
|
||||
<ref name="speed"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="peak">
|
||||
<ref name="speed"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name='burst'>
|
||||
<ref name="BurstSize"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
|
||||
<define name="speed">
|
||||
<data type="unsignedInt">
|
||||
<param name="pattern">[0-9]+</param>
|
||||
<param name="minInclusive">1</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name="BurstSize">
|
||||
<data type="unsignedInt">
|
||||
<param name="pattern">[0-9]+</param>
|
||||
<param name="minInclusive">1</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='unsignedShort'>
|
||||
<data type='integer'>
|
||||
<param name="minInclusive">0</param>
|
||||
<param name="maxInclusive">65535</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name='protocol'>
|
||||
<data type='string'>
|
||||
<param name='pattern'>(tcp)|(udp)</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name='addr-family'>
|
||||
<data type='string'>
|
||||
<param name="pattern">(ipv4)|(ipv6)</param>
|
||||
</data>
|
||||
</define>
|
||||
</grammar>
|
@ -216,6 +216,35 @@
|
||||
</attribute>
|
||||
</define>
|
||||
|
||||
<define name='wwn'>
|
||||
<data type='string'>
|
||||
<param name='pattern'>(0-9a-fA-F){16}</param>
|
||||
</data>
|
||||
</define>
|
||||
|
||||
<define name='capsfchost'>
|
||||
<attribute name='type'>
|
||||
<value>fc_host</value>
|
||||
</attribute>
|
||||
|
||||
<element name='wwnn'>
|
||||
<ref name='wwn'/>
|
||||
</element>
|
||||
|
||||
<element name='wwpn'>
|
||||
<ref name='wwn'/>
|
||||
</element>
|
||||
|
||||
<element name='fabric_wwn'>
|
||||
<ref name='wwn'/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name='capsvports'>
|
||||
<attribute name='type'>
|
||||
<value>vports_ops</value>
|
||||
</attribute>
|
||||
</define>
|
||||
|
||||
<define name='capscsihost'>
|
||||
<attribute name='type'>
|
||||
@ -225,6 +254,17 @@
|
||||
<element name='host'>
|
||||
<ref name='uint'/>
|
||||
</element>
|
||||
|
||||
<optional>
|
||||
<zeroOrMore>
|
||||
<element name='capability'>
|
||||
<choice>
|
||||
<ref name='capsfchost'/>
|
||||
<ref name='capsvports'/>
|
||||
</choice>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</optional>
|
||||
</define>
|
||||
|
||||
<define name='capscsi'>
|
||||
|
@ -28,6 +28,26 @@
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</optional>
|
||||
<optional>
|
||||
<zeroOrMore>
|
||||
<element name="vlan">
|
||||
<ref name="match-attribute"/>
|
||||
<ref name="common-l2-attributes"/>
|
||||
<ref name="vlan-attributes"/>
|
||||
<ref name="comment-attribute"/>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</optional>
|
||||
<optional>
|
||||
<zeroOrMore>
|
||||
<element name="stp">
|
||||
<ref name="match-attribute"/>
|
||||
<ref name="srcmacandmask-attributes"/>
|
||||
<ref name="stp-attributes"/>
|
||||
<ref name="comment-attribute"/>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</optional>
|
||||
<optional>
|
||||
<zeroOrMore>
|
||||
<element name="arp">
|
||||
@ -286,20 +306,42 @@
|
||||
<attribute name="chain">
|
||||
<choice>
|
||||
<value>root</value>
|
||||
<value>arp</value>
|
||||
<value>rarp</value>
|
||||
<value>ipv4</value>
|
||||
<value>ipv6</value>
|
||||
<data type="string">
|
||||
<param name="pattern">mac[a-zA-Z0-9_\.:-]{0,9}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">stp[a-zA-Z0-9_\.:-]{0,9}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">vlan[a-zA-Z0-9_\.:-]{0,8}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">arp[a-zA-Z0-9_\.:-]{0,9}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">rarp[a-zA-Z0-9_\.:-]{0,8}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">ipv4[a-zA-Z0-9_\.:-]{0,8}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">ipv6[a-zA-Z0-9_\.:-]{0,8}</param>
|
||||
</data>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="priority">
|
||||
<ref name='priority-type'/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
|
||||
<define name="filterref-node-attributes">
|
||||
<attribute name="filter">
|
||||
<data type="NCName"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<zeroOrMore>
|
||||
<element name="parameter">
|
||||
<attribute name="name">
|
||||
<ref name="filter-param-name"/>
|
||||
@ -308,7 +350,7 @@
|
||||
<ref name="filter-param-value"/>
|
||||
</attribute>
|
||||
</element>
|
||||
</optional>
|
||||
</zeroOrMore>
|
||||
</define>
|
||||
|
||||
<define name="rule-node-attributes">
|
||||
@ -353,7 +395,7 @@
|
||||
</interleave>
|
||||
</define>
|
||||
|
||||
<define name="common-l2-attributes">
|
||||
<define name="srcmacandmask-attributes">
|
||||
<interleave>
|
||||
<ref name="srcmac-attribute"/>
|
||||
<optional>
|
||||
@ -361,6 +403,12 @@
|
||||
<ref name="addrMAC"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</interleave>
|
||||
</define>
|
||||
|
||||
<define name="common-l2-attributes">
|
||||
<interleave>
|
||||
<ref name="srcmacandmask-attributes"/>
|
||||
<optional>
|
||||
<attribute name="dstmacaddr">
|
||||
<ref name="addrMAC"/>
|
||||
@ -544,6 +592,134 @@
|
||||
</interleave>
|
||||
</define>
|
||||
|
||||
<define name="vlan-attributes">
|
||||
<interleave>
|
||||
<optional>
|
||||
<attribute name="vlanid">
|
||||
<ref name="vlan-vlanid"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="encap-protocol">
|
||||
<ref name="mac-protocolid"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</interleave>
|
||||
</define>
|
||||
|
||||
<define name="stp-attributes">
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<ref name="uint8range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="flags">
|
||||
<ref name="uint8range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="root-priority">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="root-priority-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="root-address">
|
||||
<ref name="addrMAC"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="root-address-mask">
|
||||
<ref name="addrMAC"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="root-cost">
|
||||
<ref name="uint32range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="root-cost-hi">
|
||||
<ref name="uint32range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="sender-priority">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="sender-priority-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="sender-address">
|
||||
<ref name="addrMAC"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="sender-address-mask">
|
||||
<ref name="addrMAC"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="port">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="port-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="age">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="age-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="max-age">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="max-age-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="hello-time">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="hello-time-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="forward-delay">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="forward-delay-hi">
|
||||
<ref name="uint16range"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
|
||||
<define name="arp-attributes">
|
||||
<interleave>
|
||||
<optional>
|
||||
@ -749,10 +925,29 @@
|
||||
<value>rarp</value>
|
||||
<value>ipv4</value>
|
||||
<value>ipv6</value>
|
||||
<value>vlan</value>
|
||||
</choice>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="vlan-vlanid">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x([0-9a-fA-F]{1,3})</param>
|
||||
</data>
|
||||
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
<param name="maxInclusive">4095</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="uint8range">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
@ -789,6 +984,24 @@
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="uint32range">
|
||||
<choice>
|
||||
<!-- variable -->
|
||||
<data type="string">
|
||||
<param name="pattern">$[a-zA-Z0-9_]+</param>
|
||||
</data>
|
||||
|
||||
<data type="string">
|
||||
<param name="pattern">0x[0-9a-fA-F]{1,8}</param>
|
||||
</data>
|
||||
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
<param name="maxInclusive">4294967295</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="boolean">
|
||||
<choice>
|
||||
<value>yes</value>
|
||||
@ -866,6 +1079,8 @@
|
||||
<value>drop</value>
|
||||
<value>accept</value>
|
||||
<value>reject</value>
|
||||
<value>continue</value>
|
||||
<value>return</value>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
@ -879,7 +1094,7 @@
|
||||
|
||||
<define name='priority-type'>
|
||||
<data type="int">
|
||||
<param name="minInclusive">0</param>
|
||||
<param name="minInclusive">-1000</param>
|
||||
<param name="maxInclusive">1000</param>
|
||||
</data>
|
||||
</define>
|
||||
|
@ -1,9 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- A Relax NG schema for the libvirt secret properties XML format -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
|
||||
<start>
|
||||
<ref name='secret'/>
|
||||
</start>
|
||||
|
||||
<include href='basictypes.rng'/>
|
||||
|
||||
<define name='secret'>
|
||||
<element name='secret'>
|
||||
<optional>
|
||||
@ -37,6 +40,7 @@
|
||||
<element name='usage'>
|
||||
<choice>
|
||||
<ref name='usagevolume'/>
|
||||
<ref name='usageceph'/>
|
||||
<!-- More choices later -->
|
||||
</choice>
|
||||
</element>
|
||||
@ -54,21 +58,13 @@
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="UUID">
|
||||
<choice>
|
||||
<data type="string">
|
||||
<param name="pattern">[a-fA-F0-9]{32}</param>
|
||||
</data>
|
||||
<data type="string">
|
||||
<param name="pattern">[a-fA-F0-9]{8}\-([a-fA-F0-9]{4}\-){3}[a-fA-F0-9]{12}</param>
|
||||
</data>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
<define name="absFilePath">
|
||||
<data type="string">
|
||||
<param name="pattern">/[a-zA-Z0-9_\.\+\-&/%]+</param>
|
||||
</data>
|
||||
<define name='usageceph'>
|
||||
<attribute name='type'>
|
||||
<value>ceph</value>
|
||||
</attribute>
|
||||
<element name='name'>
|
||||
<ref name='genericName'/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
|
@ -60,6 +60,10 @@
|
||||
<a href="auth.html">Authentication</a>
|
||||
<span>Configure authentication for the libvirt daemon</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="migration.html">Migration</a>
|
||||
<span>Migrating guests between machines</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="windows.html">Windows port</a>
|
||||
<span>Access the libvirt daemon from a native Windows client</span>
|
||||
@ -202,6 +206,10 @@
|
||||
<a href="drvvmware.html">VMware Workstation / Player</a>
|
||||
<span>Driver for VMware Workstation / Player</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="drvhyperv.html">Microsoft Hyper-V</a>
|
||||
<span>Driver for Microsoft Hyper-V</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
@ -288,6 +296,10 @@
|
||||
<a href="internals/command.html">Spawning commands</a>
|
||||
<span>Spawning commands from libvirt driver code</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="internals/rpc.html">RPC protocol & APIs</a>
|
||||
<span>RPC protocol information and API / dispatch guide</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="internals/locking.html">Lock managers</a>
|
||||
<span>Use lock managers to protect disk content</span>
|
||||
|
@ -2,7 +2,7 @@
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
|
@ -47,6 +47,8 @@ my $trackers = BZ::Client::Bug->search($client, {'product' => $product,
|
||||
my @trackers;
|
||||
|
||||
foreach my $tracker (@{$trackers}) {
|
||||
next if $tracker->{'bug_status'} eq "CLOSED";
|
||||
|
||||
my $summary = $tracker->{'short_desc'};
|
||||
$summary =~ s/^\s*RFE\s*:\s*//;
|
||||
$summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
|
||||
@ -64,6 +66,8 @@ foreach my $tracker (@trackers) {
|
||||
'blocked' => $tracker->{id}});
|
||||
|
||||
foreach my $feature (@{$features}) {
|
||||
next if $feature->{'bug_status'} eq "CLOSED";
|
||||
|
||||
my $summary = $feature->{'short_desc'};
|
||||
$summary =~ s/^\s*RFE\s*:\s*//;
|
||||
$summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
|
||||
|
103
docs/uri.html.in
103
docs/uri.html.in
@ -2,6 +2,8 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1 >Connection URIs</h1>
|
||||
|
||||
<ul id="toc"></ul>
|
||||
<p>
|
||||
Since libvirt supports many different kinds of virtualization
|
||||
(often referred to as "drivers" or "hypervisors"), we need a
|
||||
@ -13,41 +15,46 @@ machine over the network.
|
||||
To this end, libvirt uses URIs as used on the Web and as defined in <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>. This page
|
||||
documents libvirt URIs.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#URI_libvirt">Specifying URIs to libvirt</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#URI_virsh">Specifying URIs to virsh, virt-manager and virt-install</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#URI_xen">xen:/// URI</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#URI_qemu">qemu:///... QEMU and KVM URIs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#URI_remote">Remote URIs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#URI_test">test:///... Test URIs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#URI_legacy">Other & legacy URI formats</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a name="URI_libvirt">Specifying URIs to libvirt</a>
|
||||
</h3>
|
||||
<h2><a name="URI_libvirt">Specifying URIs to libvirt</a></h2>
|
||||
|
||||
<p>
|
||||
The URI is passed as the <code>name</code> parameter to <a href="html/libvirt-libvirt.html#virConnectOpen"><code>virConnectOpen</code></a> or <a href="html/libvirt-libvirt.html#virConnectOpenReadOnly"><code>virConnectOpenReadOnly</code></a>. For example:
|
||||
</p>
|
||||
<pre>
|
||||
virConnectPtr conn = virConnectOpenReadOnly (<b>"test:///default"</b>);
|
||||
</pre>
|
||||
<h3>
|
||||
<h2>
|
||||
<a name="URI_config">Configuring URI aliases</a>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
To simplify life for administrators, it is possible to setup URI aliases in a
|
||||
libvirt client configuration file. The configuration file is <code>/etc/libvirt/libvirt.conf</code>
|
||||
for the root user, or <code>$HOME/.libvirt/libvirt.conf</code> for any unprivileged user.
|
||||
In this file, the following syntax can be used to setup aliases
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
uri_aliases = [
|
||||
"hail=qemu+ssh://root@hail.cloud.example.com/system",
|
||||
"sleet=qemu+ssh://root@sleet.cloud.example.com/system",
|
||||
]
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
A URI alias should be a string made up from the characters
|
||||
<code>a-Z, 0-9, _, -</code>. Following the <code>=</code>
|
||||
can be any libvirt URI string, including arbitrary URI parameters.
|
||||
URI aliases will apply to any application opening a libvirt
|
||||
connection, unless it has explicitly passed the <code>VIR_CONNECT_NO_ALIASES</code>
|
||||
parameter to <code>virConnectOpenAuth</code>. If the passed in
|
||||
URI contains characters outside the allowed alias character
|
||||
set, no alias lookup will be attempted.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
<a name="URI_virsh">Specifying URIs to virsh, virt-manager and virt-install</a>
|
||||
</h3>
|
||||
</h2>
|
||||
<p>
|
||||
In virsh use the <code>-c</code> or <code>--connect</code> option:
|
||||
</p>
|
||||
@ -76,9 +83,9 @@ In virt-install use the <code>--connect=</code><i>URI</i> option:
|
||||
<pre>
|
||||
virt-install <b>--connect=test:///default</b> <i>[other options]</i>
|
||||
</pre>
|
||||
<h3>
|
||||
<h2>
|
||||
<a name="URI_xen">xen:/// URI</a>
|
||||
</h3>
|
||||
</h2>
|
||||
<p>
|
||||
<i>This section describes a feature which is new in libvirt >
|
||||
0.2.3. For libvirt ≤ 0.2.3 use <a href="#URI_legacy_xen"><code>"xen"</code></a>.</i>
|
||||
@ -87,9 +94,9 @@ virt-install <b>--connect=test:///default</b> <i>[other options]</i>
|
||||
To access a Xen hypervisor running on the local machine
|
||||
use the URI <code>xen:///</code>.
|
||||
</p>
|
||||
<h3>
|
||||
<h2>
|
||||
<a name="URI_qemu">qemu:///... QEMU and KVM URIs</a>
|
||||
</h3>
|
||||
</h2>
|
||||
<p>
|
||||
To use QEMU support in libvirt you must be running the
|
||||
<code>libvirtd</code> daemon (named <code>libvirt_qemud</code>
|
||||
@ -119,9 +126,9 @@ KVM URIs are identical. You select between qemu, qemu accelerated and
|
||||
KVM guests in the <a href="format.html#KVM1">guest XML as described
|
||||
here</a>.
|
||||
</p>
|
||||
<h3>
|
||||
<h2>
|
||||
<a name="URI_remote">Remote URIs</a>
|
||||
</h3>
|
||||
</h2>
|
||||
<p>
|
||||
Remote URIs are formed by taking ordinary local URIs and adding a
|
||||
hostname and/or transport name. As a special case, using a URI
|
||||
@ -182,9 +189,9 @@ We refer you to <a href="remote.html#Remote_URI_reference">the libvirt
|
||||
remote URI reference</a> and <a href="remote.html">full documentation
|
||||
for libvirt remote support</a>.
|
||||
</p>
|
||||
<h3>
|
||||
<h2>
|
||||
<a name="URI_test">test:///... Test URIs</a>
|
||||
</h3>
|
||||
</h2>
|
||||
<p>
|
||||
The test driver is a dummy hypervisor for test purposes.
|
||||
The URIs supported are:
|
||||
@ -196,12 +203,12 @@ host definitions built into the driver. </li>
|
||||
a set of host definitions held in the named file.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<h2>
|
||||
<a name="URI_legacy">Other & legacy URI formats</a>
|
||||
</h3>
|
||||
<h4>
|
||||
</h2>
|
||||
<h3>
|
||||
<a name="URI_NULL">NULL and empty string URIs</a>
|
||||
</h4>
|
||||
</h3>
|
||||
<p>
|
||||
Libvirt allows you to pass a <code>NULL</code> pointer to
|
||||
<code>virConnectOpen*</code>. Empty string (<code>""</code>) acts in
|
||||
@ -223,9 +230,9 @@ the user to type a URI in directly (if that is appropriate). If your
|
||||
application wishes to connect specifically to a Xen hypervisor, then
|
||||
for future proofing it should choose a full <a href="#URI_xen"><code>xen:///</code> URI</a>.
|
||||
</p>
|
||||
<h4>
|
||||
<h3>
|
||||
<a name="URI_file">File paths (xend-unix-server)</a>
|
||||
</h4>
|
||||
</h3>
|
||||
<p>
|
||||
If XenD is running and configured in <code>/etc/xen/xend-config.sxp</code>:
|
||||
</p>
|
||||
@ -240,9 +247,9 @@ using a file URI such as:
|
||||
<pre>
|
||||
virsh -c ///var/run/xend/xend-socket
|
||||
</pre>
|
||||
<h4>
|
||||
<h3>
|
||||
<a name="URI_http">Legacy: <code>http://...</code> (xend-http-server)</a>
|
||||
</h4>
|
||||
</h3>
|
||||
<p>
|
||||
If XenD is running and configured in <code>/etc/xen/xend-config.sxp</code>:
|
||||
|
||||
@ -276,17 +283,17 @@ Notes:
|
||||
libvirt, only the old-style sexpr interface known in the Xen
|
||||
documentation as "unix server" or "http server".</li>
|
||||
</ol>
|
||||
<h4>
|
||||
<h3>
|
||||
<a name="URI_legacy_xen">Legacy: <code>"xen"</code></a>
|
||||
</h4>
|
||||
</h3>
|
||||
<p>
|
||||
Another legacy URI is to specify name as the string
|
||||
<code>"xen"</code>. This will continue to refer to the Xen
|
||||
hypervisor. However you should prefer a full <a href="#URI_xen"><code>xen:///</code> URI</a> in all future code.
|
||||
</p>
|
||||
<h4>
|
||||
<h3>
|
||||
<a name="URI_legacy_proxy">Legacy: Xen proxy</a>
|
||||
</h4>
|
||||
</h3>
|
||||
<p>
|
||||
Libvirt continues to support connections to a separately running Xen
|
||||
proxy daemon. This provides a way to allow non-root users to make a
|
||||
|
@ -1,3 +1,6 @@
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
EXTRA_DIST= \
|
||||
TEMPLATE \
|
||||
libvirt-qemu \
|
||||
|
@ -27,9 +27,9 @@
|
||||
# but may constitute a security risk. If your environment does not require
|
||||
# the use of sound in your VMs, feel free to comment out or prepend 'deny' to
|
||||
# the rules for files in /dev.
|
||||
/dev/shm/ r,
|
||||
/dev/shm/pulse-shm* r,
|
||||
/dev/shm/pulse-shm* rwk,
|
||||
/{dev,run}/shm r,
|
||||
/{dev,run}/shmpulse-shm* r,
|
||||
/{dev,run}/shmpulse-shm* rwk,
|
||||
/dev/snd/* rw,
|
||||
capability ipc_lock,
|
||||
# 'kill' is not required for sound and is a security risk. Do not enable
|
||||
@ -69,6 +69,8 @@
|
||||
/usr/bin/qemu-system-cris rmix,
|
||||
/usr/bin/qemu-system-i386 rmix,
|
||||
/usr/bin/qemu-system-m68k rmix,
|
||||
/usr/bin/qemu-system-microblaze rmix,
|
||||
/usr/bin/qemu-system-microblazeel rmix,
|
||||
/usr/bin/qemu-system-mips rmix,
|
||||
/usr/bin/qemu-system-mips64 rmix,
|
||||
/usr/bin/qemu-system-mips64el rmix,
|
||||
@ -87,6 +89,8 @@
|
||||
/usr/bin/qemu-cris rmix,
|
||||
/usr/bin/qemu-i386 rmix,
|
||||
/usr/bin/qemu-m68k rmix,
|
||||
/usr/bin/qemu-microblaze rmix,
|
||||
/usr/bin/qemu-microblazeel rmix,
|
||||
/usr/bin/qemu-mips rmix,
|
||||
/usr/bin/qemu-mipsel rmix,
|
||||
/usr/bin/qemu-ppc rmix,
|
||||
|
@ -1,3 +1,6 @@
|
||||
## Copyright (C) 2005-2011 Red Hat, Inc.
|
||||
## See COPYING.LIB for the License of this software
|
||||
|
||||
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib
|
||||
noinst_PROGRAMS = event-test
|
||||
|
@ -40,7 +40,7 @@ void usage(const char *pname);
|
||||
|
||||
const char *eventToString(int event) {
|
||||
const char *ret = "";
|
||||
switch(event) {
|
||||
switch ((virDomainEventType) event) {
|
||||
case VIR_DOMAIN_EVENT_DEFINED:
|
||||
ret ="Defined";
|
||||
break;
|
||||
@ -59,13 +59,16 @@ const char *eventToString(int event) {
|
||||
case VIR_DOMAIN_EVENT_STOPPED:
|
||||
ret ="Stopped";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SHUTDOWN:
|
||||
ret = "Shutdown";
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *eventDetailToString(int event, int detail) {
|
||||
const char *ret = "";
|
||||
switch(event) {
|
||||
switch ((virDomainEventType) event) {
|
||||
case VIR_DOMAIN_EVENT_DEFINED:
|
||||
if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED)
|
||||
ret = "Added";
|
||||
@ -77,7 +80,7 @@ static const char *eventDetailToString(int event, int detail) {
|
||||
ret = "Removed";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_STARTED:
|
||||
switch (detail) {
|
||||
switch ((virDomainEventStartedDetailType) detail) {
|
||||
case VIR_DOMAIN_EVENT_STARTED_BOOTED:
|
||||
ret = "Booted";
|
||||
break;
|
||||
@ -87,22 +90,48 @@ static const char *eventDetailToString(int event, int detail) {
|
||||
case VIR_DOMAIN_EVENT_STARTED_RESTORED:
|
||||
ret = "Restored";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT:
|
||||
ret = "Snapshot";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED:
|
||||
if (detail == VIR_DOMAIN_EVENT_SUSPENDED_PAUSED)
|
||||
switch ((virDomainEventSuspendedDetailType) detail) {
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED_PAUSED:
|
||||
ret = "Paused";
|
||||
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED)
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED:
|
||||
ret = "Migrated";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED_IOERROR:
|
||||
ret = "I/O Error";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG:
|
||||
ret = "Watchdog";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED_RESTORED:
|
||||
ret = "Restored";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT:
|
||||
ret = "Snapshot";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_RESUMED:
|
||||
if (detail == VIR_DOMAIN_EVENT_RESUMED_UNPAUSED)
|
||||
switch ((virDomainEventResumedDetailType) detail) {
|
||||
case VIR_DOMAIN_EVENT_RESUMED_UNPAUSED:
|
||||
ret = "Unpaused";
|
||||
else if (detail == VIR_DOMAIN_EVENT_RESUMED_MIGRATED)
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_RESUMED_MIGRATED:
|
||||
ret = "Migrated";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT:
|
||||
ret = "Snapshot";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_STOPPED:
|
||||
switch (detail) {
|
||||
switch ((virDomainEventStoppedDetailType) detail) {
|
||||
case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN:
|
||||
ret = "Shutdown";
|
||||
break;
|
||||
@ -121,6 +150,16 @@ static const char *eventDetailToString(int event, int detail) {
|
||||
case VIR_DOMAIN_EVENT_STOPPED_FAILED:
|
||||
ret = "Failed";
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT:
|
||||
ret = "Snapshot";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_EVENT_SHUTDOWN:
|
||||
switch ((virDomainEventShutdownDetailType) detail) {
|
||||
case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED:
|
||||
ret = "Finished";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -256,6 +295,25 @@ static int myDomainEventControlErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED
|
||||
}
|
||||
|
||||
|
||||
const char *diskChangeReasonStrings[] = {
|
||||
"startupPolicy", /* 0 */
|
||||
/* add new reason here */
|
||||
};
|
||||
static int myDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
const char *oldSrcPath,
|
||||
const char *newSrcPath,
|
||||
const char *devAlias,
|
||||
int reason,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
printf("%s EVENT: Domain %s(%d) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s\n",
|
||||
__func__, virDomainGetName(dom), virDomainGetID(dom),
|
||||
oldSrcPath, newSrcPath, devAlias, diskChangeReasonStrings[reason]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void myFreeFunc(void *opaque)
|
||||
{
|
||||
char *str = opaque;
|
||||
@ -290,6 +348,7 @@ int main(int argc, char **argv)
|
||||
int callback6ret = -1;
|
||||
int callback7ret = -1;
|
||||
int callback8ret = -1;
|
||||
int callback9ret = -1;
|
||||
struct sigaction action_stop;
|
||||
|
||||
memset(&action_stop, 0, sizeof action_stop);
|
||||
@ -304,7 +363,9 @@ int main(int argc, char **argv)
|
||||
virEventRegisterDefaultImpl();
|
||||
|
||||
virConnectPtr dconn = NULL;
|
||||
dconn = virConnectOpenReadOnly (argv[1] ? argv[1] : NULL);
|
||||
dconn = virConnectOpenAuth(argc > 1 ? argv[1] : NULL,
|
||||
virConnectAuthPtrDefault,
|
||||
VIR_CONNECT_RO);
|
||||
if (!dconn) {
|
||||
printf("error opening\n");
|
||||
return -1;
|
||||
@ -353,6 +414,11 @@ int main(int argc, char **argv)
|
||||
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventControlErrorCallback),
|
||||
strdup("callback control error"), myFreeFunc);
|
||||
callback9ret = virConnectDomainEventRegisterAny(dconn,
|
||||
NULL,
|
||||
VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventDiskChangeCallback),
|
||||
strdup("disk change"), myFreeFunc);
|
||||
|
||||
if ((callback1ret != -1) &&
|
||||
(callback2ret != -1) &&
|
||||
@ -360,8 +426,16 @@ int main(int argc, char **argv)
|
||||
(callback4ret != -1) &&
|
||||
(callback5ret != -1) &&
|
||||
(callback6ret != -1) &&
|
||||
(callback7ret != -1)) {
|
||||
while (run) {
|
||||
(callback7ret != -1) &&
|
||||
(callback9ret != -1)) {
|
||||
if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
fprintf(stderr, "Failed to start keepalive protocol: %s\n",
|
||||
err && err->message ? err->message : "Unknown error");
|
||||
run = 0;
|
||||
}
|
||||
|
||||
while (run && virConnectIsAlive(dconn) == 1) {
|
||||
if (virEventRunDefaultImpl() < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
fprintf(stderr, "Failed to run event loop: %s\n",
|
||||
@ -377,6 +451,7 @@ int main(int argc, char **argv)
|
||||
virConnectDomainEventDeregisterAny(dconn, callback5ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback6ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback7ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback9ret);
|
||||
if (callback8ret != -1)
|
||||
virConnectDomainEventDeregisterAny(dconn, callback8ret);
|
||||
}
|
||||
|
@ -430,7 +430,8 @@ def eventToString(event):
|
||||
"Started",
|
||||
"Suspended",
|
||||
"Resumed",
|
||||
"Stopped" );
|
||||
"Stopped",
|
||||
"Shutdown" );
|
||||
return eventStrings[event];
|
||||
|
||||
def detailToString(event, detail):
|
||||
@ -440,7 +441,8 @@ def detailToString(event, detail):
|
||||
( "Booted", "Migrated", "Restored", "Snapshot" ),
|
||||
( "Paused", "Migrated", "IOError", "Watchdog" ),
|
||||
( "Unpaused", "Migrated"),
|
||||
( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot")
|
||||
( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
|
||||
( "Finished" )
|
||||
)
|
||||
return eventStrings[event][detail]
|
||||
|
||||
@ -469,13 +471,19 @@ def myDomainEventIOErrorCallback(conn, dom, srcpath, devalias, action, opaque):
|
||||
def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authScheme, subject, opaque):
|
||||
print "myDomainEventGraphicsCallback: Domain %s(%s) %d %s" % (dom.name(), dom.ID(), phase, authScheme)
|
||||
|
||||
def usage():
|
||||
print "usage: "+os.path.basename(sys.argv[0])+" [uri]"
|
||||
print " uri will default to qemu:///system"
|
||||
def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason, opaque):
|
||||
print "myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s" % (
|
||||
dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason)
|
||||
def usage(out=sys.stderr):
|
||||
print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]"
|
||||
print >>out, " uri will default to qemu:///system"
|
||||
print >>out, " --help, -h Print this help message"
|
||||
print >>out, " --debug, -d Print debug output"
|
||||
print >>out, " --loop, -l Toggle event-loop-implementation"
|
||||
|
||||
def main():
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "h", ["help"] )
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hdl", ["help", "debug", "loop"])
|
||||
except getopt.GetoptError, err:
|
||||
# print help information and exit:
|
||||
print str(err) # will print something like "option -a not recognized"
|
||||
@ -483,11 +491,17 @@ def main():
|
||||
sys.exit(2)
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
usage()
|
||||
usage(sys.stdout)
|
||||
sys.exit()
|
||||
if o in ("-d", "--debug"):
|
||||
global do_debug
|
||||
do_debug = True
|
||||
if o in ("-l", "--loop"):
|
||||
global use_pure_python_event_loop
|
||||
use_pure_python_event_loop ^= True
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
uri = sys.argv[1]
|
||||
if len(args) >= 1:
|
||||
uri = args[0]
|
||||
else:
|
||||
uri = "qemu:///system"
|
||||
|
||||
@ -517,12 +531,15 @@ def main():
|
||||
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR, myDomainEventIOErrorCallback, None)
|
||||
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback, None)
|
||||
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback, None)
|
||||
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DISK_CHANGE, myDomainEventDiskChangeCallback, None)
|
||||
|
||||
vc.setKeepAlive(5, 3)
|
||||
|
||||
# The rest of your app would go here normally, but for sake
|
||||
# of demo we'll just go to sleep. The other option is to
|
||||
# run the event loop in your main thread if your app is
|
||||
# totally event based.
|
||||
while 1:
|
||||
while vc.isAlive() == 1:
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user